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

    Test various clipping strategies

  • §

    Run code

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

    Scene setup

    const {canvas1, canvas2, canvas3} = scrawl.library.canvas;

    const canvas1 = scrawl.findCanvas('canvas1'),
        canvas2 = scrawl.findCanvas('canvas2'),
        canvas3 = scrawl.findCanvas('canvas3');
  • §

    Import image from DOM

    scrawl.importDomImage('.canal');
  • §

    Canvas 1

    Applying more than one clipped region to a scene, using Groups to separate them

    const ns1 = `canvas1`;
    const name1 = (name) => `${ns1}-${name}`;
  • §

    The scene will be made up of two clipped images, both draggable around the canvas

    scrawl.makeGroup({
    
        name: name1('cog-clip'),
        host: canvas1.get('baseName'),
    
    }).clone({
    
        name: name1('star-clip'),
        host: canvas1.get('baseName'),
    });
  • §

    Clipping region entitys

    scrawl.makeCog({
    
        name: name1('cog-clipper'),
        group: name1('cog-clip'),
    
        start: ['25%', 'center'],
        handle: ['center', 'center'],
    
        outerRadius: 140,
        innerRadius: 120,
        outerControlsDistance: 20,
        innerControlsDistance: 16,
        points: 24,
    
        method: 'clip',
    
        delta: {
            roll: 0.4,
        },
  • §

    The clipping region entity MUST be stamped on the canvas before the entitys that will be clipped by it

        bringToFrontOnDrag: false,
  • §

    Add outlines to our clipped regions

    }).clone({
    
        name: name1('cog-outline'),
        order: 2,
        pivot: name1('cog-clipper'),
        lockTo: 'pivot',
    
        strokeStyle: 'coral',
        lineWidth: 6,
        method: 'draw',
    });
    
    scrawl.makeStar({
    
        name: name1('star-clipper'),
        group: name1('star-clip'),
    
        start: ['75%', 'center'],
        handle: ['center', 'center'],
    
        radius1: 80,
        radius2: 140,
        points: 6,
    
        delta: {
            roll: -0.7,
        },
    
        method: 'clip',
        bringToFrontOnDrag: false,
    
    }).clone({
    
        name: name1('star-outline'),
        order: 2,
        pivot: name1('star-clipper'),
        lockTo: 'pivot',
    
        strokeStyle: 'coral',
        lineWidth: 6,
        method: 'draw',
    });
  • §

    Picture entitys - we pivot these to our clipping region entitys to make the clipped display the same, wherever it is moved to on the canvas

    scrawl.makePicture({
    
        name: name1('cog-image'),
        group: name1('cog-clip'),
    
        asset: 'factory',
    
        dimensions: [400, 400],
        copyDimensions: [400, 400],
    
        pivot: name1('cog-clipper'),
        addPivotRotation: true,
        lockTo: 'pivot',
        handle: ['center', 'center'],
    
    }).clone({
    
        name: name1('star-image'),
        group: name1('star-clip'),
    
        pivot: name1('star-clipper'),
        copyStartX: 100,
    });
  • §

    We’re not interested with associating the canvas 1 drag group with the canvas’s base cell - the entitys in this group will already be assigned to the clip groups, thus will already be included in the canvas’s Display cycle

    scrawl.makeGroup({
    
        name: name1('drag-group'),
    
    }).addArtefacts(name1('cog-clipper'), name1('star-clipper'));
    
    scrawl.makeDragZone({
    
        zone: canvas1,
        collisionGroup: name1('drag-group'),
        endOn: ['up', 'leave'],
        preventTouchDefaultWhenDragging: true,
    });
  • §

    Canvas 2:

    Generate and use Picture entitys from clipped scenes

    const ns2 = `canvas2`;
    const name2 = (name) => `${ns2}-${name}`;
  • §

    We’ll be creating some temporary cells etc which we need to clear out after completing work

    const prepNamespace = `prep-for-canvas2`;
    const prepName = (name) => `${prepNamespace}-${name}`;
  • §

    We will generate Image assets from cells created specifically for this one task

    canvas2.buildCell({
    
        name: prepName('cog-clip'),
        dimensions: [280, 280],
        shown: false,
    });
    
    canvas2.buildCell({
    
        name: prepName('star-clip'),
        dimensions: [280, 280],
        shown: false,
    });
  • §

    Clipped entitys - this code is much the same as for canvas1, without dragging and delta animation

    scrawl.makeCog({
    
        name: prepName('cog-clipper'),
        group: prepName('cog-clip'),
    
        outerRadius: 140,
        innerRadius: 120,
        outerControlsDistance: 20,
        innerControlsDistance: 16,
        points: 24,
    
        method: 'clip',
    
    }).clone({
    
        name: prepName('cog-outline'),
        order: 2,
        pivot: prepName('cog-clipper'),
        lockTo: 'pivot',
    
        strokeStyle: 'coral',
        lineWidth: 6,
        method: 'draw',
    });
    
    scrawl.makeStar({
    
        name: prepName('star-clipper'),
        group: prepName('star-clip'),
    
        radius1: 140,
        radius2: 80,
        points: 6,
    
        method: 'clip',
    
    }).clone({
    
        name: prepName('star-outline'),
        order: 2,
        pivot: prepName('star-clipper'),
        lockTo: 'pivot',
    
        strokeStyle: 'coral',
        lineWidth: 6,
        method: 'draw',
    });
    
    scrawl.makePicture({
    
        name: prepName('cog-image'),
        group: prepName('cog-clip'),
    
        asset: 'factory',
    
        dimensions: [280, 280],
        copyDimensions: [280, 280],
    
        copyStart: [70, 60],
    
        pivot: prepName('cog-clipper'),
        lockTo: 'pivot',
    
    }).clone({
    
        name: prepName('star-image'),
        group: prepName('star-clip'),
    
        pivot: prepName('star-clipper'),
        copyStart: [170, 20],
    });
  • §

    We will get Scrawl-canvas to capture the image output of each Cell as part of the first Display cycle. Then we can create regular Picture entitys from those images, and get rid of the original cells and entitys.

    scrawl.createImageFromCell(prepName('cog-clip'), name2('cog-image'),);
    scrawl.createImageFromCell(prepName('star-clip'), name2('star-image'));
  • §

    We create our Picture entitys from Cell output in a post-initialization step. Note that this function may run more than once as page loading is asynchronous and unpredictable

    const canvasTwoPostInitialization = function () {
    
        console.log('running canvasTwoPostInitialization()');
    
        const drag = scrawl.makeGroup({
            name: name2('drag-group'),
        });
    
        scrawl.makeDragZone({
            zone: canvas2,
            collisionGroup: name2('drag-group'),
            endOn: ['up', 'leave'],
            preventTouchDefaultWhenDragging: true,
        });
    
        scrawl.makePicture({
    
            name: name2('cog'),
            group: canvas2.get('baseGroup'),
    
            asset: name2('cog-image'),
    
            start: ['25%', 'center'],
            handle: ['center', 'center'],
    
            dimensions: [280, 280],
            copyDimensions: ['100%', '100%'],
    
            delta: {
                roll: 0.4,
            },
    
            method: 'fill',
        });
    
        drag.addArtefacts(name2('cog'));
    
        scrawl.makePicture({
    
            name: name2('star'),
            group: canvas2.get('baseGroup'),
    
            asset: name2('star-image'),
    
            start: ['75%', 'center'],
            handle: ['center', 'center'],
    
            dimensions: [280, 280],
            copyDimensions: ['100%', '100%'],
    
            delta: {
                roll: -0.7,
            },
    
            method: 'fill',
        });
    
        drag.addArtefacts(name2('star'));
  • §

    The cog and star Cells - and their Groups, entitys, etc - have served their purpose

    • Time to get rid of them
        setTimeout(() => scrawl.purge(prepNamespace), 0);
    };
  • §

    Canvas 3:

    Emulate clipping to a Label entity using a composite scene rendered in its own cell

    const ns3 = `canvas3`;
    const name3 = (name) => `${ns3}-${name}`;
  • §

    We will generate Image assets from cells created specifically for this one task

    const c3Cell = canvas3.buildCell({
        name: name3('serif-cell'),
        dimensions: ['100%', '100%'],
    });
    
    const c3Phrase = scrawl.makeLabel({
    
        name: name3('serif-text-hello'),
        group: name3('serif-cell'),
    
        text: 'HELLO!',
        fontString: 'bold 120px serif',
    });
    
    
    const canvasThreePostInitialization = function () {
  • §

    Font loading is async - only run this code if the font has been loaded and measured

    • We always measure the font at a size of 100px, whatever value we set the entity’s font size to
        if (scrawl.library.fontfamilymetadatanames.includes('100px serif')) {
    
            console.log('running canvasThreePostInitialization()');
  • §

    create our drag group and dragzone

            const drag = scrawl.makeGroup({
                name: name3('drag-group'),
            });
    
            scrawl.makeDragZone({
                zone: canvas3,
                collisionGroup: name3('drag-group'),
                endOn: ['up', 'leave'],
                preventTouchDefaultWhenDragging: true,
            });
  • §

    We need to retrieve the Label entity’s dimensions - which are hard to guess before it’s created - and update its surrounding environment to fit.

            const [width, height] = c3Phrase.get('dimensions');
  • §

    We can use the label entity as a stencil by applying a Picture entity over it with a GCO = ‘source-atop’

            scrawl.makePicture({
    
                name: name3('serif-image'),
                group: name3('serif-cell'),
    
                asset: 'factory',
    
                width,
                height,
                copyDimensions: [width, height],
                copyStart: [50, 50],
    
                method: 'fill',
                order: 1,
                globalCompositeOperation: 'source-atop',
            });
  • §

    We can also add an outline, if we want

            c3Phrase.clone({
    
                name: name3('serif-outline'),
                order: 2,
                globalCompositeOperation: 'source-over',
    
                method: 'draw',
                lineWidth: 3,
                strokeStyle: 'coral',
            });
  • §

    We cannot directly drag-and-drop a Cell, but we can create a Block entity and pivot the Cell to it, then drag-and-drop the Block

            scrawl.makeBlock({
                name: name3('serif-block'),
                group: canvas3.get('baseGroup'),
                width,
                height,
                start: ['center', 'center'],
                handle: ['center', 'center'],
                delta: {
                    roll: 0.5,
                },
                method: 'none',
            })
  • §

    Update our cell

            c3Cell.set({
                width,
                height,
                handle: ['center', 'center'],
                pivot: name3('serif-block'),
                addPivotRotation: true,
                lockTo: 'pivot',
            });
    
            drag.addArtefacts(name3('serif-block'));
  • §

    Switch off this check

    • We could do this using the render object’s set function - .set({afterShow: () => {}})
    • But render objects also have an updateHook function, which takes two args: the hook name, and the new function
    • If we don’t supply a new function, the existing hook function is just removed
            canvas3_animation.updateHook('afterShow');
        }
        else console.log('FAILED TO RUN canvasThreePostInitialization()');
    };
  • §

    Scene animation

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

    const report = reportSpeed('#reportmessage');
  • §

    Canvas 1 animation

    scrawl.makeRender({
        name: name1('animation'),
        target: canvas1,
    });
  • §

    Canvas 2 animation

    scrawl.makeRender({
    
        name: name2('animation'),
        target: canvas2,
        afterCreated: canvasTwoPostInitialization,
    });
  • §

    Canvas 3 animation

    const canvas3_animation = scrawl.makeRender({
    
        name: name3('animation'),
        target: canvas3,
        afterShow: canvasThreePostInitialization,
    });
  • §

    Speed report animation

    scrawl.makeRender({
    
        name: 'demo-speed',
        noTarget: true,
        afterShow: report,
    });
  • §

    Development and testing

    console.log(scrawl.library);