• 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-016.js ./demo/canvas-017.js ./demo/canvas-018.js ./demo/canvas-019.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-057.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/canvas-065.js ./demo/canvas-066.js ./demo/canvas-067.js ./demo/canvas-068.js ./demo/canvas-069.js ./demo/canvas-070.js ./demo/canvas-071.js ./demo/canvas-072.js ./demo/canvas-073.js ./demo/canvas-201.js ./demo/canvas-202.js ./demo/canvas-203.js ./demo/canvas-204.js ./demo/canvas-205.js ./demo/canvas-206.js ./demo/canvas-207.js ./demo/canvas-208.js ./demo/canvas-209.js ./demo/canvas-210.js ./demo/canvas-211.js ./demo/canvas-212.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/dom-019.js ./demo/dom-020.js ./demo/dom-021.js ./demo/filters-001.js ./demo/filters-002.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-029.js ./demo/filters-030.js ./demo/filters-031.js ./demo/filters-032.js ./demo/filters-033.js ./demo/filters-034.js ./demo/filters-035.js ./demo/filters-036.js ./demo/filters-037.js ./demo/filters-038.js ./demo/filters-039.js ./demo/filters-040.js ./demo/filters-041.js ./demo/filters-042.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/particles-017.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/temp-001.js ./demo/temp-shape-scale-investigation.js ./demo/tensorflow-001.js ./demo/tensorflow-002.js ./demo/utilities.js
  • §

    Demo Canvas 031

    Cell generation and processing order - kaleidoscope clock

  • §

    Run code

    import * as scrawl from '../source/scrawl.js';
    
    import { reportSpeed } from './utilities.js';
  • §

    This code can be factored away into its own module

    • Because: clocks are useful; most of this code can be thought of as clock boilerplate
    const buildClockface = function (canvas, namespace) {
    
        const name = (n) => `${namespace}-${n}`;
  • §

    The clock face will go into its own Cell

        const myFace = canvas.buildCell({
    
            name: name('face'),
    
            width: '100%',
            height: '100%',
    
            setRelativeDimensionsUsingBase: true,
        });
  • §

    The clock frame is a wheel, as is the center pin

        scrawl.makeWheel({
    
            name: name('frame'),
            group: name('face'),
    
            radius: '40%',
    
            start: ['center', 'center'],
            handle: ['center', 'center'],
    
            lineWidth: 6,
            strokeStyle: 'black',
            method: 'draw',
    
        }).clone({
    
            name: name('center-pin'),
    
            radius: '2%',
    
            lineWidth: 2,
            fillStyle: 'darkred',
            strokeStyle: 'gold',
            method: 'fillThenDraw',
    
            order: 1,
    
            shadowOffsetX: 1,
            shadowOffsetY: 1,
            shadowColor: 'black',
            shadowBlur: 3,
        });
  • §

    The hour, minute and second hands are all Line shapes

        scrawl.makeLine({
    
            name: name('hour-hand'),
            group: name('face'),
    
            startX: 'center',
            startY: 'center',
            endX: 'center',
            endY: '23%',
    
            handleY: '-15%',
    
            lineWidth: 10,
            lineCap: 'round',
            strokeStyle: 'darkblue',
            method: 'draw',
    
            shadowOffsetX: 3,
            shadowOffsetY: 3,
            shadowColor: 'black',
            shadowBlur: 3,
    
        }).clone({
    
            name: name('minute-hand'),
    
            endY: '15%',
            strokeStyle: 'blue',
            lineWidth: 6,
    
        }).clone({
    
            name: name('second-hand'),
    
            endY: '12%',
            lineWidth: 4,
            strokeStyle: 'red',
        });
  • §

    Function to make the clock tick

        const updateClockHands = function () {
    
            const hourHand = scrawl.findEntity(name('hour-hand')),
                minuteHand = scrawl.findEntity(name('minute-hand')),
                secondHand = scrawl.findEntity(name('second-hand'));
    
            const secondsSinceMidnight = () => {
    
                const now = new Date(),
                    then = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
    
                return (now.getTime() - then.getTime()) / 1000;
            };
    
            return function () {
    
                const time = secondsSinceMidnight(),
                    hour = ((time % 43200) / 12) * (360 / 3600),
                    minute = ((time % 3600)) * (360 / 3600),
                    second = ((time % 60)) * (360 / 60);
    
                hourHand.set({ roll: hour });
                minuteHand.set({ roll: minute });
                secondHand.set({ roll: second });
            }
    
        }();
  • §

    Once modularized, we can export a function to run the above code

    • When the function is invoked it builds the clock face Cell and entitys
    • It returns the cell, and the the clock tick function
        return {
    
            cell: myFace,
            update: updateClockHands
        }
    };
  • §

    Scene setup

    const canvas = scrawl.findCanvas('mycanvas');
    
    const namespace = canvas.name;
    const name = (n) => `${namespace}-${n}`;
  • §

    Building the background - this goes in a separate Cell

    canvas.buildCell({
    
        name: name('background'),
    
        width: '100%',
        height: '100%',
    
        setRelativeDimensionsUsingBase: true,
        shown: false,
    });
  • §

    We use a wheel segment as a stencil

    scrawl.makeWheel({
    
        name: name('stencil'),
        group: name('background'),
    
        order: 0,
    
        radius: '40%',
        startAngle: -30,
        endAngle: 30,
        includeCenter: true,
    
        start: ['center', 'center'],
        handle: ['center', 'center'],
    
        fillStyle: 'white',
        method: 'fill',
    });
  • §

    Use a color factory object to generate random colors within a restricted palette

    const myColorFactory = scrawl.makeColor({
    
        name: name('colors'),
    });
  • §

    Add some blocks to create the animated background

    for (let i = 0; i < 50; i++) {
    
        scrawl.makeBlock({
    
            name: name(`decoration-block-${i}`),
            group: name('background'),
    
            globalCompositeOperation: 'source-atop',
            globalAlpha: 0.3,
    
            order: 1,
    
            startX: `${10 + (Math.random() * 80)}%`,
            startY: `${10 + (Math.random() * 80)}%`,
    
            handleX: `${(Math.random() * 400) - 200}%`,
            handleY: `${(Math.random() * 400) - 200}%`,
    
            width: `${10 + (Math.random() * 15)}%`,
            height: `${2 + (Math.random() * 10)}%`,
            roll: Math.floor(Math.random() * 360),
    
            fillStyle: myColorFactory.get('random'),
    
            delta: {
                roll: ((Math.random() * 2) - 1) / 4,
            },
        });
    }
  • §

    We don’t display the background Cell. Instead we use it as the source for a set of Picture entitys

    scrawl.makePicture({
    
        name: name('segment-0'),
        group: canvas.get('baseName'),
    
        width: '100%',
        height: '100%',
    
        copyWidth: '100%',
        copyHeight: '100%',
    
        start: ['center', 'center'],
        handle: ['center', 'center'],
    
        asset: name('background'),
    
    }).clone({
    
        name: name('segment-1'),
        roll: 120,
    
    }).clone({
    
        name: name('segment-2'),
        roll: 240,
    
    }).clone({
    
        name: name('segment-3'),
        flipReverse: true,
    
    }).clone({
    
        name: name('segment-4'),
        roll: 120,
    
    }).clone({
    
        name: name('segment-5'),
        roll: 0,
    });
  • §

    Build the clock face

    const clock = buildClockface(canvas, `${namespace}-clock`);
  • §

    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

    scrawl.makeRender({
    
        name: name('animation'),
        target: canvas,
    
        commence: clock.update,
        afterShow: report,
    });
  • §

    Development and testing

    console.log(scrawl.library);