import * as scrawl from '../source/scrawl.js'
import { reportSpeed } from './utilities.js';
import * as scrawl from '../source/scrawl.js'
import { reportSpeed } from './utilities.js';
const canvas = scrawl.findCanvas('mycanvas');
Namespacing boilerplate
const namespace = canvas.name;
const name = (n) => `${namespace}-${n}`;
Define some filters
scrawl.makeFilter({
name: name('grayscale'),
method: 'grayscale',
}).clone({
name: name('invert'),
method: 'invert',
});
scrawl.makeFilter({
name: name('tint'),
method: 'tint',
redInRed: 0.5, redInGreen: 1, redInBlue: 0.9,
greenInRed: 0, greenInGreen: 0.3, greenInBlue: 0.8,
blueInRed: 0.8, blueInGreen: 0.8, blueInBlue: 0.4,
});
scrawl.makeFilter({
name: name('matrix'),
method: 'matrix',
weights: [-1, -1, 0, -1, 1, 1, 0, 1, 1],
});
Create a Shape entity to act as a path for our Tracer entitys
scrawl.makeShape({
name: name('my-arrow'),
pathDefinition: 'M266.2,703.1 h-178 L375.1,990 l287-286.9 H481.9 C507.4,365,683.4,91.9,911.8,25.5 877,15.4,840.9,10,803.9,10 525.1,10,295.5,313.4,266.2,703.1 z',
start: ['center', 'center'],
handle: ['center', 'center'],
scale: 0.4,
roll: -70,
flipUpend: true,
useAsPath: true,
strokeStyle: 'gray',
fillStyle: 'lavender',
lineWidth: 8,
method: 'fillThenDraw',
bringToFrontOnDrag: false,
});
Tracer entitys don’t have any color control built in; we need to create our own color factory
const colorFactory = scrawl.makeColor({
name: name('tracer-3-color-factory'),
minimumColor: 'red',
maximumColor: 'blue',
colorSpace: 'LAB',
});
Create a Tracer entity
scrawl.makeTracer({
name: name('trace-1'),
historyLength: 50,
We will delta-animate this Tracer alonbg the path of our Shape entity
path: name('my-arrow'),
pathPosition: 0,
lockTo: 'path',
delta: {
pathPosition: 0.002,
},
artefact: scrawl.makeWheel({
name: name('burn-1'),
radius: 6,
handle: ['center', 'center'],
fillStyle: 'red',
method: 'fill',
visibility: false,
noUserInteraction: true,
noPositionDependencies: true,
noFilters: true,
noDeltaUpdates: true,
}),
This Tracer will produce a ‘dashed’ effect, by displaying discrete ranges of its history
stampAction: function (artefact, particle, host) {
const history = particle.history;
let start;
history.forEach((p, index) => {
if (index < 10 || (index > 20 && index < 30) || index > 40) {
[ , , ...start] = p;
artefact.simpleStamp(host, { start });
}
});
},
Clone the Tracer entity
}).clone({
name: name('trace-2'),
pathPosition: 0.33,
artefact: scrawl.findEntity(name('burn-1')).clone({
name: name('burn-2'),
fillStyle: 'green',
globalAlpha: 0.2,
}),
Our second Tracer shows a ‘tail-fade’ effect
stampAction: function (artefact, particle, host) {
const history = particle.history,
len = history.length;
let start;
history.forEach((p, index) => {
if (index % 3 === 0) {
[ , , ...start] = p;
artefact.simpleStamp(host, {
start,
globalAlpha: (len - index) / len,
});
}
});
},
Clone the second Tracer entity
}).clone({
name: name('trace-3'),
pathPosition: 0.67,
artefact: scrawl.findEntity(name('burn-1')).clone({
name: name('burn-3'),
fillStyle: 'blue',
}),
This Tracer varies its scale to create a ‘teardrop’ effect
stampAction: function (artefact, particle, host) {
const history = particle.history,
len = history.length;
let start;
history.forEach((p, index) => {
[ , , ...start] = p;
const magicNumber = (len - index) / len;
artefact.simpleStamp(host, {
start,
scale: magicNumber * 3,
fillStyle: colorFactory.getRangeColor(magicNumber),
});
});
},
});
Function to display frames-per-second data, and other information relevant to the demo
const report = reportSpeed('#reportmessage');
Create the Display cycle animation
scrawl.makeRender({
name: name('animation'),
target: canvas,
afterShow: report,
});
Make the arrow draggable
scrawl.makeGroup({
name: name('my-draggable-group'),
}).addArtefacts(name('my-arrow'));
scrawl.makeDragZone({
zone: canvas,
collisionGroup: name('my-draggable-group'),
endOn: ['up', 'leave'],
preventTouchDefaultWhenDragging: true,
});
Action user choice to apply a filter to a Tracer entity
const filterChoice = function (e) {
if (e && e.target) {
e.preventDefault();
e.returnValue = false;
const myTrace = scrawl.findEntity(name('trace-2'));
const val = e.target.value;
/** @ts-expect-error */
myTrace.clearFilters();
/** @ts-expect-error */
if (val) myTrace.addFilters(name(val));
}
};
scrawl.addNativeListener(['input', 'change'], filterChoice, '#filter');
/** @ts-expect-error */
document.querySelector('#filter').options.selectedIndex = 0;
console.log(scrawl.library);