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

    EnhancedLabel - TextUnit dynamic manipulation

  • §

    Run code

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

    Scene setup

    Get a handle to the Canvas wrapper

    const canvas = scrawl.findCanvas('mycanvas');
  • §

    Namespacing boilerplate

    const namespace = canvas.name;
    const name = (n) => `${namespace}-${n}`;
    
    
    scrawl.makeWheel({
    
        name: name('ball'),
        radius: 80,
        strokeStyle: 'rgb(255 0 0)',
        lineWidth: 3,
        method: 'draw',
        handle: ['center', 'center'],
        lockTo: 'mouse',
    });
    
    scrawl.makeBlock({
    
        name: name('template'),
        dimensions: ['100%', '100%'],
    
        start: ['center', 'center'],
        handle: ['center', 'center'],
    
        method: 'none',
    });
    
    const effect = scrawl.makeEnhancedLabel({
    
        name: name('effect'),
        layoutTemplate: name('template'),
    
        fontString: '18px "Roboto Serif"',
    
        fillStyle: 'aliceblue',
    
        text: '→ → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → → →',
    
        textHandle: ['center', 'center'],
        wordSpacing: '5px',
        justifyLine: 'space-around',
    });
  • §

    To test line, quadratic, bezier pivoting

    scrawl.makeLine({
        name: name('line'),
    
        useStartAsControlPoint: true,
        pivot: name('effect'),
        pivotIndex: 10,
        lockTo: 'pivot',
    
        endPivot: name('effect'),
        endPivotIndex: 200,
        endLockTo: 'pivot',
    
        lineWidth: 10,
        lineCap: 'round',
        strokeStyle: 'rgb(255 255 255 / 0.4)',
        method: 'draw',
    });
    
    scrawl.makeQuadratic({
        name: name('quad'),
    
        useStartAsControlPoint: true,
        pivot: name('effect'),
        pivotIndex: 10,
        lockTo: 'pivot',
    
        controlPivot: name('effect'),
        controlPivotIndex: 290,
        controlLockTo: 'pivot',
    
        endPivot: name('effect'),
        endPivotIndex: 574,
        endLockTo: 'pivot',
    
        lineWidth: 10,
        lineCap: 'round',
        strokeStyle: 'rgb(255 255 255 / 0.4)',
        method: 'draw',
    });
    
    scrawl.makeBezier({
        name: name('bezier'),
    
        useStartAsControlPoint: true,
        pivot: name('effect'),
        pivotIndex: 10,
        lockTo: 'pivot',
    
        startControlPivot: name('effect'),
        startControlPivotIndex: 270,
        startControlLockTo: 'pivot',
    
        endControlPivot: name('effect'),
        endControlPivotIndex: 390,
        endControlLockTo: 'pivot',
    
        endPivot: name('effect'),
        endPivotIndex: 594,
        endLockTo: 'pivot',
    
        lineWidth: 10,
        lineCap: 'round',
        strokeStyle: 'rgb(255 255 255 / 0.4)',
        method: 'draw',
    });
  • §

    Scene animation

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

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

    Update TextUnit display on a per-display-cycle basis

    let currentX = 0,
        currentY = 0;
    
    const units = effect.get('textUnits'),
        here = canvas.here,
        radToDeg = 180 / Math.PI;
    
    const updateTextUnits = () => {
    
        if (here.x !== currentX || here.y !== currentY) {
    
            const coord = scrawl.requestCoordinate();
    
            let distance, x, y, angle, arrowStyle;
    
            const displayedUnits = units.findAllDisplayedChars();
    
            displayedUnits.forEach(unit => {
    
                [x, y] = coord.setFromVector(here).subtract(unit.startData);
    
                distance = coord.getMagnitude();
  • §

    TS errors occurring because coordinate (and by inference, vector) objects are capable of accepting string values for their x and y attributes, whereas all the erroring values here expect numbers

    /** @ts-expect-error */
                angle = Math.atan2(y, x) * radToDeg;
    
                arrowStyle = {};
    /** @ts-expect-error */
                if (x < 0 && y < 0) arrowStyle.fillStyle = 'rgb(255 140 140)';
    /** @ts-expect-error */
                else if (x > 0 && y < 0) arrowStyle.fillStyle = 'rgb(140 140 255)';
    /** @ts-expect-error */
                else if (x < 0 && y > 0) arrowStyle.fillStyle = 'rgb(140 255 140)';
    /** @ts-expect-error */
                else arrowStyle.fillStyle = 'rgb(255 255 0)';
    
                if (distance < 80) {
    /** @ts-expect-error */
                    arrowStyle.method = 'draw';
    /** @ts-expect-error */
                    arrowStyle.strokeStyle = 'rgb(255 255 255)';
                    angle += 180;
                }
    
                effect.setTextUnit(unit.index, {
  • §

    localAlignment gets added to the entity’s alignment value

                    localAlignment: angle,
  • §

    localStyle can be used to override the following attributes on a per-TextUnit basis:

    • fillStyle, strokeStyle, method
    • includeUnderline, underlineStyle, underlineOffset, underlineWidth
    • includeOverline, overlineStyle, overlineOffset, overlineWidth
    • includeHighlight, highlightStyle
                    localStyle: arrowStyle,
                });
            });
    
            currentX = here.x;
            currentY = here.y;
    
            scrawl.releaseCoordinate(coord);
        }
    };
  • §

    Create the Display cycle animation

    scrawl.makeRender({
    
        name: name('animation'),
        target: canvas,
        commence: updateTextUnits,
        afterShow: report,
    });
  • §

    Development and testing

    console.log(scrawl.library);