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

<h2> Use of offscreen surfaces </h2>
<canvas id=surfaces 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,
  });
  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);

    SurfaceAPI1(CanvasKit);
  });

  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.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": []
};

  function SurfaceAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('surfaces');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    console.log('SurfaceAPI1 top surface type = '+surface.reportBackendType() );
    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;
    }
    console.log('SurfaceAPI1 subSurface type = '+subSurface.reportBackendType() );

    // 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 shader before_map;
      in shader after_map;
      in 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);
      }

      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 shader color_map;
      in shader normal_map;

      uniform float3   lightPos;
      layout (marker=local_to_world)          uniform float4x4 localToWorld;
      layout (marker=normals(local_to_world)) uniform float4x4 localToWorldAdjInv;

      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(localToWorldAdjInv * 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.concat(CanvasKit.SkM44.multiply(viewport, perspective));
      canvas.concat(CanvasKit.SkM44.multiply(camera, mustInvert(viewport)));
      // Mark the matrix to make it available to the shader by this name.
      canvas.markCTM('local_to_world');
    }

    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.concat(CanvasKit.SkM44.multiply(trans, m, mustInvert(trans)));
      const znormal = front(canvas.getLocalToDevice());
      if (znormal < 0) {
        return; // skip faces facing backwards
      }
      // Pad with space for two 4x4 matrices. Even though the shader uses a layout()
      // statement to populate them, we still have to reserve space for them.
      const uniforms = [...lightWorldPos, ...Array(32).fill(0)];
      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>
