- Jump To … +
  ./demo/canvas-001.js ./demo/canvas-002.js ./demo/canvas-003.js ./demo/canvas-004.js ./demo/canvas-005.js ./demo/canvas-006.js ./demo/canvas-007.js ./demo/canvas-008.js ./demo/canvas-009.js ./demo/canvas-010.js ./demo/canvas-011.js ./demo/canvas-012.js ./demo/canvas-013.js ./demo/canvas-014.js ./demo/canvas-015.js ./demo/canvas-015a.js ./demo/canvas-016.js ./demo/canvas-017.js ./demo/canvas-018.js ./demo/canvas-019.js ./demo/canvas-019a.js ./demo/canvas-020.js ./demo/canvas-021.js ./demo/canvas-022.js ./demo/canvas-023.js ./demo/canvas-024.js ./demo/canvas-025.js ./demo/canvas-026.js ./demo/canvas-027.js ./demo/canvas-028.js ./demo/canvas-029.js ./demo/canvas-030.js ./demo/canvas-031.js ./demo/canvas-032.js ./demo/canvas-033.js ./demo/canvas-034.js ./demo/canvas-035.js ./demo/canvas-036.js ./demo/canvas-037.js ./demo/canvas-038.js ./demo/canvas-039.js ./demo/canvas-040.js ./demo/canvas-041.js ./demo/canvas-042.js ./demo/canvas-043.js ./demo/canvas-044.js ./demo/canvas-045.js ./demo/canvas-046.js ./demo/canvas-047.js ./demo/canvas-048.js ./demo/canvas-049.js ./demo/canvas-050.js ./demo/canvas-051.js ./demo/canvas-052.js ./demo/canvas-053.js ./demo/canvas-054.js ./demo/canvas-055.js ./demo/canvas-056.js ./demo/canvas-058.js ./demo/canvas-059.js ./demo/canvas-060.js ./demo/canvas-061.js ./demo/canvas-062.js ./demo/canvas-063.js ./demo/canvas-064.js ./demo/core-001.js ./demo/delaunator-001.js ./demo/delaunator-002.js ./demo/dom-001.js ./demo/dom-002.js ./demo/dom-003.js ./demo/dom-004.js ./demo/dom-005.js ./demo/dom-006.js ./demo/dom-007.js ./demo/dom-008.js ./demo/dom-009.js ./demo/dom-010.js ./demo/dom-011.js ./demo/dom-012.js ./demo/dom-013.js ./demo/dom-015.js ./demo/dom-016.js ./demo/dom-017.js ./demo/dom-018.js ./demo/filters-001.js ./demo/filters-002.js ./demo/filters-002a.js ./demo/filters-003.js ./demo/filters-004.js ./demo/filters-005.js ./demo/filters-006.js ./demo/filters-007.js ./demo/filters-008.js ./demo/filters-009.js ./demo/filters-010.js ./demo/filters-011.js ./demo/filters-012.js ./demo/filters-013.js ./demo/filters-014.js ./demo/filters-015.js ./demo/filters-016.js ./demo/filters-017.js ./demo/filters-018.js ./demo/filters-019.js ./demo/filters-020.js ./demo/filters-021.js ./demo/filters-022.js ./demo/filters-023.js ./demo/filters-024.js ./demo/filters-025.js ./demo/filters-026.js ./demo/filters-027.js ./demo/filters-028.js ./demo/filters-101.js ./demo/filters-102.js ./demo/filters-103.js ./demo/filters-104.js ./demo/filters-105.js ./demo/filters-501.js ./demo/filters-502.js ./demo/filters-503.js ./demo/filters-504.js ./demo/filters-505.js ./demo/mediapipe-001.js ./demo/mediapipe-002.js ./demo/mediapipe-003.js ./demo/modules-001.js ./demo/modules-002.js ./demo/modules-003.js ./demo/modules-004.js ./demo/modules-005.js ./demo/modules-006.js ./demo/packets-001.js ./demo/packets-002.js ./demo/particles-001.js ./demo/particles-002.js ./demo/particles-003.js ./demo/particles-004.js ./demo/particles-005.js ./demo/particles-006.js ./demo/particles-007.js ./demo/particles-008.js ./demo/particles-009.js ./demo/particles-010.js ./demo/particles-011.js ./demo/particles-012.js ./demo/particles-013.js ./demo/particles-014.js ./demo/particles-015.js ./demo/particles-016.js ./demo/rapier-001.js ./demo/snippets-001.js ./demo/snippets-002.js ./demo/snippets-003.js ./demo/snippets-004.js ./demo/snippets-005.js ./demo/snippets-006.js ./demo/tensorflow-001.js ./demo/tensorflow-002.js ./demo/utilities.js

- §

      /* eslint-disable */

- §

  # Demo Rapier 001

  Rapier physics engine - stacking boxes

- §

  Run code

      import * as scrawl from '../source/scrawl.js';

- §

  @ts-expect-error

      import rapier from "https://cdn.skypack.dev/@dimforge/rapier2d-compat";

      import { reportSpeed } from './utilities.js';

- §

  We are using a 600px x 600px canvas

  - which means we can assume 1 rapierUnit = 60px
  - remember that the y coordinates are positive-up from the bottom left corner
  - and rapier cube dimensions are measured as halfwidth, halfheight
  - also, rapier rotation is the opposite direction to Scrawl-canvas roll

      const unit = 60,
          halfUnit = unit / 2,
          thirdUnit = unit / 3,
          sixthUnit = unit / 6,
          rows = 10,
          cols = 10,
          height = 600;

- §

  #### Scene setup

      const artefacts = scrawl.library.artefact;

      const canvas = artefacts.mycanvas;

- §

  Keep the dynamic boxes in their own group (for drag-and-drop functionality later)

      const boxesGroup = scrawl.makeGroup({
          name: "boxes-group",
          host: canvas.base.name
      });

- §

  #### Scrawl-canvas entitys

  Build static boxes

      const ground = scrawl.makeBlock({
          name: "my-ground",
          dimensions: [600, 40],
          start: [300, 580],
          handle: ["center", "center"],
          fillStyle: "green",
          method: "fill"
      });

- §

  A color generator to make our dynamic boxes look pretty

      const colorMaker = scrawl.makeColor({
          name: "box-color-fill-generator",
          maximumColor: "orange",
          minimumColor: "brown"
      });

- §

  Build dynamic boxes

      for (let y = 0; y < rows; y++) {

          for (let x = 0; x < cols; x++) {

              scrawl.makeBlock({
                  name: `block-${y}-${x}`,
                  group: "boxes-group",
                  startX: halfUnit + x * unit,
                  startY: -sixthUnit + y * unit,
                  handle: ["center", "center"],
                  width: thirdUnit + Math.ceil(Math.random() * halfUnit),
                  height: thirdUnit + Math.ceil(Math.random() * halfUnit),
                  fillStyle: colorMaker.getRangeColor(Math.random()),
                  method: "fillThenDraw"
              });
          }
      }

- §

  ### Rapier rigid bodies

      const boxes = [],
          boxnames = [...boxesGroup.artefacts],
          rad = scrawl.library.radian;

- §

  Function to automate rigid body generation from Scrawl-canvas Block entitys

      /* eslint-disable-next-line */
      const createBodyFromBlock = function (world, block, density = 1, isStatic = false ) {

          const tempx = block.get("startX") / unit,
              tempy = (height - block.get("startY")) / unit,
              tempw = block.get("width") / unit,
              temph = block.get("height") / unit;

          let rbDesc, colDesc, rigidBody;

          const bodyType = isStatic
              ? rapier.RigidBodyType.Static
              : rapier.RigidBodyType.Dynamic;

          rbDesc = new rapier.RigidBodyDesc(bodyType);
          rbDesc.setTranslation(tempx, tempy);
          rigidBody = world.createRigidBody(rbDesc);
          colDesc = rapier.ColliderDesc.cuboid(tempw / 2, temph / 2);
          world.createCollider(colDesc, rigidBody.handle);

          return rigidBody;
      };

- §

  Function to update Scrawl-canvas entitys with Rapier rigid body position/rotation data

      const updatePosition = function (box) {

          const { entity, body } = box;
          const { x, y } = body.translation();

          const r = -body.rotation() / rad;

          let sx = x * unit,
              sy = y * unit;

          sy = height - sy;

          entity.set({
              startX: sx,
              startY: sy,
              roll: r
          });
      };

- §

  Flag to run/halt the physics simulation

      let isRunning = false;

- §

  Initialize Rapier (involves web assembly, thus asynchronous)

      rapier.init()
      .then(() => {

- §

  Create the world, with added gravity

          const gravity = new rapier.Vector2(0.0, -9.8),
              world = new rapier.World(gravity);

- §

  Create rigid body for static ground entity

          createBodyFromBlock(world, ground, null, true);

- §

  Create dynamic rigid-bodies for the other boxes

          boxnames.forEach((name) => {

              const ent = artefacts[name];

              if (ent) {

                  boxes.push({
                      entity: ent,
                      body: createBodyFromBlock(world, ent, 2)
                  });
              }
          });

- §

  Simulation loop

          const physicsLoop = () => {

              if (isRunning) {

                  world.step();
                  boxes.forEach(b => updatePosition(b));
              }
          };

- §

  Add the simulation loop to our Scrawl-canvas animation object

          animation.set({
              commence: physicsLoop,
          });
      })
      .catch(e => console.log(e));

- §

  #### Scene animation

  Function to display frames-per-second data, and other information relevant to the demo

      const report = reportSpeed('#reportmessage');

- §

  Create the Display cycle animation

      const animation = scrawl.makeRender({
          name: "demo-animation",
          target: canvas,
          afterShow: report
      });

- §

  #### User interaction

      const runButton = document.querySelector("#run"),
          haltButton = document.querySelector("#halt");

      scrawl.addNativeListener("click", () => {

          runButton.setAttribute("disabled", "disabled");
          haltButton.removeAttribute("disabled");
          isRunning = true;

      }, runButton);

      scrawl.addNativeListener("click", () => {

          runButton.removeAttribute("disabled");
          haltButton.setAttribute("disabled", "disabled");
          isRunning = false;

      }, haltButton);

- §

  #### Development and testing

      console.log(scrawl.library);