<!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 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);
    SkpExample(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)
  });

  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 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 = before_map.eval(xy);
          half4 after = after_map.eval(xy);

          float m = smooth_cutoff(threshold_map.eval(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);

      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()
                             .makeShaderCubic(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
                             1/3, 1/3);

    };

    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) {
    if (!CanvasKit) {
      return;
    }

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

    const paint = new CanvasKit.Paint();
    paint.setColor(CanvasKit.RED);

    const textPaint = new CanvasKit.Paint();
    const textFont = new CanvasKit.Font(null, 20);
    const pr = new CanvasKit.PictureRecorder();
    const skpCanvas = pr.beginRecording(CanvasKit.LTRBRect(0, 0, 200, 200));
    skpCanvas.drawRect(CanvasKit.LTRBRect(10, 10, 50, 50), paint);
    skpCanvas.drawText('If you see this, CanvasKit loaded!!', 5, 100, textPaint, textFont);

    const pic = pr.finishRecordingAsPicture();
    const skpData = pic.serialize();

    paint.delete();
    pr.delete();

    const deserialized = CanvasKit.MakePicture(skpData);

    function drawFrame(canvas) {
      if (deserialized) {
        canvas.drawPicture(deserialized);
      } else {
        canvas.drawText('SKP did not deserialize', 5, 100, textPaint, textFont);
      }
    }
    surface.drawOnce(drawFrame);
    textPaint.delete();
    textFont.delete();
  }

  // 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>
