<!DOCTYPE html>
<title>CanvasKit Extra features (Skia via Web Assembly)</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
  canvas {
    border: 1px dashed #AAA;
  }
  #sk_legos,#sk_drinks,#sk_party,#sk_onboarding, #sk_animated_gif {
      width: 300px;
      height: 300px;
  }

</style>

<h2> Skottie </h2>
<canvas id=sk_legos width=300 height=300></canvas>
<canvas id=sk_drinks width=500 height=500></canvas>
<canvas id=sk_party width=500 height=500></canvas>
<canvas id=sk_onboarding width=500 height=500></canvas>
<canvas id=sk_animated_gif width=500 height=500
        title='This is an animated gif being animated in Skottie'></canvas>

<h2> RT Shader </h2>
<canvas id=rtshader width=300 height=300></canvas>
<canvas id=rtshader2 width=300 height=300></canvas>

<h2> Particles </h2>
<canvas id=particles width=500 height=500></canvas>

<h2> Paragraph </h2>
<canvas id=para1 width=600 height=600></canvas>
<canvas id=para2 width=600 height=600 tabindex='-1'></canvas>

<h2> CanvasKit can serialize/deserialize .skp files</h2>
<canvas id=skp width=500 height=500></canvas>

<h2> 3D perspective transformations </h2>
<canvas id=glyphgame width=500 height=500></canvas>

<h2> Support for extended color spaces </h2>
<a href="chrome://flags/#force-color-profile">Force P3 profile</a>
<canvas id=colorsupport width=300 height=300></canvas>

<script type="text/javascript" src="/node_modules/canvaskit/bin/canvaskit.js"></script>

<script type="text/javascript" src="textapi_utils.js"></script>

<script type="text/javascript" charset="utf-8">

  var CanvasKit = null;
  var cdn = 'https://storage.googleapis.com/skia-cdn/misc/';

  const ckLoaded = CanvasKitInit({locateFile: (file) => '/node_modules/canvaskit/bin/'+file});

  const loadLegoJSON = fetch(cdn + 'lego_loader.json').then((response) => response.text());
  const loadDrinksJSON = fetch(cdn + 'drinks.json').then((response) => response.text());
  const loadConfettiJSON = fetch(cdn + 'confetti.json').then((response) => response.text());
  const loadOnboardingJSON = fetch(cdn + 'onboarding.json').then((response) => response.text());
  const loadMultiframeJSON = fetch(cdn + 'skottie_sample_multiframe.json').then((response) => response.text());

  const loadFlightGif = fetch(cdn + 'flightAnim.gif').then((response) => response.arrayBuffer());
  const loadSkp = fetch(cdn + 'picture2.skp').then((response) => response.arrayBuffer());
  const loadFont = fetch(cdn + 'Roboto-Regular.ttf').then((response) => response.arrayBuffer());
  const loadDog = fetch(cdn + 'dog.jpg').then((response) => response.arrayBuffer());
  const loadMandrill = fetch(cdn + 'mandrill_256.png').then((response) => response.arrayBuffer());
  const loadBrickTex = fetch(cdn + 'brickwork-texture.jpg').then((response) => response.arrayBuffer());
  const loadBrickBump = fetch(cdn + 'brickwork_normal-map.jpg').then((response) => response.arrayBuffer());

  const curves = {
    "MaxCount": 1000,
    "Drawable": {
      "Type": "SkCircleDrawable",
      "Radius": 2
    },
    "Code": [`
      void effectSpawn(inout Effect effect) {
        effect.rate = 200;
        effect.color = float4(1, 0, 0, 1);
      }
      void spawn(inout Particle p) {
        p.lifetime = 3 + rand(p.seed);
        p.vel.y = -50;
      }

      void update(inout Particle p) {
        float w = mix(15, 3, p.age);
        p.pos.x = sin(radians(p.age * 320)) * mix(25, 10, p.age) + mix(-w, w, rand(p.seed));
        if (rand(p.seed) < 0.5) { p.pos.x = -p.pos.x; }

        p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand(p.seed))) / 255;
      }
      `
    ],
    "Bindings": []
  };

  const spiralSkSL = `
  uniform float rad_scale;
  uniform float2 in_center;
  uniform float4 in_colors0;
  uniform float4 in_colors1;

  half4 main(float2 p) {
      float2 pp = p - in_center;
      float radius = sqrt(dot(pp, pp));
      radius = sqrt(radius);
      float angle = atan(pp.y / pp.x);
      float t = (angle + 3.1415926/2) / (3.1415926);
      t += radius * rad_scale;
      t = fract(t);
      return half4(mix(in_colors0, in_colors1, t));
  }`;

  // Examples which only require canvaskit
  ckLoaded.then((CK) => {
    CanvasKit = CK;
    ParticlesAPI1(CanvasKit);
    RTShaderAPI1(CanvasKit);
    ColorSupport(CanvasKit);
  });

  // Examples requiring external resources.
  // Set bounds to fix the 4:3 resolution of the legos
  Promise.all([ckLoaded, loadLegoJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_legos', jsonstr, [-50, 0, 350, 300]);
  });
  // Re-size to fit
  let fullBounds = [0, 0, 500, 500];
  Promise.all([ckLoaded, loadDrinksJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_drinks', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadConfettiJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_party', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadOnboardingJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_onboarding', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadMultiframeJSON, loadFlightGif]).then(([ck, jsonstr, gif]) => {
    SkottieExample(ck, 'sk_animated_gif', jsonstr, fullBounds, {'image_0.png': gif});
  });

  Promise.all([ckLoaded, loadFont]).then((results) => {
    ParagraphAPI1(...results);
    ParagraphAPI2(...results);
    GlyphGame(...results)
  });
  Promise.all([ckLoaded, loadSkp]).then((results) => {SkpExample(...results)});

  const rectLeft = 0;
  const rectTop = 1;
  const rectRight = 2;
  const rectBottom = 3;

  function SkottieExample(CanvasKit, id, jsonStr, bounds, assets) {
    if (!CanvasKit || !jsonStr) {
      return;
    }
    const animation = CanvasKit.MakeManagedAnimation(jsonStr, assets);
    const duration = animation.duration() * 1000;
    const size = animation.size();
    let c = document.getElementById(id);
    bounds = bounds || CanvasKit.LTRBRect(0, 0, size.w, size.h);

    // Basic managed animation test.
    if (id === 'sk_drinks') {
      animation.setColor('BACKGROUND_FILL', CanvasKit.Color(0, 163, 199, 1.0));
    }

    const surface = CanvasKit.MakeCanvasSurface(id);
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    let firstFrame = Date.now();

    function drawFrame(canvas) {
      let seek = ((Date.now() - firstFrame) / duration) % 1.0;
      let damage = animation.seek(seek);

      if (damage[rectRight] > damage[rectLeft] && damage[rectBottom] > damage[rectTop]) {
        canvas.clear(CanvasKit.WHITE);
        animation.render(canvas, bounds);
      }
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    return surface;
  }

  function ParticlesAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('particles');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    canvas.translate(250, 450);

    const particles = CanvasKit.MakeParticles(JSON.stringify(curves));
    particles.start(Date.now() / 1000.0, true);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.BLACK);

      particles.update(Date.now() / 1000.0);
      particles.draw(canvas);
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);
  }

  function ParagraphAPI1(CanvasKit, fontData) {
    if (!CanvasKit || !fontData) {
      return;
    }

    const surface = CanvasKit.MakeCanvasSurface('para1');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const canvas = surface.getCanvas();
    const fontMgr = CanvasKit.FontMgr.FromData([fontData]);

    const paraStyle = new CanvasKit.ParagraphStyle({
        textStyle: {
            color: CanvasKit.BLACK,
            fontFamilies: ['Roboto'],
            fontSize: 50,
        },
        textAlign: CanvasKit.TextAlign.Left,
        maxLines: 5,
    });

    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText('The quick brown fox ate a hamburgerfons and got sick.');
    const paragraph = builder.build();

    let wrapTo = 0;

    let X = 100;
    let Y = 100;

    const tf = fontMgr.MakeTypefaceFromData(fontData);
    const font = new CanvasKit.Font(tf, 50);
    const fontPaint = new CanvasKit.Paint();
    fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
    fontPaint.setAntiAlias(true);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.WHITE);
      wrapTo = 350 + 150 * Math.sin(Date.now() / 2000);
      paragraph.layout(wrapTo);
      canvas.drawParagraph(paragraph, 0, 0);

      canvas.drawLine(wrapTo, 0, wrapTo, 400, fontPaint);

      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    let interact = (e) => {
      X = e.offsetX*2; // multiply by 2 because the canvas is 300 css pixels wide,
      Y = e.offsetY*2; // but the canvas itself is 600px wide
    };

    document.getElementById('para1').addEventListener('pointermove', interact);
    return surface;
  }

    function ParagraphAPI2(CanvasKit, fontData) {
      if (!CanvasKit || !fontData) {
        return;
      }

      const surface = CanvasKit.MakeCanvasSurface('para2');
      if (!surface) {
        console.error('Could not make surface');
        return;
      }

      const mouse = MakeMouse();
      const cursor = MakeCursor(CanvasKit);
      const canvas = surface.getCanvas();

      const text0 = "In a hole in the ground there lived a hobbit. Not a nasty, dirty, " +
                    "wet hole full of worms and oozy smells. This was a hobbit-hole and " +
                    "that means good food, a warm hearth, and all the comforts of home.";
      const LOC_X = 20,
            LOC_Y = 20;

      const bgPaint = new CanvasKit.Paint();
      bgPaint.setColor([0.965, 0.965, 0.965, 1]);

      const editor = MakeEditor(text0, {typeface:null, size:24}, cursor, 400);

      editor.applyStyleToRange({size:100}, 0, 1);
      editor.applyStyleToRange({italic:true}, 38, 38+6);
      editor.applyStyleToRange({color:[1,0,0,1]}, 5, 5+4);

      editor.setXY(LOC_X, LOC_Y);

      function drawFrame(canvas) {
        const lines = editor.getLines();

        canvas.clear(CanvasKit.WHITE);

        if (mouse.isActive()) {
            const pos = mouse.getPos(-LOC_X, -LOC_Y);
            const a = lines_pos_to_index(lines, pos[0], pos[1]);
            const b = lines_pos_to_index(lines, pos[2], pos[3]);
            if (a == b) {
                editor.setIndex(a);
            } else {
                editor.setIndices(a, b);
            }
        }

        canvas.drawRect(editor.bounds(), bgPaint);
        editor.draw(canvas);

        surface.requestAnimationFrame(drawFrame);
      }
      surface.requestAnimationFrame(drawFrame);

      function interact(e) {
        const type = e.type;
        if (type === 'pointerup') {
            mouse.setUp(e.offsetX, e.offsetY);
        } else if (type === 'pointermove') {
            mouse.setMove(e.offsetX, e.offsetY);
        } else if (type === 'pointerdown') {
            mouse.setDown(e.offsetX, e.offsetY);
        }
      };

      function keyhandler(e) {
          switch (e.key) {
              case 'ArrowLeft':  editor.moveDX(-1); return;
              case 'ArrowRight': editor.moveDX(1); return;
              case 'ArrowUp':
                e.preventDefault();
                editor.moveDY(-1);
                return;
              case 'ArrowDown':
                e.preventDefault();
                editor.moveDY(1);
                return;
              case 'Backspace':
                editor.deleteSelection();
                return;
              case 'Shift':
                return;
            }
            if (e.ctrlKey) {
                switch (e.key) {
                    case 'r': editor.applyStyleToSelection({color:[1,0,0,1]}); return;
                    case 'g': editor.applyStyleToSelection({color:[0,0.6,0,1]}); return;
                    case 'u': editor.applyStyleToSelection({color:[0,0,1,1]}); return;
                    case 'k': editor.applyStyleToSelection({color:[0,0,0,1]}); return;

                    case 'i': editor.applyStyleToSelection({italic:'toggle'}); return;
                    case 'b': editor.applyStyleToSelection({bold:'toggle'}); return;
                    case 'l': editor.applyStyleToSelection({underline:'toggle'}); return;

                    case ']': editor.applyStyleToSelection({size_add:1}); return;
                    case '[': editor.applyStyleToSelection({size_add:-1}); return;
                }
            }
            if (!e.ctrlKey && !e.metaKey) {
                e.preventDefault(); // at least needed for 'space'
                editor.insert(e.key);
            }
      }

      document.getElementById('para2').addEventListener('pointermove', interact);
      document.getElementById('para2').addEventListener('pointerdown', interact);
      document.getElementById('para2').addEventListener('pointerup', interact);
      document.getElementById('para2').addEventListener('keydown', keyhandler);
      return surface;
    }

  function RTShaderAPI1(CanvasKit) {
    if (!CanvasKit) {
      return;
    }

    const surface = CanvasKit.MakeCanvasSurface('rtshader');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const canvas = surface.getCanvas();

    const effect = CanvasKit.RuntimeEffect.Make(spiralSkSL);
    const shader = effect.makeShader([
      0.5,
      150, 150,
      0, 1, 0, 1,
      1, 0, 0, 1], true);
    const paint = new CanvasKit.Paint();
    paint.setShader(shader);
    canvas.drawRect(CanvasKit.LTRBRect(0, 0, 300, 300), paint);

    surface.flush();
    shader.delete();
    paint.delete();
    effect.delete();
  }

  // RTShader2 demo
  Promise.all([ckLoaded, loadDog, loadMandrill]).then((values) => {
    const [CanvasKit, dogData, mandrillData] = values;
    const dogImg = CanvasKit.MakeImageFromEncoded(dogData);
    if (!dogImg) {
      console.error('could not decode dog');
      return;
    }
    const mandrillImg = CanvasKit.MakeImageFromEncoded(mandrillData);
    if (!mandrillImg) {
      console.error('could not decode mandrill');
      return;
    }
    const quadrantSize = 150;

    const dogShader = dogImg.makeShaderCubic(
        CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
        1/3, 1/3,
        CanvasKit.Matrix.scaled(quadrantSize/dogImg.width(),
        quadrantSize/dogImg.height()));
    const mandrillShader = mandrillImg.makeShaderCubic(
        CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
        1/3, 1/3,
        CanvasKit.Matrix.scaled(
            quadrantSize/mandrillImg.width(),
            quadrantSize/mandrillImg.height()));

    const surface = CanvasKit.MakeCanvasSurface('rtshader2');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const prog = `
      uniform shader before_map;
      uniform shader after_map;
      uniform shader threshold_map;

      uniform float cutoff;
      uniform float slope;

      float smooth_cutoff(float x) {
          x = x * slope + (0.5 - slope * cutoff);
          return clamp(x, 0, 1);
      }

      half4 main(float2 xy) {
          half4 before = sample(before_map, xy);
          half4 after = sample(after_map, xy);

          float m = smooth_cutoff(sample(threshold_map, xy).r);
          return mix(before, after, half(m));
      }`;

    const canvas = surface.getCanvas();

    const thresholdEffect = CanvasKit.RuntimeEffect.Make(prog);
    const spiralEffect = CanvasKit.RuntimeEffect.Make(spiralSkSL);

    const draw = (x, y, shader) => {
      const paint = new CanvasKit.Paint();
      paint.setShader(shader);
      canvas.save();
      canvas.translate(x, y);
      canvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint);
      canvas.restore();
      paint.delete();
    };

    const offscreenSurface = CanvasKit.MakeSurface(quadrantSize, quadrantSize);
    const getBlurrySpiralShader = (rad_scale) => {
      const oCanvas = offscreenSurface.getCanvas();

      const spiralShader = spiralEffect.makeShader([
      rad_scale,
      quadrantSize/2, quadrantSize/2,
      1, 1, 1, 1,
      0, 0, 0, 1], true);

      return spiralShader;
      // TODO(kjlubick): The raster backend does not like atan or fract, so we can't
      // draw the shader into the offscreen canvas and mess with it. When we can, that
      // would be cool to show off.

      const blur = CanvasKit.ImageFilter.MakeBlur(0.1, 0.1, CanvasKit.TileMode.Clamp, null);

      const paint = new CanvasKit.Paint();
      paint.setShader(spiralShader);
      paint.setImageFilter(blur);
      oCanvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint);

      paint.delete();
      blur.delete();
      spiralShader.delete();
      return offscreenSurface.makeImageSnapshot()
                             .makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp);

    };

    const drawFrame = () => {
      surface.requestAnimationFrame(drawFrame);
      const thresholdShader = getBlurrySpiralShader(Math.sin(Date.now() / 5000) / 2);

      const blendShader = thresholdEffect.makeShaderWithChildren(
        [0.5, 10],
        true, [dogShader, mandrillShader, thresholdShader]);
      draw(0, 0, blendShader);
      draw(quadrantSize, 0, thresholdShader);
      draw(0, quadrantSize, dogShader);
      draw(quadrantSize, quadrantSize, mandrillShader);

      blendShader.delete();
    };

    surface.requestAnimationFrame(drawFrame);
  });

  function SkpExample(CanvasKit, skpData) {
    if (!skpData || !CanvasKit) {
      return;
    }

    const surface = CanvasKit.MakeSWCanvasSurface('skp');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const pic = CanvasKit.MakePicture(skpData);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.TRANSPARENT);
      // this particular file has a path drawing at (68,582) that's 1300x1300 pixels
      // scale it down to 500x500 and translate it to fit.
      const scale = 500.0/1300;
      canvas.scale(scale, scale);
      canvas.translate(-68, -582);
      canvas.drawPicture(pic);
    }
    // Intentionally just draw frame once
    surface.drawOnce(drawFrame);
  }

  // Shows a hidden message by rotating all the characters in a kind of way that makes you
  // search with your mouse.
  function GlyphGame(canvas, robotoData) {
    const surface = CanvasKit.MakeCanvasSurface('glyphgame');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const sizeX = document.getElementById('glyphgame').width;
    const sizeY = document.getElementById('glyphgame').height;
    const halfDim = Math.min(sizeX, sizeY) / 2;
    const margin = 50;
    const marginTop = 25;
    let rotX = 0; //  expected to be updated in interact()
    let rotY = 0;
    let pointer = [500, 450];
    const radPerPixel = 0.005; // radians of subject rotation per pixel distance moved by mouse.

    const camAngle = Math.PI / 12;
    const cam = {
      'eye'  : [0, 0, 1 / Math.tan(camAngle/2) - 1],
      'coa'  : [0, 0, 0],
      'up'   : [0, 1, 0],
      'near' : 0.02,
      'far'  : 4,
      'angle': camAngle,
    };

    let lastImage = null;

    const fontMgr = CanvasKit.FontMgr.FromData([robotoData]);

    const paraStyle = new CanvasKit.ParagraphStyle({
        textStyle: {
            color: CanvasKit.Color(105, 56, 16), // brown
            fontFamilies: ['Roboto'],
            fontSize: 28,
        },
        textAlign: CanvasKit.TextAlign.Left,
    });
    const hStyle = CanvasKit.RectHeightStyle.Max;
    const wStyle = CanvasKit.RectWidthStyle.Tight;

    const quotes = [
      'Some activities superficially familiar to you are merely stupid and should be avoided for your safety, although they are not illegal as such. These include: giving your bank account details to the son of the Nigerian Minister of Finance; buying title to bridges, skyscrapers, spacecraft, planets, or other real assets; murder; selling your identity; and entering into financial contracts with entities running Economics 2.0 or higher.',
      // Charles Stross - Accelerando
      'If only there were evil people somewhere insidiously committing evil deeds, and it were necessary only to separate them from the rest of us and destroy them. But the line dividing good and evil cuts through the heart of every human being. And who is willing to destroy a piece of his own heart?',
      // Aleksandr Solzhenitsyn - The Gulag Archipelago
      'There is one metaphor of which the moderns are very fond; they are always saying, “You can’t put the clock back.” The simple and obvious answer is “You can.” A clock, being a piece of human construction, can be restored by the human finger to any figure or hour. In the same way society, being a piece of human construction, can be reconstructed upon any plan that has ever existed.',
      // G. K. Chesterton - What's Wrong With The World?
    ];

    // pick one at random
    const text = quotes[Math.floor(Math.random()*3)];
    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText(text);
    const paragraph = builder.build();
    const font = new CanvasKit.Font(null, 18);
    // wrap the text to a given width.
    paragraph.layout(sizeX - margin*2);

    // to rotate every glyph individually, calculate the bounding rect of each one,
    // construct an array of rects and paragraphs that would draw each glyph individually.
    const letters = Array(text.length);
    for (let i = 0; i < text.length; i++) {
      const r = paragraph.getRectsForRange(i, i+1, hStyle, wStyle)[0];
      // The character is drawn with drawParagraph so we can pass the paraStyle,
      // and have our character be the exact size and shape the paragraph expected
      // when it wrapped the text. canvas.drawText wouldn't cut it.
      const tmpbuilder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
      tmpbuilder.addText(text[i]);
      const para = tmpbuilder.build();
      para.layout(100);
      letters[i] = {
        'r': r,
        'para': para,
      };
    }

    function drawFrame(canvas) {
      // persistence of vision effect is done by drawing the past frame as an image,
      // then covering with semitransparent background color.
      if (lastImage) {
        canvas.drawImage(lastImage, 0, 0, null);
        canvas.drawColor(CanvasKit.Color(171, 244, 255, 0.1)); // sky blue, almost transparent
      } else {
        canvas.clear(CanvasKit.Color(171, 244, 255)); // sky blue, opaque
      }
      canvas.save();
      // Set up 3D view enviroment
      canvas.concat(CanvasKit.M44.setupCamera(
        CanvasKit.LTRBRect(0, 0, sizeX, sizeY), halfDim, cam));

      // Rotate the whole paragraph as a unit.
      const paraRotPoint = [halfDim, halfDim, 1];
      canvas.concat(CanvasKit.M44.multiply(
        CanvasKit.M44.translated(paraRotPoint),
        CanvasKit.M44.rotated([0,1,0], rotX),
        CanvasKit.M44.rotated([1,0,0], rotY * 0.2),
        CanvasKit.M44.translated(CanvasKit.Vector.mulScalar(paraRotPoint, -1)),
      ));

      // Rotate every glyph in the paragraph individually.
      let i = 0;
      for (const letter of letters) {
        canvas.save();
        let r = letter['r'];
        // rotate about the center of the glyph's rect.
        rotationPoint = [
          margin + r[rectLeft] + (r[rectRight] - r[rectLeft]) / 2,
          marginTop + r[rectTop] + (r[rectBottom] - r[rectTop]) / 2,
          0
        ];
        distanceFromPointer = CanvasKit.Vector.dist(pointer, rotationPoint.slice(0, 2));
        // Rotate more around the Y-axis depending on the glyph's distance from the pointer.
        canvas.concat(CanvasKit.M44.multiply(
          CanvasKit.M44.translated(rotationPoint),
          // note that I'm rotating around the x axis first, undoing some of the rotation done to the whole
          // paragraph above, where x came second. If I rotated y first, a lot of letters would end up
          // upside down, which is a bit too hard to unscramble.
          CanvasKit.M44.rotated([1,0,0], rotY * -0.6),
          CanvasKit.M44.rotated([0,1,0], distanceFromPointer * -0.035),
          CanvasKit.M44.translated(CanvasKit.Vector.mulScalar(rotationPoint, -1)),
        ));
        canvas.drawParagraph(letter['para'], margin + r[rectLeft], marginTop + r[rectTop]);
        i++;
        canvas.restore();
      }
      canvas.restore();
      lastImage = surface.makeImageSnapshot();
    }

    function interact(e) {
      pointer = [e.offsetX, e.offsetY]
      rotX = (pointer[0] - halfDim) * radPerPixel;
      rotY = (pointer[1] - halfDim) * radPerPixel * -1;
      surface.requestAnimationFrame(drawFrame);
    };

    document.getElementById('glyphgame').addEventListener('pointermove', interact);
    surface.requestAnimationFrame(drawFrame);
  }

  function ColorSupport(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('colorsupport', CanvasKit.ColorSpace.ADOBE_RGB);
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const canvas = surface.getCanvas();

    // If the surface is correctly initialized with a higher bit depth color type,
    // And chrome is compositing it into a buffer with the P3 color space,
    // then the inner round rect should be distinct and less saturated than the full red background.
    // Even if the monitor it is viewed on cannot accurately represent that color space.

    let red = CanvasKit.Color4f(1, 0, 0, 1);
    let paint = new CanvasKit.Paint();
    paint.setColor(red, CanvasKit.ColorSpace.ADOBE_RGB);
    canvas.drawPaint(paint);
    paint.setColor(red, CanvasKit.ColorSpace.DISPLAY_P3);
    canvas.drawRRect(CanvasKit.RRectXY([50, 50, 250, 250], 30, 30), paint);
    paint.setColor(red, CanvasKit.ColorSpace.SRGB);
    canvas.drawRRect(CanvasKit.RRectXY([100, 100, 200, 200], 30, 30), paint);

    surface.flush();
    surface.delete();
  }
</script>
