<!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 fontMgr = CanvasKit.FontMgr.FromData([fontData]);
      const TEXTSIZE = 32;

      const paraStyle = new CanvasKit.ParagraphStyle({
          textStyle: {
              color: CanvasKit.GRAY,
              fontFamilies: ['Roboto'],
              fontSize: TEXTSIZE,
          },
          textAlign: CanvasKit.TextAlign.Left,
      });
      const builder = function() {
          return CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
      }

      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 WIDTH = 400;

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

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

      const editor = MakeEditor(text0, cursor, WIDTH, builder);

      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.save();
        canvas.translate(LOC_X, LOC_Y);

        canvas.drawRect([0, 0, editor.width(), editor.height()], bgPaint);

        cursor.draw_before(canvas);
        for (const l of lines) {
            for (let r of l.runs) {
                canvas.drawGlyphs(r.glyphs, r.positions, 0, 0, font, fontPaint);
            }
        }
        cursor.draw_after(canvas);
        canvas.restore();

        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); break;
              case 'ArrowRight': editor.moveDX(1); break;
              case 'ArrowUp':
                e.preventDefault();
                editor.moveDY(-1);
                break;
              case 'ArrowDown':
                e.preventDefault();
                editor.moveDY(1);
                break;
              case 'Backspace':
                editor.deleteSelection();
                break;
              case 'Shift':
                break;
              default:
                if (!e.ctrlKey && !e.metaKey) {
                    e.preventDefault(); // at least needed for 'space'
                    editor.insert(e.key);
                }
                break;
          }
      }

      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>
