﻿<!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;
  }

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


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

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

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

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

  var CanvasKit = null;
  var legoJSON = null;
  var drinksJSON = null;
  var confettiJSON = null;
  var onboardingJSON = null;
  var multiFrameJSON = null;
  var fullBounds = {fLeft: 0, fTop: 0, fRight: 500, fBottom: 500};

  var robotoData = null;
  var notoserifData = null;

  var flightAnimGif = null;
  var skpData = null;
  var cdn = 'https://storage.googleapis.com/skia-cdn/misc/';
  const ckLoaded = CanvasKitInit({
    locateFile: (file) => '/node_modules/canvaskit/bin/'+file,
  }).ready();
  ckLoaded.then((CK) => {
    CanvasKit = CK;
    // Set bounds to fix the 4:3 resolution of the legos
    SkottieExample(CanvasKit, 'sk_legos', legoJSON,
                  {fLeft: -50, fTop: 0, fRight: 350, fBottom: 300});
    // Re-size to fit
    SkottieExample(CanvasKit, 'sk_drinks', drinksJSON, fullBounds);
    SkottieExample(CanvasKit, 'sk_party', confettiJSON, fullBounds);
    SkottieExample(CanvasKit, 'sk_onboarding', onboardingJSON, fullBounds);
    SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, {
      'image_0.png': flightAnimGif,
    });
    ParticlesAPI1(CanvasKit);

    ParagraphAPI1(CanvasKit, robotoData);

    RTShaderAPI1(CanvasKit);

    SkpExample(CanvasKit, skpData);
  });

  fetch(cdn + 'lego_loader.json').then((resp) => {
    resp.text().then((str) => {
      legoJSON = str;
      SkottieExample(CanvasKit, 'sk_legos', legoJSON,
                    {fLeft: -50, fTop: 0, fRight: 350, fBottom: 300});
    });
  });

  fetch(cdn + 'drinks.json').then((resp) => {
    resp.text().then((str) => {
      drinksJSON = str;
      SkottieExample(CanvasKit, 'sk_drinks', drinksJSON, fullBounds);
    });
  });

  fetch(cdn + 'confetti.json').then((resp) => {
    resp.text().then((str) => {
      confettiJSON = str;
      SkottieExample(CanvasKit, 'sk_party', confettiJSON, fullBounds);
    });
  });

  fetch(cdn + 'onboarding.json').then((resp) => {
    resp.text().then((str) => {
      onboardingJSON = str;
      SkottieExample(CanvasKit, 'sk_onboarding', onboardingJSON, fullBounds);
    });
  });

  fetch(cdn + 'skottie_sample_multiframe.json').then((resp) => {
    resp.text().then((str) => {
      multiFrameJSON = str;
      SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, {
        'image_0.png': flightAnimGif,
      });
    });
  });

  fetch(cdn + 'flightAnim.gif').then((resp) => {
    resp.arrayBuffer().then((buffer) => {
      flightAnimGif = buffer;
      SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, {
        'image_0.png': flightAnimGif,
      });
    });
  });

  fetch(cdn + 'Roboto-Regular.ttf').then((resp) => {
    resp.arrayBuffer().then((buffer) => {
      robotoData = buffer;
      ParagraphAPI1(CanvasKit, robotoData);
    });
  });

  fetch(cdn + 'picture2.skp').then((response) => response.arrayBuffer()).then((buffer) => {
    skpData = buffer;
    SkpExample(CanvasKit, skpData);
  });

  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());
  Promise.all([ckLoaded, loadBrickTex, loadBrickBump]).then((results) => {Camera3D(...results)});

  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 || {fLeft: 0, fTop: 0, fRight: size.w, fBottom: 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);
      // TODO: SkRect.isEmpty()?
      if (damage.fRight > damage.fLeft && damage.fBottom > damage.fTop) {
        canvas.clear(CanvasKit.WHITE);
        animation.render(canvas, bounds);
      }
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    //animation.delete();
    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);
  }

const curves = {
   "MaxCount": 1000,
   "Drawable": {
      "Type": "SkCircleDrawable",
      "Radius": 2
   },
   "EffectCode": [
      "void effectSpawn(inout Effect effect) {",
      "  effect.rate = 200;",
      "  effect.color = float4(1, 0, 0, 1);",
      "}",
      ""
   ],
   "Code": [
      "void spawn(inout Particle p) {",
      "  p.lifetime = 3 + rand;",
      "  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);",
      "  if (rand < 0.5) { p.pos.x = -p.pos.x; }",
      "",
      "  p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand)) / 255;",
      "}",
      ""
   ],
   "Bindings": []
};

  function SurfaceAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('surfaces');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();

    // create a subsurface as a temporary workspace.
    const subSurface = surface.makeSurface({
      width: 50,
      height: 50,
      alphaType: CanvasKit.AlphaType.Premul,
      colorType: CanvasKit.ColorType.RGBA_8888,
    });

    if (!subSurface) {
      console.error('Could not make subsurface');
      return;
    }

    // draw a small "scene"
    const paint = new CanvasKit.SkPaint();
    paint.setColor(CanvasKit.Color(139, 228, 135, 0.95)); // greenish
    paint.setStyle(CanvasKit.PaintStyle.Fill);
    paint.setAntiAlias(true);

    const subCanvas = subSurface.getCanvas();
    subCanvas.clear(CanvasKit.BLACK);
    subCanvas.drawRect(CanvasKit.LTRBRect(5, 15, 45, 40), paint);

    paint.setColor(CanvasKit.Color(214, 93, 244)); // purplish
    for (let i = 0; i < 10; i++) {
      const x = Math.random() * 50;
      const y = Math.random() * 50;

      subCanvas.drawOval(CanvasKit.XYWHRect(x, y, 6, 6), paint);
    }

    // Snap it off as an SkImage - this image will be in the form the
    // parent surface prefers (e.g. Texture for GPU / Raster for CPU).
    const img = subSurface.makeImageSnapshot();

    // clean up the temporary surface
    subSurface.delete();
    paint.delete();

    // Make it repeat a bunch with a shader
    const pattern = img.makeShader(CanvasKit.TileMode.Repeat, CanvasKit.TileMode.Mirror);
    const patternPaint = new CanvasKit.SkPaint();
    patternPaint.setShader(pattern);

    let i = 0;

    function drawFrame() {
      i++;
      CanvasKit.setCurrentContext(context);
      canvas.clear(CanvasKit.WHITE);

      canvas.drawOval(CanvasKit.LTRBRect(i % 60, i % 60, 300 - (i% 60), 300 - (i % 60)), patternPaint);
      surface.flush();
      window.requestAnimationFrame(drawFrame);
    }
    window.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.SkFontMgr.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 font = new CanvasKit.SkFont(null, 18);
    const fontPaint = new CanvasKit.SkPaint();
    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);

      let posA = paragraph.getGlyphPositionAtCoordinate(X, Y);
      canvas.drawText(`At (${X.toFixed(2)}, ${Y.toFixed(2)}) glyph is ${posA.pos}`, 5, 450, fontPaint, font);

      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;
  }

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

    void main(float2 p, inout half4 color) {
        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);
        color = half4(mix(in_colors0, in_colors1, t));
    }`;

  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.SkRuntimeEffect.Make(spiralSkSL);
    const shader = effect.makeShader([
      0.5,
      150, 150,
      0, 1, 0, 1,
      1, 0, 0, 1], true);
    const paint = new CanvasKit.SkPaint();
    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.makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
                                        CanvasKit.SkMatrix.scaled(quadrantSize/dogImg.width(),
                                                                  quadrantSize/dogImg.height()));
    const mandrillShader = mandrillImg.makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
                                                  CanvasKit.SkMatrix.scaled(
                                                    quadrantSize/mandrillImg.width(),
                                                    quadrantSize/mandrillImg.height()));

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

    const prog = `
      in fragmentProcessor before_map;
      in fragmentProcessor after_map;
      in fragmentProcessor 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);
      }

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

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

    const canvas = surface.getCanvas();

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

    const draw = (x, y, shader) => {
      const paint = new CanvasKit.SkPaint();
      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.SkImageFilter.MakeBlur(0.1, 0.1, CanvasKit.TileMode.Clamp, null);

      const paint = new CanvasKit.SkPaint();
      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.MakeSkPicture(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);
  }

  function Camera3D(canvas, textureImgData, normalImgData) {
    if (!canvas) {

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

    const sizeX = document.getElementById('camera3d').width;
    const sizeY = document.getElementById('camera3d').height;

    let clickToWorld = CanvasKit.SkM44.identity();
    let worldToClick = CanvasKit.SkM44.identity();
    // rotation of the cube shown in the demo
    let rotation = CanvasKit.SkM44.identity();
    // temporary during a click and drag
    let clickRotation = CanvasKit.SkM44.identity();

    // A virtual sphere used for tumbling the object on screen.
    const vSphereCenter = [sizeX/2, sizeY/2];
    const vSphereRadius = Math.min(...vSphereCenter);

    // The rounded rect used for each face
    const margin = vSphereRadius / 20;
    const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(margin, margin,
      vSphereRadius - margin, vSphereRadius - margin), margin*2.5, margin*2.5);

    const camNear = 0.05;
    const camFar = 4;
    const camAngle = Math.PI / 12;

    const camEye = [0, 0, 1 / Math.tan(camAngle/2) - 1];
    const camCOA = [0, 0, 0];
    const camUp =  [0, 1, 0];

    let mouseDown = false;
    let clickDown = [0, 0]; // location of click down
    let lastMouse = [0, 0]; // last mouse location

    // keep spinning after mouse up. Also start spinning on load
    let axis = [0.4, 1, 1];
    let totalSpin = 0;
    let spinRate = 0.1;
    let lastRadians = 0;
    let spinning = setInterval(keepSpinning, 30);

    const textPaint = new CanvasKit.SkPaint();
    textPaint.setColor(CanvasKit.BLACK);
    textPaint.setAntiAlias(true);
    const roboto = CanvasKit.SkFontMgr.RefDefault().MakeTypefaceFromData(robotoData);
    const textFont = new CanvasKit.SkFont(roboto, 30);

    const imgscale = CanvasKit.SkMatrix.scaled(2, 2);
    const textureShader = CanvasKit.MakeImageFromEncoded(textureImgData).makeShader(
      CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp, imgscale);
    const normalShader = CanvasKit.MakeImageFromEncoded(normalImgData).makeShader(
      CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp, imgscale);
    const children = [textureShader, normalShader];

    const prog = `
      in fragmentProcessor color_map;
      in fragmentProcessor normal_map;

      uniform float4x4 localToWorld;
      uniform float4x4 localToWorldAdjInv;
      uniform float3   lightPos;

      float3 convert_normal_sample(half4 c) {
          float3 n = 2 * c.rgb - 1;
          n.y = -n.y;
          return n;
      }

      void main(float2 p, inout half4 color) {
          float3 norm = convert_normal_sample(sample(normal_map, p));
          float3 plane_norm = normalize(localToWorld * float4(norm, 0)).xyz;

          float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
          float3 light_dir = normalize(lightPos - plane_pos);

          float ambient = 0.2;
          float dp = dot(plane_norm, light_dir);
          float scale = min(ambient + max(dp, 0), 1);

          color = sample(color_map, p) * half4(float4(scale, scale, scale, 1));
      }
`;
    const fact = CanvasKit.SkRuntimeEffect.Make(prog);

    // properties of light
    let lightLocation = [...vSphereCenter];
    let lightDistance = vSphereRadius;
    let lightIconRadius = 12;
    let draggingLight = false;

    function computeLightWorldPos() {
      return CanvasKit.SkVector.add(CanvasKit.SkVector.mulScalar([...vSphereCenter, 0], 0.5),
        CanvasKit.SkVector.mulScalar(vSphereUnitV3(lightLocation), lightDistance));
    }

    let lightWorldPos = computeLightWorldPos();

    function drawLight(canvas) {
      const paint = new CanvasKit.SkPaint();
      paint.setAntiAlias(true);
      paint.setColor(CanvasKit.WHITE);
      canvas.drawCircle(...lightLocation, lightIconRadius + 2, paint);
      paint.setColor(CanvasKit.BLACK);
      canvas.drawCircle(...lightLocation, lightIconRadius, paint);
    }

    // Takes an x and y rotation in radians and a scale and returns a 4x4 matrix used to draw a
    // face of the cube in that orientation.
    function faceM44(rx, ry, scale) {
      return CanvasKit.SkM44.multiply(
        CanvasKit.SkM44.rotated([0,1,0], ry),
        CanvasKit.SkM44.rotated([1,0,0], rx),
        CanvasKit.SkM44.translated([0, 0, scale]));
    }

    const faceScale = vSphereRadius/2
    const faces = [
      {matrix: faceM44(         0,         0, faceScale ), color:CanvasKit.RED}, // front
      {matrix: faceM44(         0,   Math.PI, faceScale ), color:CanvasKit.GREEN}, // back

      {matrix: faceM44( Math.PI/2,         0, faceScale ), color:CanvasKit.BLUE}, // top
      {matrix: faceM44(-Math.PI/2,         0, faceScale ), color:CanvasKit.CYAN}, // bottom

      {matrix: faceM44(         0, Math.PI/2, faceScale ), color:CanvasKit.MAGENTA}, // left
      {matrix: faceM44(         0,-Math.PI/2, faceScale ), color:CanvasKit.YELLOW}, // right
    ];

    // Returns a component of the matrix m indicating whether it faces the camera.
    // If it's positive for one of the matrices representing the face of the cube,
    // that face is currently in front.
    function front(m) {
      // Is this invertible?
      var m2 = CanvasKit.SkM44.invert(m);
      if (m2 === null) {
        m2 = CanvasKit.SkM44.identity();
      }
      // look at the sign of the z-scale of the inverse of m.
      // that's the number in row 2, col 2.
      return m2[10]
    }

    // Return the inverse of an SkM44. throw an error if it's not invertible
    function mustInvert(m) {
      var m2 = CanvasKit.SkM44.invert(m);
      if (m2 === null) {
        throw "Matrix not invertible";
      }
      return m2;
    }

    function saveCamera(canvas, /* rect */ area, /* scalar */ zscale) {
      const camera = CanvasKit.SkM44.lookat(camEye, camCOA, camUp);
      const perspective = CanvasKit.SkM44.perspective(camNear, camFar, camAngle);
      // Calculate viewport scale. Even through we know these values are all constants in this
      // example it might be handy to change the size later.
      const center = [(area.fLeft + area.fRight)/2, (area.fTop + area.fBottom)/2, 0];
      const viewScale = [(area.fRight - area.fLeft)/2, (area.fBottom - area.fTop)/2, zscale];
      const viewport = CanvasKit.SkM44.multiply(
        CanvasKit.SkM44.translated(center),
        CanvasKit.SkM44.scaled(viewScale));

      // want "world" to be in our big coordinates (e.g. area), so apply this inverse
      // as part of our "camera".
      canvas.saveCamera(
        CanvasKit.SkM44.multiply(viewport, perspective),
        CanvasKit.SkM44.multiply(camera, mustInvert(viewport)));
    }

    function setClickToWorld(canvas, matrix) {
      const l2d = canvas.getLocalToDevice();
      worldToClick = CanvasKit.SkM44.multiply(mustInvert(matrix), l2d);
      clickToWorld = mustInvert(worldToClick);
    }

    function drawCubeFace(canvas, m, color) {
      const trans = new CanvasKit.SkM44.translated([vSphereRadius/2, vSphereRadius/2, 0]);
      canvas.concat44(CanvasKit.SkM44.multiply(trans, m, mustInvert(trans)));
      const znormal = front(canvas.getLocalToDevice());
      if (znormal < 0) {
        return; // skip faces facing backwards
      }
      const ltw = canvas.getLocalToWorld();
      // shader expects the 4x4 matrices in column major order.
      const uniforms = [...CanvasKit.SkM44.transpose(ltw), ...mustInvert(ltw), ...lightWorldPos];
      const paint = new CanvasKit.SkPaint();
      paint.setAntiAlias(true);
      const shader = fact.makeShaderWithChildren(uniforms, true /*=opaque*/, children);
      paint.setShader(shader);
      canvas.drawRRect(rr, paint);
      canvas.drawText(znormal.toFixed(2), faceScale*0.25, faceScale*0.4, textPaint, textFont);
    }

    function drawFrame(canvas) {
      const clickM = canvas.getLocalToDevice();
      canvas.save();
      canvas.translate(vSphereCenter[0] - vSphereRadius/2, vSphereCenter[1] - vSphereRadius/2);
      // pass surface dimensions as viewport size.
      saveCamera(canvas, CanvasKit.LTRBRect(0, 0, vSphereRadius, vSphereRadius), vSphereRadius/2);
      setClickToWorld(canvas, clickM);
      for (let f of faces) {
        const saveCount = canvas.getSaveCount();
        canvas.save();
        drawCubeFace(canvas, CanvasKit.SkM44.multiply(clickRotation, rotation, f.matrix), f.color);
        canvas.restoreToCount(saveCount);
      }
      canvas.restore();  // camera
      canvas.restore();  // center the following content in the window

      // draw virtual sphere outline.
      const paint = new CanvasKit.SkPaint();
      paint.setAntiAlias(true);
      paint.setStyle(CanvasKit.PaintStyle.Stroke);
      paint.setColor(CanvasKit.Color(64, 255, 0, 1.0));
      canvas.drawCircle(vSphereCenter[0], vSphereCenter[1], vSphereRadius, paint);
      canvas.drawLine(vSphereCenter[0], vSphereCenter[1] - vSphereRadius,
                       vSphereCenter[0], vSphereCenter[1] + vSphereRadius, paint);
      canvas.drawLine(vSphereCenter[0] - vSphereRadius, vSphereCenter[1],
                       vSphereCenter[0] + vSphereRadius, vSphereCenter[1], paint);

      drawLight(canvas);
    }

    // convert a 2D point in the circle displayed on screen to a 3D unit vector.
    // the virtual sphere is a technique selecting a 3D direction by clicking on a the projection
    // of a hemisphere.
    function vSphereUnitV3(p) {
      // v = (v - fCenter) * (1 / fRadius);
      let v = CanvasKit.SkVector.mulScalar(CanvasKit.SkVector.sub(p, vSphereCenter), 1/vSphereRadius);

      // constrain the clicked point within the circle.
      let len2 = CanvasKit.SkVector.lengthSquared(v);
      if (len2 > 1) {
          v = CanvasKit.SkVector.normalize(v);
          len2 = 1;
      }
      // the closer to the edge of the circle you are, the closer z is to zero.
      const z = Math.sqrt(1 - len2);
      v.push(z);
      return v;
    }

    function computeVSphereRotation(start, end) {
      const u = vSphereUnitV3(start);
      const v = vSphereUnitV3(end);
      // Axis is in the scope of the Camera3D function so it can be used in keepSpinning.
      axis = CanvasKit.SkVector.cross(u, v);
      const sinValue = CanvasKit.SkVector.length(axis);
      const cosValue = CanvasKit.SkVector.dot(u, v);

      let m = new CanvasKit.SkM44.identity();
      if (Math.abs(sinValue) > 0.000000001) {
          m = CanvasKit.SkM44.rotatedUnitSinCos(
            CanvasKit.SkVector.mulScalar(axis, 1/sinValue), sinValue, cosValue);
          const radians = Math.atan(cosValue / sinValue);
          spinRate = lastRadians - radians;
          lastRadians = radians;
      }
      return m;
    }

    function keepSpinning() {
      totalSpin += spinRate;
      clickRotation = CanvasKit.SkM44.rotated(axis, totalSpin);
      spinRate *= .998;
      if (spinRate < 0.01) {
        stopSpinning();
      }
      surface.requestAnimationFrame(drawFrame);
    }

    function stopSpinning() {
        clearInterval(spinning);
        rotation = CanvasKit.SkM44.multiply(clickRotation, rotation);
        clickRotation = CanvasKit.SkM44.identity();
    }

    function interact(e) {
      const type = e.type;
      let eventPos = [e.offsetX, e.offsetY];
      if (type === 'lostpointercapture' || type === 'pointerup' || type == 'pointerleave') {
        if (draggingLight) {
          draggingLight = false;
        } else if (mouseDown) {
          mouseDown = false;
          if (spinRate > 0.02) {
            stopSpinning();
            spinning = setInterval(keepSpinning, 30);
          }
        } else {
          return;
        }
        return;
      } else if (type === 'pointermove') {
        if (draggingLight) {
          lightLocation = eventPos;
          lightWorldPos = computeLightWorldPos();
        } else if (mouseDown) {
          lastMouse = eventPos;
          clickRotation = computeVSphereRotation(clickDown, lastMouse);
        } else {
          return;
        }
      } else if (type === 'pointerdown') {
        // Are we repositioning the light?
        if (CanvasKit.SkVector.dist(eventPos, lightLocation) < lightIconRadius) {
          draggingLight = true;
          return;
        }
        stopSpinning();
        mouseDown = true;
        clickDown = eventPos;
        lastMouse = eventPos;
      }
      surface.requestAnimationFrame(drawFrame);
    };

    document.getElementById('camera3d').addEventListener('pointermove', interact);
    document.getElementById('camera3d').addEventListener('pointerdown', interact);
    document.getElementById('camera3d').addEventListener('lostpointercapture', interact);
    document.getElementById('camera3d').addEventListener('pointerleave', interact);
    document.getElementById('camera3d').addEventListener('pointerup', interact);

    surface.requestAnimationFrame(drawFrame);
  }
</script>
