import * as scrawl from '../source/scrawl.js'
import { reportSpeed, killPolylineArtefact } from './utilities.js';Polyline entity functionality
import * as scrawl from '../source/scrawl.js'
import { reportSpeed, killPolylineArtefact } from './utilities.js';let canvas = scrawl.library.artefact.mycanvas;Build some coordinate arrays …
let absoluteCoords = [[100, 200], [200, 400], [300, 300], [400, 400], [500, 200], [240, 100]];
let relativeCoords = [['50%', 'center'], ['40%', '10%'], ['20%', '40%'], ['25%', '80%'], ['70%', '75%'], ['85%', '60%']];… And a third coordinate array using Wheel entitys
absoluteCoords.forEach((item, index) => {
const [x, y] = item;
scrawl.makeWheel({
name: `pin-${index}`,
startX: x,
startY: y,
radius: 20,
handleX: 'center',
handleY: 'center',
shadowColor: 'black',
fillStyle: 'darkgreen',
method: 'fill',
});
});
let pivotCoords = ['pin-0', 'pin-1', 'pin-2', 'pin-3', 'pin-4', 'pin-5'];Add another Wheel entity to act as a (potential) pivot for the Polyline
scrawl.makeWheel({
name: 'pivot-wheel',
start: [50, 50],
radius: 20,
handleX: 'center',
handleY: 'center',
shadowColor: 'black',
fillStyle: 'darkred',
method: 'fill',
});Define the Polyline entity
let myline = scrawl.makePolyline({
name: 'my-polyline',The pins attribute takes an array with elements which are:
set function will also accept an object with attributes: index, x, y - to be used by tweens)
pins: absoluteCoords, pins: absoluteCoords,Tension gives us the curviness of the line:
tension: 0,Whether to connect all the pins (true), or run from first to last pin only (false)
closed: false,The starting position is the top left corner of the box which tightly encloses the Shape - regardless of the positions of any artefacts which may be used as pins. Handles and offsets should work as expected
mapToPins flag is set; now the start coordinate maps directly to the first coordinate supplied in the pins array. Handle and offset values can no longer be relied on. startX: 0,
startY: 0,The precision attribute determines the accuracy for positioning artefacts on the path when they have set their constantPathSpeed flag to true
10; decreasing the value increases the positioning accuracy. The more accurate the positioning, the greater the computational (and memory) burden. precision: 0.05,
pivot: 'pivot-wheel',
lockTo: 'start',
mapToPins: false,
strokeStyle: 'orange',
lineWidth: 6,
lineCap: 'round',
lineJoin: 'round',
shadowColor: 'black',
method: 'draw',Note: the bounding box dimensions reflect the minimum/maximum coordinates of all the pins used to construct the shape. It will only reflect the actual shape of the Shape when useAsPath attribute is set to true
showBoundingBox: true,Note: when using a Polyline entity as a pivot for other artefacts, set the useAsPath flag to true
useAsPath: true,
});Add some Block entitys which will pivot to our Polyline entity
absoluteCoords.forEach((item, index) => {
scrawl.makeBlock({
name: `block-${index}`,
width: 20,
height: 20,
pivot: 'my-polyline',
pivotPin: index,
lockTo: 'pivot',
handleX: 'center',
handleY: 'center',
roll: 45,
fillStyle: 'lightblue',
strokeStyle: 'yellow',
lineWidth: 3,
method: 'fillThenDraw',
});
});Testing natural vs constant speeds along the path
for (let i = 0; i < 10; i++) {
scrawl.makeWheel({
name: `normal-ball-${i}`,
order: 2,
radius: 10,
fillStyle: 'lightgreen',
strokeStyle: 'red',
method: 'fillThenDraw',
handle: ['center', 'center'],
path: 'my-polyline',
pathPosition: i / 100,
lockTo: 'path',
delta: {
pathPosition: 0.001,
},
}).clone({
name: `constant-ball-${i}`,
fillStyle: 'yellow',
strokeStyle :'blue',
pathPosition: (i / 100) + 0.5,
constantSpeedAlongPath: true,
});
}scrawl.makeDragZone({
zone: canvas,
collisionGroup: canvas.base.name,
endOn: ['up', 'leave'],
updateOnStart: {
shadowBlur: 6,
shadowOffsetX: 3,
shadowOffsetY: 3,
},
updateOnEnd: {
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 0,
},
preventTouchDefaultWhenDragging: true,
});Function to display frames-per-second data, and other information relevant to the demo
const report = reportSpeed('#reportmessage', function () {
return `Bounding box: ${myline.getBoundingBox().join(', ')}`;
});Create the Display cycle animation
scrawl.makeRender({
name: 'demo-animation',
target: canvas,
afterShow: report,
});scrawl.observeAndUpdate({
event: ['input', 'change'],
origin: '.controlItem',
target: myline,
useNativeListener: true,
preventDefault: true,
updates: {
tension: ['tension', 'float'],
pivot: ['lockTo', 'raw'],
closed: ['closed', 'boolean'],
path: ['useAsPath', 'boolean'],
map: ['mapToPins', 'boolean'],
reverse: ['flipReverse', 'boolean'],
upend: ['flipUpend', 'boolean'],
roll: ['roll', 'float'],
scale: ['scale', 'float'],
},
});Change the coordinate array used by the Polyline
let updatePins = (e) => {
e.preventDefault();
e.returnValue = false;
let val = e.target.value;
if (val === 'absolute') myline.set({ pins: absoluteCoords });
else if (val === 'relative') myline.set({ pins: relativeCoords });
else if (val === 'artefacts') myline.set({ pins: pivotCoords });
};
scrawl.addNativeListener(['input', 'change'], updatePins, '#pins');Setup form @ts-expect-error
document.querySelector('#tension').value = 0;@ts-expect-error
document.querySelector('#pivot').value = 'start';@ts-expect-error
document.querySelector('#closed').value = 0;@ts-expect-error
document.querySelector('#path').value = 1;@ts-expect-error
document.querySelector('#map').value = 0;@ts-expect-error
document.querySelector('#pins').value = 'absolute';@ts-expect-error
document.querySelector('#reverse').value = 0;@ts-expect-error
document.querySelector('#upend').value = 0;@ts-expect-error
document.querySelector('#roll').value = 0;@ts-expect-error
document.querySelector('#scale').value = 1;console.log(scrawl.library);
console.log('Performing tests ...');
killPolylineArtefact(canvas, 'pin-2', 3000, myline, () => myline.updatePinAt('pin-2', 2));