• 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-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/js/mediapipe/tasks-vision/vision-bundle.js ./demo/js/mediapipe/tasks-vision/wasm/vision_wasm_internal.js ./demo/js/mediapipe/tasks-vision/wasm/vision_wasm_nosimd_internal.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/modules/canvas-minimap.js ./demo/modules/canvas-scene-editor.js ./demo/modules/demo-m006-c1.js ./demo/modules/demo-m006-c2.js ./demo/modules/demo-m006-c3.js ./demo/modules/demo-m006-c4.js ./demo/modules/demo-m006-utils.js ./demo/modules/dom-entity-editor.js ./demo/modules/entity-copy-paste.js ./demo/modules/entity-manipulation-gui.js ./demo/modules/entity-navigation.js ./demo/modules/entity-ring-builder.js ./demo/modules/london-crime-lines.js ./demo/modules/london-crime-stacked-bars.js ./demo/modules/lottie-loader.js ./demo/modules/simple-chart-frame.js ./demo/modules/simple-graph-lines.js ./demo/modules/simple-graph-stacked-bars.js ./demo/modules/wikipedia-views-spiral-chart.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/snippets/animated-highlight-gradient-text-snippet.js ./demo/snippets/animated-hover-gradient-snippet.js ./demo/snippets/animated-word-gradient-snippet.js ./demo/snippets/before-after-slider-infographic.js ./demo/snippets/bubbles-text-snippet.js ./demo/snippets/green-box-snippet.js ./demo/snippets/jazzy-button-snippet.js ./demo/snippets/page-performance-snippet-test.js ./demo/snippets/page-performance-snippet.js ./demo/snippets/pan-image-snippet.js ./demo/snippets/placeholder-effect-snippet.js ./demo/snippets/ripple-effect-snippet.js ./demo/snippets/risograph-text-gradient-snippet.js ./demo/snippets/spotlight-text-snippet-test.js ./demo/snippets/spotlight-text-snippet.js ./demo/snippets/swirling-stripes-text-snippet.js ./demo/snippets/word-highlighter-snippet.js ./demo/snippets/worley-text-gradient-snippet.js ./demo/temp-001.js ./demo/temp-shape-scale-investigation.js ./demo/tensorflow-001.js ./demo/tensorflow-002.js ./demo/utilities.js
  • §

    Demo Snippets 001

    Scrawl-canvas DOM element snippets

    Related files:

    • DOM element snippets - main module
    • Spotlight text snippet
    • Jazzy button snippet
    • Page performance snippet

    Snippet definitions

    Snippet definitions are functions that take a DOM element and manipulate it to supply it with additional functionality, including the ability to add Scrawl-canvas displays and animations to the DOM element

    Example of how a Javascript module can import and use a snippet definition:

    import scrawl from '../relative/or/absolute/path/to/scrawl.js';
    import { mySnippet } from './relative/or/absolute/path/to/snippet/definition/file.js';
    
    let myElements = document.querySelectorAll('.some-class');
    myElements.forEach(el => mySnippet(el));
    

    Snippet definition functions can be written in any way the developer sees fit - a developer could write a snippet definition so that it:

    • can accept additional data to help further personalize how the snippet gets built
    • visits remote APIs to gather additional data as part of the snippet build
    • holds local state for the snippet
    • supplies a return object, class instance or function containing handles to the objects built by the definition, or functions for manipulating the Scrawl-canvas assets, artefacts, styles, animation(s) and/or canvas built by the definition (a ‘mini-API’ for each snippet)
    • etc…

    At a minimum, a snippet definition function will need to take a DOM element (or a pointer to it) as an argument. Note that Scrawl-canvas will manipulate the element in the following ways to make it work as a snippet:

    • the element’s CSS ‘position’ value, if set to ‘static’ (the default value), will change to either ‘relative’ or ‘absolute’ - this is required to get any added canvas to stick to its element in the final display
    • it will also be given a unique Scrawl-canvas identifier in a new data-scrawl-name attribute on the element
    • the new <canvas> element will be added to the element as its first child; the canvas will be absolutely positioned within the element
    • Scrawl-canvas will also add a hidden text-hold <div> element immediately after the canvas element - this is where Scrawl-canvas keeps dynamic text (for assistive technology)
    • by default, the canvas is built so that it displays beneath the element, using a lower z-index CSS property on the canvas element (compared to the host’s z-index value)
    • the new canvas’s dimensions will include the element’s padding and border as well as its content

    For the sake of fellow developers, each snippet definition function should come with some documentation to explain:

    • the purpose and usage of the snippet that the definition function will deliver/render
    • any effects (beyond those explained above) that snippetization will have on the DOM element and any child elements it may contain
    • what input the function requires, and in what format and argument order
    • what - if anything - the definition function will return

    Each of the following snippet definition functions could live in its own file; we can also bundle snippets together so that related snippets can be imported into another Javascript module using a single import statement in that file

  • §

    ‘Spotlight text’ snippet

    Purpose: adds a spotlight effect to an element. When the user hovers the mouse over the element, a ‘spotlight’ gradient will track the mouse’s movements.

    Function input:

    • the DOM element, or a handle to it, as the first argument.
    • an optional key:value Object as the second argument

    Function output: a Javascript object will be returned, containing the following attributes

    {
        element     // the Scrawl-canvas wrapper for the DOM element supplied to the function
        canvas      // the Scrawl-canvas wrapper for the snippet's canvas
        animation   // the Scrawl-canvas animation object
        demolish    // remove the snippet from the Scrawl-canvas library
    }
    
    Usage example:
    import spotlightText from './relative/or/absolute/path/to/this/file.js';
    
    let myElements = document.querySelectorAll('.some-class');
    
    myElements.forEach(el => spotlightText(scrawl, el));
    

    Effects on the element:

    • no additional effects on the DOM element
    • setting any background fill on the DOM element will hide the snippet canvas, unless it is deliberately brought forward
    export default function (scrawl, el, args = {}) {
  • §

    The snippet will accept an optional key:value Object as the second argument

    • spotlightColor - default: white
    • backgroundColor - default: lightgray
        const spotlightColor = args.spotlightColor || 'white',
            backgroundColor = args.backgroundColor || 'lightgray';
  • §

    Apply the snippet to the DOM element

        const snippet = scrawl.makeSnippet({
  • §

    (required) The DOM element we are about to snippetize

            domElement: el,
  • §

    (optional) An array of animation hook functions with the following attributes

    • commence - for an preparatory work required before the display cycle kicks off
    • afterClear - runs between the ‘clear’ and ‘compile’ stages of the display cycle
    • afterCompile - runs between the ‘compile’ and ‘show’ stages of the display cycle
    • afterShow - for any cleanup work required after the display cycle completes
    • error - a function to run when an error in the display cycle occurs

    For this snippet, we’ll define and add an animation hook function after the animation object has been created

            animationHooks: {},
  • §

    (optional) Options we can supply for the IntersectionObserver. Defaults are usually good enough; changing the ‘threshold’ value is probably the most useful option to play with

            observerSpecs: {},
  • §

    (optional - default: true) Scrawl-canvas snippets don’t have to include a canvas!

            includeCanvas: true,
  • §

    (optional, and only useful if we are including a canvas) - canvas-specific options. The most useful attribute is (probably) fit, whose value can be one of: contain, cover, fill, or none (the default value)

            canvasSpecs: {},
        });
  • §

    NOTE: makeSnippet() defines its own afterClear animation hook

    • the functionality is to keep the canvas properly aligned and sized with its DOM element
    • overwriting this hook here will lose that functionality!
    • instead, use the commence animation hook for all display cycle preparations

    Once the snippet is built, we can supply values to our previously defined variables

        if (snippet) {
  • §

    Set some convenience variables

            const canvas = snippet.canvas,
                animation = snippet.animation,
                wrapper = snippet.element,
                name = wrapper.name;
    
            canvas.setAsCurrentCanvas();
  • §

    Define the gradient

            const spotlightGradient = scrawl.makeRadialGradient({
    
                name: `${name}-gradient`,
                startX: '50%',
                startY: '50%',
                endX: '50%',
                endY: '50%',
                endRadius: '20%',
            })
            .updateColor(0, spotlightColor)
            .updateColor(999, backgroundColor);
  • §

    This animation hook uses the variables and gradient we defined above

            animation.commence = function () {
    
                let active = false;
    
                return function () {
    
                    if (canvas.here.active !== active) {
    
                        active = canvas.here.active;
  • §

    The block entity swaps between the gradient and a color fill, dependent on user interaction

                        block.set({
                            lockTo: (active) ? 'mouse' : 'start',
                            fillStyle: (active) ? spotlightGradient : backgroundColor,
                        });
                    }
                };
            }();
  • §

    Define the block which will (sometimes) display our spotlingt gradient

            const block = scrawl.makeBlock({
    
                name: `${name}-spotlight`,
                width: '200%',
                height: '200%',
    
                startX: "50%",
                startY: "50%",
                handleX: "50%",
                handleY: "50%",
    
                fillStyle: backgroundColor,
                lockFillStyleToEntity: true,
    
                method: 'fill',
            });
        }
  • §

    Return the snippet, so coders can access the snippet’s parts - in case they need to tweak the output to meet the web page’s specific requirements

        return snippet;
    }