• 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 DOM 009

    Stop and restart the main animation loop; add and remove event listener; retrieve all artefacts at a given coordinate

  • ¶

    Run code

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

    Scene setup

    let artefact = scrawl.library.artefact,
        stack = artefact.mystack;
    
    stack.set({
        width: 600,
        height: 600,
    });
  • ¶

    Create a group to hold all the circles

    let circleGroup = scrawl.makeGroup({
        name: 'circles',
        host: 'mystack',
    }).moveArtefactsIntoGroup('f_0', 'f_1', 'f_2', 'f_3', 'f_4', 'f_5', 'f_6', 'f_7', 'f_8', 'f_9', 'f_10', 'f_11', 'f_12', 'f_13', 'f_14', 'f_15', 'f_16', 'f_17', 'f_18', 'f_19', 'f_20', 'f_21', 'f_22', 'f_23', 'f_24', 'f_25', 'f_26', 'f_27', 'f_28', 'f_29', 'f_30', 'f_31', 'f_32', 'f_33', 'f_34', 'f_35', 'f_36', 'f_37', 'f_38', 'f_39', 'f_40', 'f_41', 'f_42', 'f_43', 'f_44', 'f_45', 'f_46', 'f_47', 'f_48', 'f_49');
  • ¶

    Simple random integer number generator

    let getRandom = (n) => Math.round(Math.random() * n);
  • ¶

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

    let colorFactory = scrawl.makeColor({
        name: 'myColorObject',
        rMax: 200,
        gMax: 50,
        bMax: 10,
    });
    
    circleGroup.artefacts.forEach(name => {
    
        let d = getRandom(50) + 50;
    
        let art = artefact[name];
    
        art.set({
            width: d,
            height: d,
    
            startX: `${getRandom(20) + 40}%`,
            startY: `${getRandom(20) + 40}%`,
            handleX: getRandom(500) - 250,
            handleY: getRandom(500) - 250,
    
            roll: getRandom(360),
            collides: true,
    
            delta: {
                roll: (getRandom(5) / 20) + 0.15
            },
    
            css: {
                backgroundColor: colorFactory.get('random'),
                border: '1px solid black',
            }
        });
    });
  • ¶

    Create a group to hold the buttons (also: test Group cloning and packet functionality)

    console.log(circleGroup.saveAsPacket());
  • ¶
    RESULTS:
    [
        "circles",
        "Group",
        "group",
        {
            "name":"circles",
            "artefacts":["f_0","f_1","f_2","f_3",etc],
            "host":"mystack"
        }
    ]
  • ¶

    Test group cloning

    let buttonGroup = circleGroup.clone({
        name: 'buttons',
    }).clearArtefacts().moveArtefactsIntoGroup('start_animation', 'stop_animation', 'start_listeners', 'stop_listeners');
    
    console.log(buttonGroup.saveAsPacket());
  • ¶
    RESULTS:
    [
        "buttons",
        "Group",
        "group",
        {
            "name":"buttons",
            "artefacts":["start_animation","stop_animation","start_listeners","stop_listeners"],
            "host":"mystack"
        }
    ]
  • ¶

    User controls setup

    buttonGroup.setArtefacts({
        width: 240,
        height: 28,
        css: {
            textAlign: 'left',
        },
        domAttributes: {
            disabled: '',
        },
    });
    
    artefact.start_animation.set({
        startY: 0,
    });
    artefact.stop_animation.set({
        startY: 30,
        domAttributes: {
            disabled: 'disabled',
        },
    });
    artefact.start_listeners.set({
        startY: 60,
    });
    artefact.stop_listeners.set({
        startY: 90,
        domAttributes: {
            disabled: 'disabled',
        },
    });
  • ¶

    The apply function triggers the artefact to render itself outside of the Scrawl-canvas display cycle - this will then trigger artefacts (in this case the 50 circles) to recalculate their positions so they can correctly place themselves within the Stack

    stack.apply();
  • ¶

    Variable holds a value shared betwen two different functions

    let targetsLength = 0;
  • ¶

    Scene animation

    Clean up circles before the start of next display cycle

    let reviewCircleClasses = function () {
    
        let firstRun = true;
    
        return function () {
  • ¶

    we need the animation cycle to run once before we disable it

            if(firstRun){
                firstRun = false;
                scrawl.stopCoreAnimationLoop();
            }
  • ¶

    updating the scene step 1 - clear out all instances of the ‘make_opaque’ CSS class from circles

            circleGroup.removeArtefactClasses('make_opaque');
  • ¶

    updating the scene step 2 - check for hits on every iteration of the animation

            let targets = circleGroup.getAllArtefactsAt(stack.here);
  • ¶

    updating the scene step 3 - add the ‘make_opaque’ CSS class to circles under the current cursor position

            targets.forEach(target => target.artefact.addClasses('make_opaque'));
            targetsLength = targets.length;
        };
    }();
    
    
    let report = function () {
    
        let testTicker = Date.now(),
            testTime, testNow, text,
            testMessage = document.querySelector('#reportmessage');
    
        return function () {
    
            testNow = Date.now();
            testTime = testNow - testTicker;
            testTicker = testNow;
    
            testMessage.textContent = `Screen refresh: ${Math.ceil(testTime)}ms; fps: ${Math.floor(1000 / testTime)}
    Hits: ${targetsLength}`;
        };
    }();
  • ¶

    Create the Display cycle animation

    scrawl.makeRender({
    
        name: 'demo-animation',
        target: stack,
        commence: reviewCircleClasses,
        afterShow: report,
    });
  • ¶

    User interaction

    Event listener for the buttons

    let buttonControls = function () {
    
        let spinListener = false,
            startAnimationButton = artefact.start_animation, 
            stopAnimationButton = artefact.stop_animation, 
            startListenersButton = artefact.start_listeners, 
            stopListenersButton = artefact.stop_listeners;
  • ¶

    Defining the spin event listener here

        let spin = (e) => {
    
            e.preventDefault();
            e.returnValue = false;
    
            if (e.target.id == 'mystack') {
    
                circleGroup.setDeltaValues({
                    roll: 'reverse'
                });
            }
        };
    
        return function (e) {
    
            e.preventDefault();
            e.returnValue = false;
    
            switch (e.target.id) {
    
                case 'start_animation':
                    scrawl.startCoreAnimationLoop();
  • ¶

    the updateDomAttributes function is the same as using .set({ domAttributes: { whatever: 'something' }})

                    startAnimationButton.updateDomAttributes('disabled', 'disabled');
                    stopAnimationButton.updateDomAttributes('disabled', '');
                    break;
    
                case 'stop_animation':
                    scrawl.stopCoreAnimationLoop();
    
                    startAnimationButton.updateDomAttributes('disabled', '');
                    stopAnimationButton.updateDomAttributes('disabled', 'disabled');
                    break;
    
                case 'start_listeners':
  • ¶

    addListener returns a function that can be invoked to remove the event listener from the DOM

                    spinListener = scrawl.addListener('up', spin, stack.domElement);
    
                    startListenersButton.updateDomAttributes('disabled', 'disabled');
                    stopListenersButton.updateDomAttributes('disabled', '');
                    break;
    
                case 'stop_listeners':
  • ¶

    Remove the spin event listener by invoking the function returned when creating it

                    if (spinListener) spinListener();
                    spinListener = false;
    
                    startListenersButton.updateDomAttributes('disabled', '');
                    stopListenersButton.updateDomAttributes('disabled', 'disabled');
                    break;
            }
        };
    }();
    
    scrawl.addListener('up', buttonControls, '.controls');
  • ¶

    Development and testing

    console.log(scrawl.library);