﻿<!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;
    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>
<canvas id=sk_webfont width=500 height=500
        title='This shows loading of a custom font (e.g. WebFont)'></canvas>

<h2> RT Shader </h2>
<canvas id=rtshader 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>

<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 webfontJSON = null;
  var fullBounds = {fLeft: 0, fTop: 0, fRight: 500, fBottom: 500};

  var robotoData = null;
  var notoserifData = null;

  var bonesImageData = null;
  var flightAnimGif = null;
  CanvasKitInit({
    locateFile: (file) => '/node_modules/canvaskit/bin/'+file,
  }).ready().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,
    });
    SkottieExample(CanvasKit, 'sk_webfont', webfontJSON, fullBounds, {
      'Roboto-Regular': robotoData,
    });

    ParticlesAPI1(CanvasKit);

    ParagraphAPI1(CanvasKit, robotoData);

    RTShaderAPI1(CanvasKit);
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/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('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/skottie_sample_multiframe.json').then((resp) => {
    resp.text().then((str) => {
      multiFrameJSON = str;
      SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, {
        'image_0.png': flightAnimGif,
      });
    });
  });

  fetch('https://storage.googleapis.com/skia-cdn/misc/flightAnim.gif').then((resp) => {
    resp.arrayBuffer().then((buffer) => {
      flightAnimGif = buffer;
      SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, {
        'image_0.png': flightAnimGif,
      });
    });
  });

  fetch('./Roboto-Regular.woff').then((resp) => {
    resp.arrayBuffer().then((buffer) => {
      robotoData = buffer;
      SkottieExample(CanvasKit, 'sk_webfont', webfontJSON, fullBounds, {
        'Roboto-Regular': robotoData,
      });
      ParagraphAPI1(CanvasKit, robotoData);
    });
  });

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

  function RTShaderAPI1(CanvasKit) {
    if (!CanvasKit) {
      return;
    }
    const prog = `

  uniform half4 gColor;

  void main(float x, float y, inout half4 color) {
      color = half4(half(x)*(1.0/255), half(y)*(1.0/255), gColor.b, 1);
  }
`;
    const surface = CanvasKit.MakeCanvasSurface('rtshader');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const canvas = surface.getCanvas();

    const effect = CanvasKit._SkRuntimeEffect.Make(prog);
    const rot = CanvasKit.SkMatrix.rotated(90, 128, 128);
    const shader = effect.makeShader([1, 0, 0, 1], true, rot);

    const paint = new CanvasKit.SkPaint();
    paint.setShader(shader);
    canvas.drawRect(CanvasKit.LTRBRect(0, 0, 256, 256), paint);

    surface.flush();
    shader.delete();
    paint.delete();
    effect.delete();
  }
</script>
