{"id":13428,"date":"2022-05-06T20:03:53","date_gmt":"2022-05-06T18:03:53","guid":{"rendered":"https:\/\/www.espai.es\/blog\/?p=13428"},"modified":"2022-07-29T13:23:57","modified_gmt":"2022-07-29T11:23:57","slug":"houdini-css-paint-api","status":"publish","type":"post","link":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/","title":{"rendered":"Houdini: CSS Paint API"},"content":{"rendered":"<p>Gracias al elemento &lt;canvas&gt; de HTML5 podemos dibujar una imagen, mediante c\u00f3digo JavaScript. Pero, \u00bfqu\u00e9 sucede si queremos hacer lo mismo con una imagen que queremos usar en CSS? Pues bien, en este art\u00edculo vamos a ver como con la nueva <strong>CSS Paint API<\/strong> podemos hacer justamente eso; <strong>dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS<\/strong>.<\/p>\n<h2>\u00bfQue es Houdini CSS?<\/h2>\n<p>Hoidini CSS es un nuevo conjunto de APIs para mejorar y expandir la funcionalidad de CSS desde JavaScript. Sobretodo, lo que nos ofrece Houdini es <strong>acceso al CSSOM<\/strong>. El CSSOM es el equivalente al DOM (Document Object Model) de HTML, pero para CSS (es decir, el <strong>CSS Object Model<\/strong>).<\/p>\n<p>Houdini <strong>a\u00fan <\/strong><strong>est\u00e1 bastante verde<\/strong> y deber\u00edas <a href=\"https:\/\/ishoudinireadyyet.com\/\" target=\"_blank\" rel=\"noopener\">consultar su evoluci\u00f3n en los diferentes navegadores<\/a> para decidir cuando es buena idea empezar a usarlo. El resumen, en el d\u00eda que escribo este art\u00edculo, es que algunas cosas ya funcionan en Chrome (y navegadores con el mismo motor, como el Edge), mientras que <strong>en otros navegadores como Firefox el soporte es b\u00e1sicamente nulo.<\/strong><\/p>\n<p>Pero bueno, igualmente en este art\u00edculo veremos que medidas podemos tomar para evitar problemas en navegadores donde estos APIs no funcionan todav\u00eda.<\/p>\n<h2>\u00bfComo funciona CSS Paint API?<\/h2>\n<p>Este API nos permite generar una imagen, mediante JavaScript, que posteriormente podemos usar en cualquier propiedad CSS que admita una imagen. Como, por ejemplo, <strong><em>background-image<\/em><\/strong>, <em><strong>border-image<\/strong><\/em>, <em><strong>mask-image<\/strong><\/em>, etc.<\/p>\n<p>Normalmente en una propiedad CSS que acepta una imagen, como <em><strong>background-image<\/strong><\/em>, usamos la funci\u00f3n <em><strong>url()<\/strong><\/em> para indicar la ruta y nombre de archivo de la imagen que queremos usar. En el caso de <strong>CSS Paint API<\/strong>, debemos de usar la funci\u00f3n <em><strong>paint()<\/strong><\/em> en lugar de la funci\u00f3n <em><strong>url()<\/strong><\/em>, y como par\u00e1metro debemos de indicarle el nombre de nuestro <strong><em>paint worklet<\/em><\/strong>.<\/p>\n<h2>\u00bfQue es un Paint Worklet?<\/h2>\n<p>Un <em><strong>Worklet<\/strong> <\/em>es una especie de <em><strong>Web Worker<\/strong><\/em> simplificado, que nos va a dar un acceso m\u00e1s directo al \u00abdibujado\u00bb de los elementos.<\/p>\n<p>A efectos pr\u00e1cticos esto se traduce en<strong> una clase que debemos de escribir en un m\u00f3dulo JavaScript<\/strong>. Dicha clase debe de implementar un m\u00e9todo <em><strong>paint()<\/strong><\/em>, y debemos de registrarla en el sistema para que pueda ser usada desde CSS.<\/p>\n<p>Esto que suena tan complicado se reduce a crear un archivo <em><strong>.js<\/strong><\/em> con un c\u00f3digo similar a este:<\/p>\n<pre>class MiWorklet {\r\n  \/\/ debemos implementar este m\u00e9todo con estos par\u00e1metros\r\n  paint(ctx, geometry, properties) {\r\n    \/\/ ctx - es similar (con algunas limitaciones) al \"context\" que \r\n    \/\/       usamos para pintar en 2D con el API del Canvas\r\n    \/\/ geometry - en este objeto tenemos informaci\u00f3n como por ejemplo\r\n    \/\/            el ancho y alto del \"canvas\" donde vamos a dibujar\r\n    \/\/ properties - sirve para acceder a ciertas propiedades CSS que \r\n    \/\/              nos pueden servir para parametrizar nuestro worklet\r\n\r\n    \/\/ y aqu\u00ed pondr\u00edamos nuestro c\u00f3digo para pintar la imagen\r\n  }\r\n}\r\n\r\n\/\/ IMPORTANTE: debemos de registrar nuestro worklet para que sea accesible desde CSS\r\nregisterPaint('miSuperWorklet', MiWorklet); \/\/ nombre en CSS, clase del worklet\r\n<\/pre>\n<p>y despu\u00e9s debemos de cargar dicho archivo, como un m\u00f3dulo, del siguiente modo:<\/p>\n<pre>&lt;script&gt;CSS.paintWorklet.addModule('mi-worklet.js');&lt;\/script&gt;<\/pre>\n<p>Y ya est\u00e1, ya podemos usar nuestro worklet desde CSS del siguiente modo:<\/p>\n<pre>h1 { background-image: paint(miSuperWorklet); }<\/pre>\n<p>Cuando se vaya a dibujar la imagen, <strong>se generar\u00e1 una imagen del tama\u00f1o adecuado<\/strong> mediante el <em><strong>worklet<\/strong> <\/em>escrito en JavaScript y se usar\u00e1 como cualquier otra imagen. Ojo, porque <strong>si cambiamos el tama\u00f1o del elemento HTML la imagen se va a tener que volver a generar<\/strong>. Esto \u00faltimo es importante tenerlo en cuenta para no escribir un c\u00f3digo demasiado pesado de ejecutar para el dispositivo donde se visualice la p\u00e1gina Web.<\/p>\n<p>Veamos un ejemplo de como podr\u00eda ser nuestro m\u00e9todo <strong><em>paint()<\/em><\/strong>:<\/p>\n<pre>class MiWorklet {\r\n  \/\/ nuestro m\u00e9todo paint para dibujar la imagen\r\n  paint(ctx, geometry, properties) {\r\n    \/\/ vamos a dibujar una especie de curva sinusoide\r\n    ctx.strokeStyle = 'pink';    \r\n    let mitad_altura = geometry.height * 0.5;\r\n    for (let x=0;x&lt;geometry.width;x++) {\r\n      ctx.beginPath();\r\n      ctx.moveTo(x, mitad_altura);\r\n      ctx.lineTo(x, mitad_altura + Math.sin(x * 0.1) * mitad_altura);\r\n      ctx.closePath();\r\n      ctx.stroke();\r\n    }\r\n  }\r\n}\r\nregisterPaint('miSuperWorklet', MiWorklet); \/\/ nombre en CSS, clase del worklet\r\n<\/pre>\n<p>El resultado de nuestro worklet es el siguiente:<\/p>\n<p><a href=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint.png\" rel=\"attachment wp-att-13437\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13437\" src=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint.png\" alt=\"Ejemplo CSS Paint\" width=\"307\" height=\"69\" srcset=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint.png 307w, https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint-300x67.png 300w\" sizes=\"auto, (max-width: 307px) 100vw, 307px\" \/><\/a><\/p>\n<p>Tal y como se puede ver, la forma de trabajar es muy similar a la que usamos para dibujar en un elemento canvas. Pero hay que tener en cuenta que existen ciertas limitaciones, por lo que si algo que nos funciona en un canvas y no nos funciona aqu\u00ed, ya sabemos a que puede deberse.<\/p>\n<p>Muy bien, hemos logrado generar una imagen mediante c\u00f3digo JavaScript y usarla de fondo en CSS. Ahora bien, \u00bfQu\u00e9 pasa si queremos darle m\u00e1s flexibilidad a nuestro generador de im\u00e1genes? Para ello es necesario a\u00f1adir alg\u00fan tipo de par\u00e1metros que nos permitan controlar mejor como se genera nuestra imagen.<\/p>\n<h2>Parametrizar un Paint Worklet<\/h2>\n<p>Para poder parametrizar nuestro <em><strong>worklet<\/strong> <\/em>podemos usar <a href=\"https:\/\/www.espai.es\/blog\/2022\/04\/variables-css\/\" target=\"_blank\" rel=\"noopener\">variables CSS<\/a>. y despu\u00e9s podemos acceder al valor de dichas variables a trav\u00e9s del par\u00e1metro <em><strong>properties<\/strong><\/em> del m\u00e9todo <em><strong>paint()<\/strong><\/em>. Veamos de nuevo nuestro ejemplo, pero esta vez con algunos par\u00e1metros.<\/p>\n<p><strong>C\u00f3digo CSS:<\/strong><\/p>\n<pre>h1 { \r\n    --mi-amplitud: 0.5; \r\n    --mi-frecuencia: 0.05;\r\n    --mi-color: lightgreen;\r\n    background-image: paint(miSuperWorklet);\r\n}\r\n<\/pre>\n<p><strong>C\u00f3digo para cargar el m\u00f3dulo JS:<\/strong><\/p>\n<pre>&lt;script&gt;CSS.paintWorklet.addModule('mi-worklet.js');&lt;\/script&gt;<\/pre>\n<p><strong>C\u00f3digo del m\u00f3dulo JS (mi-worklet.js):<\/strong><\/p>\n<pre>class MiWorklet {\r\n  \/\/ esto es necesario para tener acceso a las propiedades CSS que necesitamos\r\n  static get inputProperties() { return ['--mi-amplitud', '--mi-frecuencia', '--mi-color']; }\r\n  \/\/ nuestro m\u00e9todo paint\r\n  paint(ctx, geometry, properties) {\r\n    \/\/ accedemos a las propiedades CSS\r\n    const ampl = parseFloat(properties.get('--mi-amplitud').toString());\r\n    const freq = parseFloat(properties.get('--mi-frecuencia').toString());\r\n    const color = properties.get('--mi-color').toString();\r\n    \r\n    \/\/ vamos a dibujar una especie de curva sinusoide\r\n    ctx.strokeStyle = color;    \r\n    let mitad_altura = geometry.height * 0.5;\r\n    for (let x=0;x&lt;geometry.width;x++) {\r\n      ctx.beginPath();\r\n      ctx.moveTo(x, mitad_altura);\r\n      ctx.lineTo(x, mitad_altura + Math.sin(x * freq) * mitad_altura * ampl);\r\n      ctx.closePath();\r\n      ctx.stroke();\r\n    }\r\n  }\r\n}\r\nregisterPaint('miSuperWorklet', MiWorklet); \/\/ nombre en CSS, clase del worklet\r\n<\/pre>\n<p>Y este es el resultado con los nuevos par\u00e1metros a partir de las variables CSS:<\/p>\n<p><a href=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint-con-parametros.png\" rel=\"attachment wp-att-13439\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13439\" src=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint-con-parametros.png\" alt=\"Ejemplo CSS Paint con par\u00e1metros\" width=\"318\" height=\"55\" srcset=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint-con-parametros.png 318w, https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/ejemplo-css-paint-con-parametros-300x52.png 300w\" sizes=\"auto, (max-width: 318px) 100vw, 318px\" \/><\/a><\/p>\n<p>Tal y como se puede observar, con estos par\u00e1metros podemos cambiar el color, amplitud y frecuencia de la onda, lo cual nos permite una mayor flexibilidad en la imagen generada.<\/p>\n<h2>Evitar problemas de compatibilidad<\/h2>\n<p>\u00bfY que sucede con los navegadores que no soportan <strong>CSS Paint API<\/strong>?<\/p>\n<p>Pues bien, la parte de CSS es f\u00e1cil de solucionar. Tan solo <strong>debemos de indicar la propiedad 2 veces<\/strong>, una con un valor aceptable por navegadores \u00abviejos\u00bb, y otra con la funci\u00f3n <em><strong>paint()<\/strong><\/em>. Ojo, el orden es importante. Primero con el valor \u00abviejo\u00bb y despu\u00e9s con la funci\u00f3n <em><strong>paint()<\/strong><\/em>.<\/p>\n<pre>h1 { \r\n    --mi-amplitud: 0.5; \r\n    --mi-frecuencia: 0.05;\r\n    --mi-color: lightgreen;\r\n    background-image: linear-gradient(transparent, var(--mi-color), transparent);\r\n    background-image: paint(miSuperWorklet);\r\n}\r\n<\/pre>\n<p>En este ejemplo, en navegadores que no soporten <strong>CSS Paint API<\/strong>, se usar\u00e1 un degradado en lugar de nuestra imagen con la onda sinusoide.<\/p>\n<p>Respecto a la parte de c\u00f3digo JavaScript, podemos hacerlo de este modo:<\/p>\n<pre>if ('paintWorklet' in CSS) {\r\n    \/\/ si el navegador soporta CSS Paint API, cargamos nuestro m\u00f3dulo\r\n    CSS.paintWorklet.addModule('mi-worklet.js');\r\n} else {\r\n    \/\/ si hay que tomar alguna medida si el navegador no soporta CSS Paint API,\r\n    \/\/ podemos hacerlo aqu\u00ed\r\n}\r\n<\/pre>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Y nada m\u00e1s. Espero que os haya resultado interesante este nuevo API. Si quer\u00e9is inspiraros viendo otros ejemplos de <em><strong>worklets<\/strong><\/em> pod\u00e9is visitar <a href=\"https:\/\/houdini.how\/\" target=\"_blank\" rel=\"noopener\">el siguiente enlace<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.<\/p>\n","protected":false},"author":23,"featured_media":13447,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_ef_editorial_meta_date_first-draft-date":"","_ef_editorial_meta_paragraph_assignment":"","_ef_editorial_meta_checkbox_needs-photo":"","_ef_editorial_meta_number_word-count":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7],"tags":[817,13,253,818],"class_list":["post-13428","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-diseno-web","tag-css-paint-api","tag-css3","tag-javascript","tag-worklet"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Houdini: CSS Paint API - Blog Escola Espai<\/title>\n<meta name=\"description\" content=\"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Houdini: CSS Paint API - Blog Escola Espai\" \/>\n<meta property=\"og:description\" content=\"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog Escola Espai\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-06T18:03:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-29T11:23:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Abel Camarena\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Abel Camarena\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\"},\"author\":{\"name\":\"Abel Camarena\",\"@id\":\"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897\"},\"headline\":\"Houdini: CSS Paint API\",\"datePublished\":\"2022-05-06T18:03:53+00:00\",\"dateModified\":\"2022-07-29T11:23:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\"},\"wordCount\":881,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg\",\"keywords\":[\"css paint api\",\"CSS3\",\"javascript\",\"worklet\"],\"articleSection\":[\"Dise\u00f1o Web\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\",\"url\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\",\"name\":\"Houdini: CSS Paint API - Blog Escola Espai\",\"isPartOf\":{\"@id\":\"https:\/\/www.espai.es\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg\",\"datePublished\":\"2022-05-06T18:03:53+00:00\",\"dateModified\":\"2022-07-29T11:23:57+00:00\",\"author\":{\"@id\":\"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897\"},\"description\":\"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage\",\"url\":\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg\",\"contentUrl\":\"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg\",\"width\":1000,\"height\":500,\"caption\":\"Houdini Paint CSS\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\/\/www.espai.es\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Houdini: CSS Paint API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.espai.es\/blog\/#website\",\"url\":\"https:\/\/www.espai.es\/blog\/\",\"name\":\"Blog Escola Espai\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.espai.es\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897\",\"name\":\"Abel Camarena\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.espai.es\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/035501b0f14e120b1a49121758e2056b8d589fc43b9d3c3ad3670a197a90dddf?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/035501b0f14e120b1a49121758e2056b8d589fc43b9d3c3ad3670a197a90dddf?s=96&d=mm&r=g\",\"caption\":\"Abel Camarena\"},\"sameAs\":[\"http:\/\/www.espai.es\"],\"url\":\"https:\/\/www.espai.es\/blog\/author\/abel\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Houdini: CSS Paint API - Blog Escola Espai","description":"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/","og_locale":"es_ES","og_type":"article","og_title":"Houdini: CSS Paint API - Blog Escola Espai","og_description":"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.","og_url":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/","og_site_name":"Blog Escola Espai","article_published_time":"2022-05-06T18:03:53+00:00","article_modified_time":"2022-07-29T11:23:57+00:00","og_image":[{"width":1000,"height":500,"url":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","type":"image\/jpeg"}],"author":"Abel Camarena","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"Abel Camarena","Tiempo de lectura":"6 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#article","isPartOf":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/"},"author":{"name":"Abel Camarena","@id":"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897"},"headline":"Houdini: CSS Paint API","datePublished":"2022-05-06T18:03:53+00:00","dateModified":"2022-07-29T11:23:57+00:00","mainEntityOfPage":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/"},"wordCount":881,"commentCount":0,"image":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","keywords":["css paint api","CSS3","javascript","worklet"],"articleSection":["Dise\u00f1o Web"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/","url":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/","name":"Houdini: CSS Paint API - Blog Escola Espai","isPartOf":{"@id":"https:\/\/www.espai.es\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage"},"image":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","datePublished":"2022-05-06T18:03:53+00:00","dateModified":"2022-07-29T11:23:57+00:00","author":{"@id":"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897"},"description":"Con la nueva CSS Paint API podemos dibujar mediante c\u00f3digo JavaScript una imagen que despu\u00e9s podemos usar en CSS.","breadcrumb":{"@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#primaryimage","url":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","contentUrl":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","width":1000,"height":500,"caption":"Houdini Paint CSS"},{"@type":"BreadcrumbList","@id":"https:\/\/www.espai.es\/blog\/2022\/05\/houdini-css-paint-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/www.espai.es\/blog\/"},{"@type":"ListItem","position":2,"name":"Houdini: CSS Paint API"}]},{"@type":"WebSite","@id":"https:\/\/www.espai.es\/blog\/#website","url":"https:\/\/www.espai.es\/blog\/","name":"Blog Escola Espai","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.espai.es\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Person","@id":"https:\/\/www.espai.es\/blog\/#\/schema\/person\/b2d40404b9d987e3586e186c021ef897","name":"Abel Camarena","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.espai.es\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/035501b0f14e120b1a49121758e2056b8d589fc43b9d3c3ad3670a197a90dddf?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/035501b0f14e120b1a49121758e2056b8d589fc43b9d3c3ad3670a197a90dddf?s=96&d=mm&r=g","caption":"Abel Camarena"},"sameAs":["http:\/\/www.espai.es"],"url":"https:\/\/www.espai.es\/blog\/author\/abel\/"}]}},"jetpack_featured_media_url":"https:\/\/www.espai.es\/blog\/wp-content\/uploads\/2022\/05\/paint-css.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/posts\/13428","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/users\/23"}],"replies":[{"embeddable":true,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/comments?post=13428"}],"version-history":[{"count":21,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/posts\/13428\/revisions"}],"predecessor-version":[{"id":13684,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/posts\/13428\/revisions\/13684"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/media\/13447"}],"wp:attachment":[{"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/media?parent=13428"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/categories?post=13428"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.espai.es\/blog\/wp-json\/wp\/v2\/tags?post=13428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}