<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Michael Deal on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Michael Deal</name>
  </author>
  <link href="https://web.dev/authors/mdeal/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OAJG3V813un1iXuy451G.png?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>New Product Development at Orange Honey</subtitle>
  
  
  <entry>
    <title>Typographic effects in canvas</title>
    <link href="https://web.dev/canvas-texteffects/"/>
    <updated>2011-03-01T00:00:00Z</updated>
    <id>https://web.dev/canvas-texteffects/</id>
    <content type="html" mode="escaped">&lt;h2 id=&quot;my-background&quot;&gt;My Background &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#my-background&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; entered my awareness in 2006 when Firefox v2.0 was released. An article on &lt;a href=&quot;http://ajaxian.com/&quot; rel=&quot;noopener&quot;&gt;Ajaxian&lt;/a&gt;, describing the transformation matrix, inspired me to create my first &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; web-app; &lt;a href=&quot;http://www.colorjack.com/sphere/&quot; rel=&quot;noopener&quot;&gt;Color Sphere&lt;/a&gt; (2007). Which immersed me into the world of colors, and graphic primitives; inspiring the creation of &lt;a href=&quot;http://mugtug.com/sketchpad/&quot; rel=&quot;noopener&quot;&gt;Sketchpad&lt;/a&gt; (2007-2008) in an effort to put together an application &amp;quot;better than Paint&amp;quot; in the browser.
These experiments eventually led to the creation of the startup Mugtug with
my long-time friend Charles Pritchard. We&#39;re developing &lt;a href=&quot;http://mugtug.com/darkroom/&quot; rel=&quot;noopener&quot;&gt;Darkroom&lt;/a&gt; in HTML5 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;. Darkroom
is a non-destructive photo-sharing app, combining the powers of pixel-based filters with
vector-based typography and drawing.&lt;/p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#introduction&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;
&lt;img alt=&quot;Canvas banner graphic.&quot; decoding=&quot;async&quot; height=&quot;202&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 730px) 730px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/d7xs9eowhsOMYFFYcryx.png?auto=format&amp;w=1460 1460w&quot; width=&quot;730&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; brings Javascript programmers full-control of the &lt;strong&gt;colors&lt;/strong&gt;,
&lt;strong&gt;vectors&lt;/strong&gt; and &lt;strong&gt;pixels&lt;/strong&gt; on their screens - the visual makeup of the monitor.&lt;/p&gt;
&lt;p&gt;The following examples deal with one area in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; that hasnt gotten
much attention;  creating &lt;strong&gt;text-effects&lt;/strong&gt;.  The variety of text-effects
that can be created in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; are as vast as you can imagine - these demos
cover a sub-section of what is possible.  Although we &#39;re dealing with
&amp;quot;text&amp;quot; in this article, the methods can be applied to &lt;strong&gt;any vector objects&lt;/strong&gt;;
creating exciting visuals in games, and other applications:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Text-Shadows in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;CSS-like&lt;/strong&gt; text-effects in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; creating clipping masks, finding metrics in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, and using the shadow property.&lt;/dd&gt;
&lt;dt&gt;Neon-rainbow, zebra-reflection - chaining effects.&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;Photoshop-like&lt;/strong&gt; text-effects in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; examples of using globalCompositeOperation, createLinearGradient, createPattern.&lt;/dd&gt;
&lt;dt&gt;Inner and outer shadows in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;Revealing a &lt;strong&gt;little known feature&lt;/strong&gt;; using clockwise vs. anti-clockwise winding to create the inverse of a drop-shadow (the &lt;strong&gt;inner-shadow&lt;/strong&gt;).&lt;/dd&gt;
&lt;dt&gt;Spaceage - generative effect.&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;Generative based&lt;/strong&gt; text-effect in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; using hsl() color-cycling and &lt;code&gt;window.requestAnimationFrame&lt;/code&gt; to create the feeling of motion.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&quot;text-shadows-in-canvas&quot;&gt;Text-Shadows in Canvas &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#text-shadows-in-canvas&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of my favorite additions to CSS3 specs (along with border-radius, web-gradients, and others)
is the ability to create shadows. It &#39;s important to realize the differences
between CSS and &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; shadows, specifically:&lt;/p&gt;
&lt;p&gt;CSS uses two methods; &lt;strong&gt;box-shadow&lt;/strong&gt; for box-elements, such as div, span,
and so on; and &lt;strong&gt;text-shadow&lt;/strong&gt; for text content.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; has one type of shadow; it &#39;s used for all the vector
objects; ctx.moveTo, ctx.lineTo, ctx.bezierCurveTo, ctx.quadradicCurveTo, ctx.arc, ctx.rect, ctx.fillText, ctx.strokeText, and so on.
To create a shadow in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, tap into these four properties:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;ctx.shadowColor&lt;/strong&gt; = &amp;quot;red&amp;quot; // string&lt;/dt&gt;
&lt;dd&gt;Color of the shadow;  RGB, RGBA, HSL, HEX, and other inputs are valid.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;ctx.shadowOffsetX&lt;/strong&gt; = 0; // integer&lt;/dt&gt;
&lt;dd&gt;Horizontal distance of the shadow, in relation to the text.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;ctx.shadowOffsetY&lt;/strong&gt; = 0; // integer&lt;/dt&gt;
&lt;dd&gt;Vertical distance of the shadow, in relation to the text.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;ctx.shadowBlur&lt;/strong&gt; = 10; // integer&lt;/dt&gt;
&lt;dd&gt;Blurring effect to the shadow, the larger the value, the greater the blur.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;To get things started, let &#39;s see how &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; can emulate CSS effects.
Searching through Google images for &amp;quot;css text-shadow&amp;quot; led to a few great
demos for us to emulate; &lt;a href=&quot;http://line25.com/articles/using-css-text-shadow-to-create-cool-text-effects&quot; rel=&quot;noopener&quot;&gt;Line25&lt;/a&gt;,
and &lt;a href=&quot;http://lab.simurai.com/css/css3d/&quot; rel=&quot;noopener&quot;&gt;Stereoscopic&lt;/a&gt;, and
&lt;a href=&quot;http://pgwebdesign.net/blog/3d-css-shadow-text-tutorial&quot; rel=&quot;noopener&quot;&gt;Shadow 3D&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;CSS 3D Graphic&quot; decoding=&quot;async&quot; height=&quot;162&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 300px) 300px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/4B2cPb5kd0ueCx19URBI.png?auto=format&amp;w=600 600w&quot; width=&quot;300&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The stereoscopic 3D effect (see &lt;a href=&quot;http://en.wikipedia.org/wiki/Anaglyph_image&quot; rel=&quot;noopener&quot;&gt;Anaglyph image&lt;/a&gt;
for more) is an example of a simple line of code, put to great use. With the following line of CSS,
we can create the illusion of depth when viewed with 3D red/cyan glasses (the kind they give you at 3D movies):&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;text-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -0.06em 0 0 red&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.06em 0 0 cyan&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;There are two things to notice when converting this string to &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There is no shadow-blur (the third value), so there is no reason to actually run shadow, as fillText would create the same results:&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#000&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;red&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cyan&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;pre&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;EM &#39;s aren &#39;t supported in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; so they &#39;ll have
to be converted to PX &#39;s. We can find the conversion ratio for converting
between PT, PC, EM, EX, PX and so-forth by creating an element with the same
font-properties in DOM, and setting the width to the format to be measured;
or instance, to capture the EM -&amp;gt; PX conversion, we &#39;d measure the DOM
element with a &amp;quot;height: 1em&amp;quot;, the resulting offsetHeight would be
how many PX &#39;s are in each EM.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20px sans-serif&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;font: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; font &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; height: 1em; display: block&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// the value to multiply PX &#39;s by to convert to EM &#39;s&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EM2PX&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offsetHeight&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;pre&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;preventing-alpha-multiplication&quot;&gt;Preventing alpha-multiplication &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#preventing-alpha-multiplication&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In a more complex example, such as the Neon effect found on Line25, the
shadowBlur property must be used to emulate the effect properly. Since the
Neon effect relies on multiple shadows, we run into a problem; in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;
each vector object can only have one shadow. So, in order to draw multiple
shadows, you must draw multiple versions of the text on top of itself.
This results in alpha multiplication, and ultimately jagged edges.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Neon graphic&quot; decoding=&quot;async&quot; height=&quot;194&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 500px) 500px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/9mSVKCcRckyEIazPFJ2O.png?auto=format&amp;w=1000 1000w&quot; width=&quot;500&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;I tried running &lt;code&gt;ctx.fillStyle = &amp;quot;rgba(0,0,0,0)&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;transparent&amp;quot;&lt;/code&gt;
to hide the text, while displaying the shadow… however, this attempt was futile;
since the shadow is a multiplication of the fillStyle alpha, the shadow can never
be more opaque than the fillStyle.&lt;/p&gt;
&lt;p&gt;Luckily, there is a way around this, we can draw the shadow offset from
the text, keeping them separated (so they &#39;re not overlapping), and thereby
hiding the text off the side of the screen:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; blur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measureText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; blur &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textBaseline &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;top&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#000&quot;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowBlur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;clipping-around-a-text-block&quot;&gt;Clipping around a text block &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#clipping-around-a-text-block&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To clean this up a bit we can prevent the fillText from being drawn in the
first place (while allowing the shadow to be drawn) by adding a clipping path.
In order to create a clipping path surrounding the text, we need to know the
height of the text (called the &amp;quot;em-height&amp;quot; historically the height
of the letter &amp;quot;M&amp;quot; on a printing press), and the width of the text.
We can get the width using &lt;code&gt;ctx.measureText().width&lt;/code&gt;, however,
&lt;code&gt;ctx.measureText().height&lt;/code&gt; doesn &#39;t exist.&lt;/p&gt;
&lt;p&gt;Luckily, through CSS hack-ardry (&lt;strong&gt;see &lt;a href=&quot;http://mudcu.be/journal/html5-typographic-metrics/&quot; rel=&quot;noopener&quot;&gt;Typographic Metrics&lt;/a&gt;
for more ways to fix older implementations of &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; using CSS measurements&lt;/strong&gt;),
we can find the height of the text through measuring the &lt;code&gt;offsetHeight&lt;/code&gt; of a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;
with the same font-properties:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20px arial&quot;&lt;/span&gt;&lt;br /&gt;d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; emHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offsetHeight&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;From there, we can create a rectangle to use as a clipping path; enclosing the &amp;quot;shadow&amp;quot; while removing the dummy-shape.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; emHeight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Tying it all together, and optimizing as we go - if a shadow has no blur, fillText can be used to the same effect, saving us from setting up the clipping mask:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measureText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; style &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadowStyles&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// add a background to the current effect&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;background&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; textHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// parse text-shadows from css&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; shadows &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseShadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadow&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// loop through the shadow collection&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadows&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; totalWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blur &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offsetX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blur&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; totalWidth&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; textHeight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blur&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// just run shadow (clip text)&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; totalWidth&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowBlur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blur&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;totalWidth &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// just run pseudo-shadow&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shadow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// drawing the text in the foreground&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// jump to next em-line&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; textHeight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Since you&#39;re not going to want to enter all these &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; commands
manually, I &#39;ve included a simple text-shadow parser in the demo source;
this way you can feed it CSS commands and have it generate &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; commands.
Now, our &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; elements have a whole range of styles it can tie into.
These same shadow-effects can be used on any vector object, from WebFonts to
complex shapes imported from SVGs, to generative vector shapes, and so on!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Text shadow in canvas effects&quot; decoding=&quot;async&quot; height=&quot;168&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 599px) 599px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/OYIx6atDClMFriFDdbA1.png?auto=format&amp;w=1198 1198w&quot; width=&quot;599&quot; /&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;intermission-tangent-on-pixel-pushing&quot;&gt;Intermission (tangent on pixel-pushing) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#intermission-tangent-on-pixel-pushing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In writing this section of the article, the Stereoscopic example made me curious.  How hard it would be to create a 3D-movie-screen effect using &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and two images taken from slightly different perspectives?  Apparently, not too hard.  The following kernel combines the red channel of the first image (data) w/ the cyan channel of the second image (data2):&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; data2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; data2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Now, someone just needs to duct-tape two iPhones to their forehead, click &amp;quot;record video&amp;quot; at the same time, and we could make our own 3D movies in HTML5.  Any volunteers?&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;3d glasses&quot; decoding=&quot;async&quot; height=&quot;52&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 200px) 200px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/WFdfYOArz9cBunrWBSuN.png?auto=format&amp;w=400 400w&quot; width=&quot;200&quot; /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;neon-rainbow,-zebra-reflection—chaining-effects&quot;&gt;Neon-rainbow, zebra-reflection—chaining effects &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#neon-rainbow,-zebra-reflection%E2%80%94chaining-effects&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Chaining multiple effects in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; can be simple, but a basic
knowledge of the globalCompositeOperation (GCO) is required. To compare the
operations to GIMP (or Photoshop): there are 12 GCO &#39;s in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;
&lt;strong&gt;darker&lt;/strong&gt;, and &lt;strong&gt;lighter&lt;/strong&gt; can be thought of as layer blend-modes;
the other 10 operations are applied to the layers as alpha masks (one layer
removes the pixels of the other layer). The globalCompositeOperation ties &amp;quot;layers&amp;quot;
(or in our case, strings of code) together, combining them in new and exciting ways:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Chaining effects graphics&quot; decoding=&quot;async&quot; height=&quot;403&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 512px) 512px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/iz7Cvp2zPp59O7AprtMX.png?auto=format&amp;w=1024 1024w&quot; width=&quot;512&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The globalCompositeOperation chart shows
GCO modes at work; this chart uses a large portion of the color-spectrum and multiple
levels of alpha transparency in order to see in detail what to expect.
I would recommend checking out Mozilla &#39;s &lt;a href=&quot;https://developer.mozilla.org/Canvas_tutorial/Compositing&quot; rel=&quot;noopener&quot;&gt;globalCompositeOperation reference&lt;/a&gt;
for textual descriptions. For further research, you can learn how the operation
work in Porter Duff &#39;s &lt;strong&gt;&lt;a href=&quot;http://keithp.com/~keithp/porterduff/&quot; rel=&quot;noopener&quot;&gt;Compositing Digital Images&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;My favorite mode is globalCompositeOperation=&amp;quot;lighter&amp;quot;.  Lighter mixes
the appended pixels similar to how light mixes; when red, green and white light are at
full-intensity, we see white-light. It &#39;s a exciting feature to play around
with, especially when the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; is set to a low globalAlpha; enabling finer control,
and smoother edges.  Lighter has been put to many uses, my recent favorite being a
HTML5 desktop background creator found at &lt;a href=&quot;http://weavesilk.com/&quot; rel=&quot;noopener&quot;&gt;http://weavesilk.com/&lt;/a&gt;.
One of my demos, &lt;a href=&quot;http://mudcu.be/labs/JS1k/BreathingGalaxies.html&quot; rel=&quot;noopener&quot;&gt;Breathing Galaxies&lt;/a&gt; (JS1k),
also uses the lighter mode - drawing patterns from these two examples you start to
see what effect this mode yields.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; There is some missing support for some of the GCO modes across the browsers that needs to be sorted out. There are six-modes that work across browsers (in Chrome, Safari, Firefox, and Opera): &lt;strong&gt;source-over, source-atop, destination-over, destination-out, lighter, and xor&lt;/strong&gt;. Hopefully this will be sorted out in coming releases, for more information visit &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;&lt;a href=&quot;http://www.rekim.com/tag/globalcompositeoperation/&quot; rel=&quot;noopener&quot;&gt;globalCompositeOperation browser handling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;neon-rainbow-jitter-effect&quot;&gt;Neon-Rainbow Jitter Effect &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#neon-rainbow-jitter-effect&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the following demo, we &#39;re going to achieve a &lt;strong&gt;Photoshop-like&lt;/strong&gt;
neon-rainbow-glow with a jittered outline, by chaining effects together using the
globalCompositeOperation (source-in, lighter, and darker).
This demo is a progression of the &amp;quot;Text-Shadows in &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;&amp;quot; demo,
using the same strategy in separating the shadow from the text (see previous section):&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Rainbow Jitter&quot; decoding=&quot;async&quot; height=&quot;185&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 555px) 555px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/w3oTGfBBhMwD7zjhvdNE.png?auto=format&amp;w=1110 1110w&quot; width=&quot;555&quot; /&gt;
&lt;/figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;neonLightEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;alert(&#39;&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fromCharCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x2665&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&#39;)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;120px Futura, Helvetica, sans-serif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; jitter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// the distance of the maximum jitter&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; blur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBlurValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// save state&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// calculate width + height of text-block&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; metrics &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// create clipping mask around text-effect&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offsetX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; blur&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; blur&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        offsetX &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// create shadow-blur to mask rainbow onto (since shadowColor doesn&#39;t accept gradients)&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0,0,0,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowBlur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; blur&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// create the rainbow linear-gradient&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createLinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255, 0, 0, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255, 255, 0, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0, 255, 0, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0, 255, 255, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0, 0, 255, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255, 0, 255, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255, 0, 0, 1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// change composite so source is applied within the shadow-blur&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-atop&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply gradient to shadow-blur&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offsetX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; jitter&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// change composite to mix as light&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lighter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// multiply the layer&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalAlpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drawImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvas&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drawImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvas&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalAlpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// draw white-text ontop of glow&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255,255,255,0.95)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// created jittered stroke&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lineWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strokeStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(255,255,255,0.25)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; jitter &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; jitter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; top &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; jitter &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; jitter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strokeText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    &lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strokeStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0,0,0,0.20)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strokeText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;zebra-reflection-effect&quot;&gt;Zebra Reflection Effect &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#zebra-reflection-effect&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Zebra Reflection effect was inspired by
&lt;a href=&quot;http://www.webdesignerwall.com/demo/css-gradient-text&quot; rel=&quot;noopener&quot;&gt;WebDesignerWall&lt;/a&gt; &#39;s
excellent resource on how to spice up your page with CSS. This takes the idea a
little bit further, creating a &amp;quot;reflection&amp;quot; for the text - such as what
you might see in iTunes.  The effect combines the fillColor (white), createPattern (zebra.png),
and linearGradient (shine);  this illustrates the ability to apply multiple fill
types to each vector object:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Zebra effect&quot; decoding=&quot;async&quot; height=&quot;217&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 652px) 652px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/pN2lZkfjGiqbmoNZZg94.png?auto=format&amp;w=1304 1304w&quot; width=&quot;652&quot; /&gt;
&lt;/figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sleekZebraEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// inspired by - http://www.webdesignerwall.com/demo/css-gradient-text/&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Sleek Zebra...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;100px Futura, Helvetica, sans-serif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// save state&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// getMetrics calculates:&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// width + height of text-block&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// top + middle + bottom baseline&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; metrics &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getMetrics&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offsetRefectionY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// throwing a linear-gradient in to shine up the text&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createLinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#000&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#fff&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#fff&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#000&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gradient&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// draw reflected text&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-over&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetRefectionY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;font &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; offsetY &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// cut the gradient out of the reflected text &lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination-out&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createLinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;rgba(0,0,0,0.65)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#000&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// restore back to original transform state&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// using source-atop to allow the transparent .png to show through to the gradient&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-atop&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// creating pattern from &amp;lt;image&gt; sourced.&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;repeat&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// fill the height of two em-boxes, to encompass both normal and reflected state&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offsetX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offsetY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;innerouter-shadows-in-canvas&quot;&gt;Inner/outer shadows in Canvas &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#innerouter-shadows-in-canvas&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; specs doesn &#39;t touch on the subject of &amp;quot;inner&amp;quot;
vs. &amp;quot;outer&amp;quot; shadows. In fact, at first appearance, you may expect
&amp;quot;inner&amp;quot; shadow isn &#39;t supported. This is not the case.
It &#39;s just a bit tricker to enable ;) As proposed in a recent post
from &lt;a href=&quot;http://weblog.bocoup.com/can-i-draw-an-inset-shadow-with-the-html5-canvas-api&quot; rel=&quot;noopener&quot;&gt;F1LT3R&lt;/a&gt;,
you can create inner-shadows using the unique properties of clockwise vs. anti-clockwise
winding rules. To do this, you create an &amp;quot;inner-shadow&amp;quot; by drawing container
rectangle, and then, using opposite winding rules, draw a cutout shape - creating
the inverse of the shape.&lt;/p&gt;
&lt;p&gt;The following example allows for the inner-shadow and fillStyle to be stylized
with color+gradient+pattern simultaneously. You can specify pattern rotation
individually; notice the zebra stripes are now perpendicular to each-other.
A clipping mask the size of the bounding-box is used removing the need for a
super-large container to enclose the cutout shape - improving the speed by
preventing the unnecessary parts of the shadow from being processed.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Inner/outer shadows&quot; decoding=&quot;async&quot; height=&quot;234&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 241px) 241px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/0XOpHHMgFMFRcxXmBPgj.png?auto=format&amp;w=482 482w&quot; width=&quot;241&quot; /&gt;
&lt;/figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;innerShadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;drawShape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// draw anti-clockwise&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Outer circle&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;moveTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Mouth&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;moveTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Left eye&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;moveTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;140&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Right eye&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; innerColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0,0,0,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; outerColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0,0,0,1)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;170&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply inner-shadow&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; innerColor&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowBlur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBlurValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// create clipping path (around blur + shape, preventing outer-rect blurring)&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply inner-shadow (w/ clockwise vs. anti-clockwise cutout)&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;drawShape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// cutout temporary rectangle used to create inner-shadow&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination-out&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// prepare vector paths&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;drawShape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply fill-gradient to inner-shadow&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-in&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createLinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#ff0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#f00&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply fill-pattern to inner-shadow&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-atop&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalAlpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;repeat&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply fill-gradient&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination-over&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createLinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#f00&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;rgba(255,255,0,1)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addColorStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;#00f&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gradient&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply fill-pattern&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source-atop&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalAlpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;repeat&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// apply outer-shadow (color-only without temporary layer)&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalCompositeOperation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination-over&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; outerColor&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowBlur &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shadowOffsetY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;From these examples you can see, using globalCompositeOperation, we can
chain-effects together, producing more elaborate effects (utilizing masking
and blending). The screen is your oyster ;)&lt;/p&gt;
&lt;h2 id=&quot;spaceage—generative-effects&quot;&gt;Spaceage—generative effects &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#spaceage%E2%80%94generative-effects&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, going from the unicode character 0x2708:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Unicode gfaphic&quot; decoding=&quot;async&quot; height=&quot;258&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 270px) 270px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/TeGf5Gzxaq2VEDkiB54O.png?auto=format&amp;w=540 540w&quot; width=&quot;270&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;…to this shaded example:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Shaded example&quot; decoding=&quot;async&quot; height=&quot;200&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 270px) 270px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/Woj2vfpfT8X6feFfAue4.png?auto=format&amp;w=540 540w&quot; width=&quot;270&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;…can be achieved by multiple calls to &lt;code&gt;ctx.strokeText()&lt;/code&gt; with a thin lineWidth (0.25),
while slowly decreasing the x-offset and alpha; giving our vector elements the feeling of motion.&lt;/p&gt;
&lt;p&gt;By mapping the elements XY position to a sine/cosine wave, and cycling through
colors using the HSL property, we can create more interesting effects, such as this
&amp;quot;biohazard&amp;quot; example:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;HSL cycling effect&quot; decoding=&quot;async&quot; height=&quot;129&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 646px) 646px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/hTj61l44xoKOrGnlZBZP.png?auto=format&amp;w=1292 1292w&quot; width=&quot;646&quot; /&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;hsl-hue,-saturation,-lightness-1978&quot;&gt;HSL: Hue, Saturation, Lightness (1978) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#hsl-hue,-saturation,-lightness-1978&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;HSL is a newly supported format in the CSS3 specs.  Where HEX was designed
for computers, HSL is designed to be human readable.&lt;/p&gt;
&lt;p&gt;Illustrating the ease of HSL; to cycle through the color-spectrum, we &#39;d simply
increment the &amp;quot;hue&amp;quot; from 360; the hue is mapped to the spectrum in
cylindric fashion. Lightness controls how how dark/light the color is;
0% indicates a black pixel, whereas 100% indicates a white pixel.
Saturation controls how bright or vivid a color is; grey &#39;s are created
with a saturation of 0%, and vivid colors are created using a value of 100%.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;HSL Graphic&quot; decoding=&quot;async&quot; height=&quot;283&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 281px) 281px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/vRr2pXKNVbdYZ9rQ2i27.png?auto=format&amp;w=562 562w&quot; width=&quot;281&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Since HSL is a recent standard, you may wish to continue supporting older
browsers, which is possible via color-space conversion. The following code accepts
an HSL object { H: 360, S: 100, L: 100} and outputs a RGB object { R: 255, G: 255, B: 255 }.
From there, you can use those values to create your rgb or rgba string.
For more in depth information see Wikipedia &#39;s insightful article on
&lt;a href=&quot;http://en.wikipedia.org/wiki/HSL_and_HSV&quot; rel=&quot;noopener&quot;&gt;HSL&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// HSL (1978) = H: Hue / S: Saturation / L: Lightness&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function-variable function&quot;&gt;HSL_RGB&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// { H: 0-360, S: 0-100, L: 0-100 }&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; o&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; o&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; o&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Hue_2_RGB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;v1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; vH&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vH &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; vH &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vH &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; vH &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; v1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vH&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; v1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; vH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// HSL from 0 to 1&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;G&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    _2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    _2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;_1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; _2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Hue_2_RGB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;G&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Hue_2_RGB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Hue_2_RGB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;B&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;creating-animations-with-requestanimationframe&quot;&gt;Creating animations with requestAnimationFrame &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#creating-animations-with-requestanimationframe&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the past, to create animations in Javascript, there was two choices; &lt;code&gt;setTimeout&lt;/code&gt;,
and &lt;code&gt;setInterval&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;window.requestAnimationFrame&lt;/code&gt;, is the new standard here to replace
both; saving the world electricity (and your computer a few heartbeats) by
allowing the browser to regulate animations based on available resources.
Some important features include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a user exists the frame, the animation can slow down or stop
completely, to prevent the use of unneeded resources.&lt;/li&gt;
&lt;li&gt;There is a limit cap to the frame-rate at 60FPS. The reason for this is
it &#39;s well above the level humans can notice (most humans by 30FPS
see animation being &amp;quot;fluid&amp;quot;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the time of writing, vender specific prefixes are required to use &lt;code&gt;requestAnimationFrame&lt;/code&gt;.
Paul Irish created a shim layer that has cross-vender support, in &lt;a href=&quot;http://paulirish.com/2011/requestanimationframe-for-smart-animating/&quot; rel=&quot;noopener&quot;&gt;requestAnimationFrame for
smart animating&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// shim layer with setTimeout fallback&lt;/span&gt;&lt;br /&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;requestAnimFrame &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;  window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;requestAnimationFrame       &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;br /&gt;        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;webkitRequestAnimationFrame &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;br /&gt;        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mozRequestAnimationFrame    &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;br /&gt;        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;oRequestAnimationFrame      &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;br /&gt;        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;msRequestAnimationFrame     &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* function */&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* DOMElement */&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;callback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Taking that a bit further, the more ambitious might tie this together with a
poly-fill such as &lt;a href=&quot;https://github.com/neonux/requestAnimationFrame.js&quot; rel=&quot;noopener&quot;&gt;requestAnimationFrame.js&lt;/a&gt;
(there are a few features to be worked out) that would support older browsers
to a further extent, while switching to this new standard.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; endpos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    n &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; definition&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;globalAlpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; startpos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; endpos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; alpha&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doColorCycle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        hue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strokeStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hsl(&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hue &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;,99%,50%)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// iterate hue&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; cosdiv&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; cosmult&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// cosine&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; sindiv&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; sinmult&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// sin&lt;/span&gt;&lt;br /&gt;    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strokeText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; xoffset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; yoffset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// draw rainbow text&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;timeout &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requestAnimationFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;animate&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figure&gt;
&lt;img alt=&quot;Notes Blur Graphic&quot; decoding=&quot;async&quot; height=&quot;280&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 512px) 512px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/CeCJwubmXdTgzVhpyXoy.png?auto=format&amp;w=1024 1024w&quot; width=&quot;512&quot; /&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt=&quot;Animation Graphic&quot; decoding=&quot;async&quot; height=&quot;176&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 528px) 528px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/QkaDTVmX9fkhloJjC2FL.png?auto=format&amp;w=1056 1056w&quot; width=&quot;528&quot; /&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt=&quot;Matrix Graphic&quot; decoding=&quot;async&quot; height=&quot;153&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 512px) 512px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/T4FyVKpzu4WKF1kBNvXepbi08t52/ouNSXDIYdXLC24jjL0q7.png?auto=format&amp;w=1024 1024w&quot; width=&quot;512&quot; /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;source-code&quot;&gt;Source-code &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/canvas-texteffects/#source-code&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With support from across browser vendor-sphere, there is no question about the
future of &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; it can be ported to the iPhone/Android/Desktop executables
using &lt;a href=&quot;http://www.phonegap.com/&quot; rel=&quot;noopener&quot;&gt;PhoneGap&lt;/a&gt;, or&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.appcelerator.com/products/titanium-cross-platform-application-development/&quot; rel=&quot;noopener&quot;&gt;Titanium&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Michael Deal</name>
    </author>
  </entry>
</feed>
