• 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-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/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/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-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/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/temp-000.js ./demo/temp-001.js ./demo/temp-001a.js ./demo/temp-002.js ./demo/temp-003.js ./demo/temp-004.js ./demo/temp-005.js ./demo/temp-006.js ./demo/temp-007.js ./demo/temp-008.js ./demo/temp-009.js ./demo/temp-010.js ./demo/temp-011.js ./demo/temp-012.js ./demo/temp-013.js ./demo/temp-014.js ./demo/temp-015.js ./demo/temp-016.js ./demo/temp-017.js ./demo/temp-018.js ./demo/temp-018a.js ./demo/temp-019.js ./demo/temp-020.js ./demo/temp-021.js ./demo/temp-022.js ./demo/temp-023.js ./demo/temp-024.js ./demo/temp-025.js ./demo/temp-026.js ./demo/temp-027.js ./demo/temp-028.js ./demo/temp-029.js ./demo/temp-030.js ./demo/temp-031.js ./demo/temp-032.js ./demo/temp-033.js ./demo/temp-034.js ./demo/temp-035.js ./demo/temp-036.js ./demo/temp-037.js ./demo/temp-100.js ./demo/temp-101.js ./demo/temp-102.js ./demo/temp-103.js ./demo/temp-104.js ./demo/temp-200.js ./demo/temp-201.js ./demo/temp-301.js ./demo/temp-inkscapeSvgFilters.js ./demo/temp-lottie.js ./demo/tensorflow-001.js ./demo/tensorflow-002.js ./demo/utilities.js
  • §

    Demo Filters 026

    Filter parameters: Swirl filter

  • §

    Run code

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

    Scene setup

    const canvas = scrawl.library.canvas.mycanvas;
    
    scrawl.importDomImage('.flowers');
  • §
    • TODO: concurrency - want to be able to process more than one swirl in the same filter. When concurrency flag is true, then each pixels value, when the pixel is affected by more than one swirl, needs to pro-rata the effects of those swirls; when concurrency is false, need to process the entire image for each swirl in turn.
    • TODO: this filter is too slow - we need to cache the calculations as a lookup table to speed things up.
    const swirl = scrawl.makeFilter({
    
        name: 'swirl',
        method: 'swirl',
        startX: '50%',
        startY: 200,
        innerRadius: 0,
        outerRadius: '30%',
        angle: 90,
        staticSwirls: [
            ['20%', '20%', 0, '10%', 270, 'easeOutInSine'],
            ['20%', '80%', 0, '10%', -270, 'easeOutInSine'],
            ['80%', '80%', 0, '10%', -270, 'easeOutInSine'],
            ['80%', '20%', 0, '10%', 270, 'easeOutInSine']
        ]
    });
  • §

    Test the ability to load a user-created easing algorithm into the gradient

    const bespokeEasings = {
    
        'user-steps': (val) => {
    
            if (val < 0.2) return 0.1;
            if (val < 0.4) return 0.3;
            if (val < 0.6) return 0.7;
            if (val < 0.8) return 0.5;
            return 0.9;
        },
        'user-zigzag': (val) => {
    
            if (val < 0.3) return val * 3;
            else if (val < 0.7) return 0.9 - ((val - 0.3) * 2);
            else return 0.1 + ((val - 0.7) * 3);
        },
    };
  • §

    Create the target entity

    const piccy = scrawl.makePicture({
    
        asset: 'iris',
    
        width: '100%',
        height: '100%',
    
        copyWidth: '100%',
        copyHeight: '100%',
    
        method: 'fill',
    
        filters: ['swirl'],
    });
  • §

    Scene animation

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

    const report = reportSpeed('#reportmessage', function () {
  • §

    @ts-expect-error

        return `    Start - x: ${swirl.startX}; y: ${swirl.startY}\n    Radius - outer: ${swirl.outerRadius}; inner: ${swirl.innerRadius}\n    Angle: ${angle.value}\n    Opacity: ${opacity.value}`;
    });
  • §

    Create the Display cycle animation

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

    User interaction

    Setup form observer functionality

    scrawl.observeAndUpdate({
    
        event: ['input', 'change'],
        origin: '.controlItem',
    
        target: swirl,
    
        useNativeListener: true,
        preventDefault: true,
    
        updates: {
    
            opacity: ['opacity', 'float'],
            start_xPercent: ['startX', '%'],
            start_yPercent: ['startY', '%'],
            start_xAbsolute: ['startX', 'round'],
            start_yAbsolute: ['startY', 'round'],
            innerRadius_percent: ['innerRadius', '%'],
            innerRadius_absolute: ['innerRadius', 'round'],
            outerRadius_percent: ['outerRadius', '%'],
            outerRadius_absolute: ['outerRadius', 'round'],
            angle: ['angle', 'round'],
            transparentEdges: ['transparentEdges', 'boolean'],
        },
    });
    
    scrawl.addNativeListener(['input', 'change'], (e) => {
    
        e.preventDefault();
        e.returnValue = false;
    
        let val = e.target.value;
    
        if (['user-steps', 'user-zigzag'].includes(val)) {
            swirl.set({
                easing: bespokeEasings[val],
            });
        }
        else {
            swirl.set({
                easing: val,
            });
        }
    }, '#easing');
  • §

    Setup form

    const opacity = document.querySelector('#opacity');
    const angle = document.querySelector('#angle');
  • §

    @ts-expect-error

    opacity.value = 1;
  • §

    @ts-expect-error

    angle.value = 90;
  • §

    @ts-expect-error

    document.querySelector('#start_xPercent').value = 50;
  • §

    @ts-expect-error

    document.querySelector('#start_yPercent').value = 50;
  • §

    @ts-expect-error

    document.querySelector('#start_xAbsolute').value = 200;
  • §

    @ts-expect-error

    document.querySelector('#start_yAbsolute').value = 200;
  • §

    @ts-expect-error

    document.querySelector('#innerRadius_percent').value = 0;
  • §

    @ts-expect-error

    document.querySelector('#innerRadius_absolute').value = 0;
  • §

    @ts-expect-error

    document.querySelector('#outerRadius_percent').value = 30;
  • §

    @ts-expect-error

    document.querySelector('#outerRadius_absolute').value = 120;
  • §

    @ts-expect-error

    document.querySelector('#easing').options.selectedIndex = 0;
  • §

    Drag-and-Drop image loading functionality

    addImageDragAndDrop(canvas, '#my-image-store', piccy);
  • §

    Development and testing

    console.log(scrawl.library);