<!DOCTYPE html>
<title>CanvasKit (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>
  svg, canvas, img {
    border: 1px dashed #AAA;
  }

  #patheffect,#paths,#sk_drinks,#sk_party, #sk_legos, #sk_onboarding,
  #api1_c, #api2_c {
    width: 300px;
    height: 300px;
  }

</style>

<h2>Drop in replacement for HTML Canvas (e.g. node.js)</h2>
<img id=api1 width=300 height=300>
<canvas id=api1_c width=300 height=300></canvas>
<img id=api2 width=300 height=300>
<canvas id=api2_c width=300 height=300></canvas>
<img id=api3 width=300 height=300>
<canvas id=api3_c width=300 height=300></canvas>
<img id=api4 width=300 height=300>
<canvas id=api4_c width=300 height=300></canvas>

<h2> CanvasKit draws Paths to the browser</h2>
<canvas id=vertex1 width=300 height=300></canvas>
<canvas id=vertex2 width=300 height=300></canvas>
<canvas id=gradient1 width=300 height=300></canvas>
<canvas id=patheffect width=300 height=300></canvas>
<canvas id=paths width=200 height=200></canvas>
<canvas id=ink width=300 height=300></canvas>

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

<!-- Doesn't work yet. -->
<button id=lego_btn>Take a picture of the legos</button>

<h2> Nima </h2>

<canvas id=nima_example width=300 height=300></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 fullBounds = {fLeft: 0, fTop: 0, fRight: 500, fBottom: 500};

  var nimaFile = null;
  var nimaTexture = null;

  var bonesImage = null;
  CanvasKitInit({
    locateFile: (file) => '/node_modules/canvaskit/bin/'+file,
  }).then((CK) => {
     // when debugging, it can be handy to not run directly in the then, because if there
     // is a failure (for example, miscalling an API), the WASM loader tries to re-load
     // the web assembly in the (much slower) ArrayBuffer version. This will also fail
     // and thus there is a lot of extra log spew.
     // Thus, the setTimeout to run on the next microtask avoids this second loading
     // and the log spew.
    setTimeout(() => {
      CK.initFonts();
      CanvasKit = CK;
      DrawingExample(CanvasKit);
      PathExample(CanvasKit);
      InkExample(CanvasKit);
      // Set bounds to fix the 4:3 resolution of the legos
      addScreenshotListener(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);

      NimaExample(CanvasKit, nimaFile, nimaTexture);

      CanvasAPI1(CanvasKit);
      CanvasAPI2(CanvasKit);
      CanvasAPI3(CanvasKit);
      CanvasAPI4(CanvasKit);

      VertexAPI1(CanvasKit);
      VertexAPI2(CanvasKit, bonesImage);

      GradiantAPI1(CanvasKit);
    }, 0);
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/lego_loader.json').then((resp) => {
    resp.text().then((str) => {
      legoJSON = str;
      addScreenshotListener(SkottieExample(CanvasKit, 'sk_legos', legoJSON,
                            {fLeft: -50, fTop: 0, fRight: 350, fBottom: 300}));
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/drinks.json').then((resp) => {
    resp.text().then((str) => {
      drinksJSON = str;
      SkottieExample(CanvasKit, 'sk_drinks', drinksJSON, fullBounds);
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/confetti.json').then((resp) => {
    resp.text().then((str) => {
      confettiJSON = str;
      SkottieExample(CanvasKit, 'sk_party', confettiJSON, fullBounds);
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/onboarding.json').then((resp) => {
    resp.text().then((str) => {
      onboardingJSON = str;
      SkottieExample(CanvasKit, 'sk_onboarding', onboardingJSON, fullBounds);
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/robot.nima').then((resp) => {
    resp.blob().then((blob) => {
      let reader = new FileReader();
      reader.addEventListener("loadend", function() {
          nimaFile = reader.result;
          NimaExample(CanvasKit, nimaFile, nimaTexture);
      });
      reader.readAsArrayBuffer(blob);
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/robot.nima.png').then((resp) => {
    resp.blob().then((blob) => {
      let reader = new FileReader();
      reader.addEventListener("loadend", function() {
          nimaTexture = reader.result;
          NimaExample(CanvasKit, nimaFile, nimaTexture);
      });
      reader.readAsArrayBuffer(blob);
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/bones.jpg').then((resp) => {
    resp.blob().then((blob) => {
      let reader = new FileReader();
      reader.addEventListener("loadend", function() {
          bonesImage = reader.result;
          VertexAPI2(CanvasKit, bonesImage);
      });
      reader.readAsArrayBuffer(blob);
    });
  });

  function addScreenshotListener(surface) {
    if (!surface) {
      return;
    }
    if (CanvasKit.gpu) {
      // Doesn't work on GPU (yet)
      document.getElementById('lego_btn').remove();
      return;
    }
    const btn = document.getElementById('lego_btn');
    btn.addEventListener('click', () => {
      const img = surface.makeImageSnapshot()
      if (!img) { return }
      const png = img.encodeToData()
      if (!png) { return }
      const pngBytes = CanvasKit.getSkDataBytes(png);
      // See https://stackoverflow.com/a/12713326
      let b64encoded = btoa(String.fromCharCode.apply(null, pngBytes));
      console.log("base64 encoded image", b64encoded);
    });
  }

  function DrawingExample(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('patheffect');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext(); // only needed for WebGL; no-op for CPU

    const canvas = surface.getCanvas();

    const paint = new CanvasKit.SkPaint();

    const textPaint = new CanvasKit.SkPaint();
    textPaint.setColor(CanvasKit.RED);
    textPaint.setTextSize(30);
    textPaint.setAntiAlias(true);

    let i = 0;

    let X = 128;
    let Y = 128;

    function drawFrame() {
      const path = starPath(CanvasKit, X, Y);
      CanvasKit.setCurrentContext(context);
      const dpe = CanvasKit.MakeSkDashPathEffect([15, 5, 5, 10], i/5);
      i++;

      paint.setPathEffect(dpe);
      paint.setStyle(CanvasKit.PaintStyle.Stroke);
      paint.setStrokeWidth(5.0 + -3 * Math.cos(i/30));
      paint.setAntiAlias(true);
      paint.setColor(CanvasKit.Color(66, 129, 164, 1.0));

      canvas.clear(CanvasKit.TRANSPARENT);

      canvas.drawPath(path, paint);
      canvas.drawText('Try Clicking!', 10, 280, textPaint);

      surface.flush();

      dpe.delete();
      path.delete();
      window.requestAnimationFrame(drawFrame);
    }
    window.requestAnimationFrame(drawFrame);

    // Make animation interactive
    let interact = (e) => {
      if (!e.pressure) {
        return;
      }
      X = e.offsetX;
      Y = e.offsetY;
    };
    document.getElementById('patheffect').addEventListener('pointermove', interact);
    document.getElementById('patheffect').addEventListener('pointerdown', interact);
    preventScrolling(document.getElementById('patheffect'));
    // A client would need to delete this if it didn't go on for ever.
    //paint.delete();
  }

  function PathExample(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('paths');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();

    const canvas = surface.getCanvas();

    function drawFrame() {
      CanvasKit.setCurrentContext(context);
      const paint = new CanvasKit.SkPaint();
      paint.setStrokeWidth(1.0);
      paint.setAntiAlias(true);
      paint.setColor(CanvasKit.Color(0, 0, 0, 1.0));
      paint.setStyle(CanvasKit.PaintStyle.Stroke);

      const path = new CanvasKit.SkPath();
      path.moveTo(20, 5);
      path.lineTo(30, 20);
      path.lineTo(40, 10);
      path.lineTo(50, 20);
      path.lineTo(60, 0);
      path.lineTo(20, 5);

      path.moveTo(20, 80);
      path.cubicTo(90, 10, 160, 150, 190, 10);

      path.moveTo(36, 148);
      path.quadTo(66, 188, 120, 136);
      path.lineTo(36, 148);

      path.moveTo(150, 180);
      path.arcTo(150, 100, 50, 200, 20);
      path.lineTo(160, 160);

      path.moveTo(20, 120);
      path.lineTo(20, 120);

      canvas.drawPath(path, paint);

      surface.flush();

      path.delete();
      paint.delete();
      // Intentionally just draw frame once
    }
    window.requestAnimationFrame(drawFrame);
  }

  function preventScrolling(canvas) {
    canvas.addEventListener('touchmove', (e) => {
      // Prevents touch events in the canvas from scrolling the canvas.
      e.preventDefault();
      e.stopPropagation();
    });
  }

  function InkExample(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('ink');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();

    const canvas = surface.getCanvas();

    let paint = new CanvasKit.SkPaint();
    paint.setAntiAlias(true);
    paint.setColor(CanvasKit.Color(0, 0, 0, 1.0));
    paint.setStyle(CanvasKit.PaintStyle.Stroke);
    paint.setStrokeWidth(4.0);
    paint.setPathEffect(CanvasKit.MakeSkCornerPathEffect(50));

    // Draw I N K
    let path = new CanvasKit.SkPath();
    path.moveTo(80, 30);
    path.lineTo(80, 80);

    path.moveTo(100, 80);
    path.lineTo(100, 15);
    path.lineTo(130, 95);
    path.lineTo(130, 30);

    path.moveTo(150, 30);
    path.lineTo(150, 80);
    path.moveTo(170, 30);
    path.lineTo(150, 55);
    path.lineTo(170, 80);

    let paths = [path];
    let paints = [paint];

    function drawFrame() {
      CanvasKit.setCurrentContext(context);
      canvas.clear(CanvasKit.Color(255, 255, 255, 1.0));

      for (let i = 0; i < paints.length && i < paths.length; i++) {
        canvas.drawPath(paths[i], paints[i]);
      }
      surface.flush();

      window.requestAnimationFrame(drawFrame);
    }

    let hold = false;
    let interact = (e) => {
      let type = e.type;
      if (type === 'lostpointercapture' || type === 'pointerup' || !e.pressure ) {
        hold = false;
        return;
      }
      if (hold) {
        path.lineTo(e.offsetX, e.offsetY);
      } else {
        paint = paint.copy();
        paint.setColor(CanvasKit.Color(Math.random() * 255, Math.random() * 255, Math.random() * 255, Math.random() + .2));
        paints.push(paint);
        path = new CanvasKit.SkPath();
        paths.push(path);
        path.moveTo(e.offsetX, e.offsetY);
      }
      hold = true;
    };
    document.getElementById('ink').addEventListener('pointermove', interact);
    document.getElementById('ink').addEventListener('pointerdown', interact);
    document.getElementById('ink').addEventListener('lostpointercapture', interact);
    document.getElementById('ink').addEventListener('pointerup', interact);
    preventScrolling(document.getElementById('ink'));
    window.requestAnimationFrame(drawFrame);
  }

  function starPath(CanvasKit, X=128, Y=128, R=116) {
    let p = new CanvasKit.SkPath();
    p.moveTo(X + R, Y);
    for (let i = 1; i < 8; i++) {
      let a = 2.6927937 * i;
      p.lineTo(X + R * Math.cos(a), Y + R * Math.sin(a));
    }
    return p;
  }

  function fps(frameTimes) {
    let total = 0;
    for (let ft of frameTimes) {
      total += ft;
    }
    return frameTimes.length / total;
  }

  function SkottieExample(CanvasKit, id, jsonStr, bounds) {
    if (!CanvasKit || !jsonStr) {
      return;
    }
    const animation = CanvasKit.MakeAnimation(jsonStr);
    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};

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

    let firstFrame = Date.now();

    function drawFrame() {
      let seek = ((Date.now() - firstFrame) / duration) % 1.0;
      CanvasKit.setCurrentContext(context);
      animation.seek(seek);
      canvas.clear(CanvasKit.TRANSPARENT);
      animation.render(canvas, bounds);
      surface.flush();
      window.requestAnimationFrame(drawFrame);
    }
    window.requestAnimationFrame(drawFrame);

    //animation.delete();
    return surface;
  }

  function CanvasAPI1(CanvasKit) {
    let skcanvas = CanvasKit.MakeCanvas(300, 300);
    let realCanvas = document.getElementById('api1_c');

    for (let canvas of [skcanvas, realCanvas]) {
      let ctx = canvas.getContext('2d');
      ctx.font = '30px Impact'
      ctx.rotate(.1);
      let text = ctx.measureText('Awesome');
      ctx.fillText('Awesome ', 50, 100);
      ctx.strokeText('Groovy!', 60+text.width, 100);

      // Draw line under Awesome
      ctx.strokeStyle = 'rgba(125,0,0,0.5)';
      ctx.beginPath();
      ctx.lineWidth=6;
      ctx.lineTo(50, 105);
      ctx.lineTo(50 + text.width, 105);
      ctx.stroke();
    }

    // TODO load image
    document.getElementById('api1').src = skcanvas.toDataURL();
  }

  function CanvasAPI2(CanvasKit) {
    let skcanvas = CanvasKit.MakeCanvas(300, 300);
    let realCanvas = document.getElementById('api2_c');
    realCanvas.width = 300;
    realCanvas.height = 300;

    for (let canvas of [skcanvas, realCanvas]) {
      let ctx = canvas.getContext('2d');
      ctx.scale(1.5, 1.5);
      ctx.moveTo(20, 5);
      ctx.lineTo(30, 20);
      ctx.lineTo(40, 10);
      ctx.lineTo(50, 20);
      ctx.lineTo(60, 0);
      ctx.lineTo(20, 5);

      ctx.moveTo(20, 80);
      ctx.bezierCurveTo(90, 10, 160, 150, 190, 10);

      ctx.moveTo(36, 148);
      ctx.quadraticCurveTo(66, 188, 120, 136);
      ctx.lineTo(36, 148);

      ctx.rect(5, 170, 20, 25);

      ctx.moveTo(150, 180);
      ctx.arcTo(150, 100, 50, 200, 20);
      ctx.lineTo(160, 160);

      ctx.moveTo(20, 120);
      ctx.arc(20, 120, 18, 0, 1.75 * Math.PI);
      ctx.lineTo(20, 120);

      ctx.moveTo(150, 5);
      ctx.ellipse(130, 25, 30, 10, -1*Math.PI/8, Math.PI/6, 1.5*Math.PI);

      ctx.lineWidth = 4/3;
      ctx.stroke();
    }
    document.getElementById('api2').src = skcanvas.toDataURL();
  }

  function CanvasAPI3(CanvasKit) {
    let skcanvas = CanvasKit.MakeCanvas(300, 300);
    let realCanvas = document.getElementById('api3_c');
    realCanvas.width = 300;
    realCanvas.height = 300;

    for (let canvas of [skcanvas, realCanvas]) {
      let ctx = canvas.getContext('2d');
      ctx.rect(10, 10, 20, 20);

      ctx.scale(2.0, 4.0);
      ctx.rect(30, 10, 20, 20);
      ctx.resetTransform();

      ctx.rotate(Math.PI / 3);
      ctx.rect(50, 10, 20, 20);
      ctx.resetTransform();

      ctx.translate(30, -2);
      ctx.rect(70, 10, 20, 20);
      ctx.resetTransform();

      ctx.translate(60, 0);
      ctx.rotate(Math.PI / 6);
      ctx.transform(1.5, 0, 0, 0.5, 0, 0, 0); // effectively scale
      ctx.rect(90, 10, 20, 20);
      ctx.resetTransform();

      ctx.setTransform(2, 0, -.5, 2.5, -40, 120);
      ctx.rect(110, 10, 20, 20);
      ctx.lineTo(110, 0);
      ctx.resetTransform();
      ctx.lineTo(220, 120);

      ctx.scale(3.0, 3.0);
      ctx.font = '6pt Arial';
      ctx.fillText('This text should be huge', 10, 80);
      ctx.resetTransform();

      ctx.strokeStyle = 'black';
      ctx.lineWidth = 2;
      ctx.stroke();

      ctx.beginPath();
      ctx.moveTo(250, 30);
      ctx.lineTo(250, 80);
      ctx.scale(3.0, 3.0);
      ctx.lineTo(280/3, 90/3);
      ctx.closePath();
      ctx.strokeStyle = 'black';
      ctx.lineWidth = 5;
      ctx.stroke();

    }
    document.getElementById('api3').src = skcanvas.toDataURL();
  }

  function CanvasAPI4(CanvasKit) {
    let skcanvas = CanvasKit.MakeCanvas(300, 300);
    let realCanvas = document.getElementById('api4_c');
    realCanvas.width = 300;
    realCanvas.height = 300;

    for (let canvas of [skcanvas, realCanvas]) {
      let ctx = canvas.getContext('2d');

      ctx.strokeStyle = '#000';
      ctx.fillStyle = '#CCC';
      ctx.shadowColor = 'rebeccapurple';
      ctx.shadowBlur = 1;
      ctx.shadowOffsetX = 3;
      ctx.shadowOffsetY = -8;
      ctx.rect(10, 10, 30, 30);

      ctx.save();
      ctx.strokeStyle = '#C00';
      ctx.fillStyle = '#00C';
      ctx.shadowBlur = 0;
      ctx.shadowColor = 'transparent';

      ctx.stroke();

      ctx.restore();
      ctx.fill();

      ctx.beginPath();
      ctx.moveTo(36, 148);
      ctx.quadraticCurveTo(66, 188, 120, 136);
      ctx.closePath();
      ctx.stroke();

      ctx.beginPath();
      ctx.shadowColor = '#993366AA';
      ctx.shadowOffsetX = 8;
      ctx.shadowBlur = 5;
      ctx.setTransform(2, 0, -.5, 2.5, -40, 120);
      ctx.rect(110, 10, 20, 20);
      ctx.lineTo(110, 0);
      ctx.resetTransform();
      ctx.lineTo(220, 120);
      ctx.stroke();

      ctx.fillStyle = 'green';
      ctx.font = '16pt Arial';
      ctx.fillText('This should be shadowed', 20, 80);

    }
    document.getElementById('api4').src = skcanvas.toDataURL();
  }

  function NimaExample(CanvasKit, nimaFile, nimaTexture) {
    if (!CanvasKit || !nimaFile || !nimaTexture) {
      return;
    }
    const animation = CanvasKit.MakeNimaActor(nimaFile, nimaTexture);
    if (!animation) {
      console.error('could not make animation');
      return;
    }

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

    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    canvas.translate(125, 275);
    canvas.scale(0.4, -0.4);

    let firstFrame = Date.now();
    animation.setAnimationByName('attack');

    function drawFrame() {
      let seek = ((Date.now() - firstFrame) / 1000.0);
      CanvasKit.setCurrentContext(context);
      canvas.clear(CanvasKit.TRANSPARENT);
      animation.seek(seek);
      animation.render(canvas);
      surface.flush();
      window.requestAnimationFrame(drawFrame);
    }
    window.requestAnimationFrame(drawFrame);
  }

  function VertexAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('vertex1');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    let paint = new CanvasKit.SkPaint();

    // See https://fiddle.skia.org/c/f48b22eaad1bb7adcc3faaa321754af6
    // for original c++ version.
    let points = [[ 0, 0 ], [ 250, 0 ], [ 100, 100 ], [ 0, 250 ]];
    let colors = [CanvasKit.RED, CanvasKit.BLUE,
                  CanvasKit.YELLOW, CanvasKit.CYAN];
    let vertices = CanvasKit.MakeSkVertices(CanvasKit.VertexMode.TriangleFan,
                                            points, null, colors);

    canvas.drawVertices(vertices, CanvasKit.BlendMode.Src, paint);
    surface.flush();

    vertices.delete();

    // See https://fiddle.skia.org/c/e8bdae9bea3227758989028424fcac3d
    // for original c++ version.
    points   = [[ 300, 300 ], [ 50, 300 ], [ 200, 200 ], [ 300, 50 ]];
    let texs = [[   0,   0 ], [  0, 250 ], [ 250, 250 ], [ 250,  0 ]];
    vertices = CanvasKit.MakeSkVertices(CanvasKit.VertexMode.TriangleFan,
                                            points, texs, colors);

    let shader = CanvasKit.MakeLinearGradientShader([0, 0], [250, 0],
            colors, null, CanvasKit.TileMode.Clamp);
    paint.setShader(shader);

    canvas.drawVertices(vertices, CanvasKit.BlendMode.Darken, paint);
    surface.flush();

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

  function VertexAPI2(CanvasKit, bonesImage) {
    if (!CanvasKit || !bonesImage) {
      return;
    }
    const surface = CanvasKit.MakeCanvasSurface('vertex2');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    let paint = new CanvasKit.SkPaint();

    let shader = CanvasKit.MakeImageShader(bonesImage,
                    CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp);

    // comment this out to see just the triangles move.
    paint.setShader(shader);

    // points is the destination location on the canvas  We want the output
    // to be a 280x280 box (to start).
    let points   = [[ 0, 0 ],  [ 280, 0 ], [ 280, 280 ], [ 0, 280 ]];
    // texs is the coordinates of the source in the texture
    // (provided by the image shader). The image is 334x226 px big.
    let texs     = [[ 0, 0 ],  [ 334, 0 ], [ 334, 226 ], [ 0, 226 ]];
    let boneidxs = [[1,0,0,0], [2,0,0,0],  [3,0,0,0],    [2,3,0,0]];
    let bonewts  = [[1,0,0,0], [1,0,0,0],  [1,0,0,0],    [.5,.5,0,0]];
    let vertices = CanvasKit.MakeSkVertices(CanvasKit.VertexMode.TriangleFan,
                                            points, texs, null, boneidxs, bonewts);

    function drawFrame() {
      let now = Date.now();
      let bones = [
        [[1,0, // world bone (move 10px down and to the right to center)
          0,1,
          10,10]],
        [[1,0, // identity bone (bone for vertices that are static)
          0,1,
          0,0]],
        [[1,0, // ossilate in x bone
          0,1,
          10*Math.sin(now/500),0]],
        [[1,0, // ossilate in y bone
          0,1,
          0,30*Math.cos(now/500)]],
      ];
      let tVerts = vertices.applyBones(bones);
      CanvasKit.setCurrentContext(context);
      //canvas.clear(CanvasKit.TRANSPARENT);
      canvas.drawVertices(tVerts, CanvasKit.BlendMode.Src, paint);
      surface.flush();

      tVerts.delete();
      window.requestAnimationFrame(drawFrame);
    }
    window.requestAnimationFrame(drawFrame);
    //tVerts.delete();
    //vertices.delete();

    //shader && shader.delete();
    //paint.delete();
    //surface.delete();

  }

  function GradiantAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('gradient1');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    let paint = new CanvasKit.SkPaint();

    // See https://fiddle.skia.org/c/f48b22eaad1bb7adcc3faaa321754af6
    // for original c++ version.
    let points = [[ 0, 0 ], [ 250, 0 ], [ 100, 100 ], [ 0, 250 ]];
    let colors = [CanvasKit.BLUE, CanvasKit.YELLOW, CanvasKit.RED];
    let pos =    [0, .7, 1.0];
    let transform = [2, 0, 0,
                     0, 2, 0,
                     0, 0, 1]
    let shader = CanvasKit.MakeRadialGradientShader([150,150], 130, colors,
                              pos, CanvasKit.TileMode.Mirror, transform);

    paint.setShader(shader);
    paint.setTextSize(100);
    canvas.drawText("Radial", 10, 200, paint);
    surface.flush();
  }
</script>
