• 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/component-001.js ./demo/component-002.js ./demo/component-003.js ./demo/component-004.js ./demo/component-005.js ./demo/component-006.js ./demo/component-007.js ./demo/core-001.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-014a.js ./demo/dom-014b.js ./demo/dom-014c.js ./demo/dom-015.js ./demo/dom-016.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-501.js ./demo/filters-502.js ./demo/filters-503.js ./demo/filters-504.js ./demo/filters-505.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/temp-001.js ./demo/temp-inkscapeSvgFilters.js
  • ¶

    Demo Canvas 019

    Gradient and Color factories - transparency

  • ¶

    Run code

    import scrawl from '../source/scrawl.js';
  • ¶

    Scene setup

    const canvases = scrawl.library.canvas,
        entitys = scrawl.library.entity,
        c1 = canvases['canvas-1'],
        c2 = canvases['canvas-2'],
        c3 = canvases['canvas-3'],
        c4 = canvases['canvas-4'];
  • ¶

    Import the images we defined in the DOM (in <img> elements)

    scrawl.importDomImage('.places');
  • ¶

    For this scene, we’ll build a data structure which we can iterate over, to build the entitys, assets and gradients required by the scene

    const data = [
        {
            canvas: c1,
            image: 'hackney',
            transparency: 'transparent',
        },
        {
            canvas: c2,
            image: 'heathrow',
            transparency: 'rgba(0,0,0,0)',
        },
        {
            canvas: c3,
            image: 'kingston',
            transparency: '#00000000',
        },
        {
            canvas: c4,
            image: 'burglary',
            transparency: '#0000',
        },
    ];
  • ¶

    This array will hold a set of functions which we will invoke in turn at the start of each Display cycle

    const checkFunctions = [];
  • ¶

    The blur filter is temporary - we use it once on each image to generate a blurred version of that image

    • We do it this way because the blur filter is computationally very expensive - capturing a blurred version of the image is a lot better for end user power consumption
    scrawl.makeFilter({
        name: 'blur',
        method: 'blur',
        radius: 20,
        passes: 2,
    });
  • ¶

    Iterate through our data array to create Scrawl-canvas objects

    data.forEach(scene => {
  • ¶

    The original picture, with the blur filter applied to it

    • We will remove the filter in a later step
        let entity = scrawl.makePicture({
    
            name: `${scene.image}-original`,
            group: `${scene.canvas.base.name}`,
    
            asset: `${scene.image}`,
    
            dimensions: ['100%', '100%'],
            copyDimensions: ['100%', '100%'],
    
            filters: ['blur'],
            method: 'fill',
        });
  • ¶

    A one-off instruction to tell Scrawl-canvas to create an image asset from our Picture entity the next time it performs a Display cycle

        scrawl.createImageFromEntity(entity, true);
  • ¶

    The purpose of this demo is to test the various ways we can define ‘transparency’ in Scrawl-canvas Color objects and Gradients - tests a set of Color factory bugs uncovered and fixed in v8.3.2

        scrawl.makeRadialGradient({
    
            name: `${scene.image}-gradient`,
            start: ['50%', '50%'],
            end: ['50%', '50%'],
            startRadius: '5%',
            endRadius: '20%',
        })
        .updateColor(0, `${scene.transparency}`)
        .updateColor(999, 'black');
  • ¶

    Apply the gradient to the scene via a Block entity

        const filterBlock = scrawl.makeBlock({
    
            name: `${scene.image}-block`,
            group: `${scene.canvas.base.name}`,
    
            start: ['center', 'center'],
            handle: ['center', 'center'],
            dimensions: ['200%', '200%'],
    
            fillStyle: `${scene.image}-gradient`,
            lockFillStyleToEntity: true,
        });
  • ¶

    Check whether the mouse cursor is hovering over this canvas, and update the filter Block entity’s positioning accordingly

        const f = () => {
    
            const here = scene.canvas.here,
                block = filterBlock;
    
            return function () {
    
                block.set({
                    lockTo: (here.active) ? 'mouse' : 'start',
                });
            }
        };
        checkFunctions.push(f());
    });
  • ¶

    This function will run once, at the end of the first Display cycle

    const postInitialization = () => {
    
        data.forEach(scene => {
    
            let original = entitys[`${scene.image}-original`];
  • ¶

    Update our original Picture entity, in particular to remove the blur filter and set up its composition in the scene

            original.set({
                filters: [],
                order: 2,
                globalCompositeOperation: 'destination-over',
            });
  • ¶

    Create a second Picture entity using the blurred image asset Scrawl-canvas created for us during the first iteration of the Display cycle.

    • Note that we’ve asked Scrawl-canvas to create an <img> element (outside of the DOM) from our original Picture’s blurred output. Element creation takes time (it’s an asynchronous action), which means that our new Picture entity won’t show up for up to a second after the demo starts running.
            original.clone({
                name: `${scene.image}-blurred`,
                asset: `${scene.image}-original-image`,
                order: 1,
                globalCompositeOperation: 'source-atop',
            });
        });
    }
  • ¶

    Scene animation

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

    let report = function () {
    
        let testTicker = Date.now(),
            testTime, testNow, dragging,
            testMessage = document.querySelector('#reportmessage');
    
        return function () {
    
            testNow = Date.now();
  • ¶

    Because we are using the same render object to animate all four canvases, this report function gets run four times for each Display cycle (once each time each canvas is rendered). The fix is to choke the functionality so it actions only after a given number of milliseconds since it was last run - typically 2 milliseconds is enough to ensure the action only runs once per cycle.

            if (testNow - testTicker > 2) {
    
                testTime = testNow - testTicker;
                testTicker = testNow;
    
                testMessage.textContent = `Screen refresh: ${Math.ceil(testTime)}ms; fps: ${Math.floor(1000 / testTime)}`;
            }
        };
    }();
  • ¶

    Create the Display cycle animation

    scrawl.makeRender({
    
        name: 'demo-animation',
        target: [c1, c2, c3, c4],
    
        afterCreated: postInitialization,
        commence: () => checkFunctions.forEach(f => f()),
        afterShow: report,
    });
  • ¶

    Development and testing

    console.log(scrawl.library);