import {
library as L,
addNativeListener,
importDomImage,
} from '../source/scrawl.js';import {
library as L,
addNativeListener,
importDomImage,
} from '../source/scrawl.js';Function to display frames-per-second data, and other information relevant to the demo
const reportSpeed = function (output = '', xtra = () => '') {
if (!output) return function () {};
let testTicker = Date.now(),
testTime, testNow,
testMessage = document.querySelector(output);
let history = [],
averageTime = 0;
const addTime = (t) => {
if (history.length > 60) history.shift();
history.push(t);
averageTime = history.reduce((p, c) => p + c, 0);
averageTime /= history.length;
}
return function () {
testNow = Date.now();
testTime = testNow - testTicker;
testTicker = testNow;
addTime(testTime);
let text = `Screen refresh: ${Math.ceil(averageTime)}ms; fps: ${Math.floor(1000 / averageTime)}`;
if (xtra) {
text += `
${xtra()}`;
}
testMessage.textContent = text;
};
};Test to check that artefacts are properly killed and resurrected
const killArtefact = (canvas, name, time, finishResurrection = () => {}) => {
if (canvas && canvas.base && name && time) {
let groupname = canvas.base.name,
packet;
let checkGroupBucket = (name, groupname) => {
let res = L.group[groupname].artefactCalculateBuckets.filter(e => e.name === name );
return (res.length) ? 'no' : 'yes';
};
setTimeout(() => {
console.log(`${name} alive
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
packet = L.artefact[name].saveAsPacket();
L.artefact[name].kill();
setTimeout(() => {
console.log(`${name} killed
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
canvas.actionPacket(packet);
setTimeout(() => {
console.log(`${name} resurrected
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
if (finishResurrection) finishResurrection();
}, 100);
}, 100);
}, time);
}
else console.log('killArtefact test invoked improperly');
};To test styles (Gradient) kill functionality
const killStyle = (canvas, name, time, finishResurrection = () => {}) => {
if (canvas && canvas.base && name && time) {
let packet;
setTimeout(() => {
console.log(`${name} alive
removed from styles: ${(L.styles[name]) ? 'no' : 'yes'}
removed from stylesnames: ${(L.stylesnames.indexOf(name) >= 0) ? 'no' : 'yes'}`);
packet = L.styles[name].saveAsPacket();
L.styles[name].kill();
setTimeout(() => {
console.log(`${name} killed
removed from styles: ${(L.styles[name]) ? 'no' : 'yes'}
removed from stylesnames: ${(L.stylesnames.indexOf(name) >= 0) ? 'no' : 'yes'}`);
canvas.actionPacket(packet);
setTimeout(() => {
console.log(`${name} resurrected
removed from styles: ${(L.styles[name]) ? 'no' : 'yes'}
removed from stylesnames: ${(L.stylesnames.indexOf(name) >= 0) ? 'no' : 'yes'}`);
finishResurrection();
}, 100);
}, 100);
}, time);
}
else console.log('killStyle test invoked improperly');
};To test artefact + anchor kill functionality
const killArtefactAndAnchor = (canvas, name, anchorname, time, finishResurrection = () => {}) => {
let groupname = 'mycanvas_base',
packet;
let checkGroupBucket = (name, groupname) => {
let res = L.group[groupname].artefactCalculateBuckets.filter(e => e.name === name );
return (res.length) ? 'no' : 'yes';
};
setTimeout(() => {
console.log(`${name} alive
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}
anchor removed: ${(L.anchor[anchorname]) ? 'no' : 'yes'}`);
packet = L.artefact[name].saveAsPacket();
L.artefact[name].kill();
setTimeout(() => {
console.log(`${name} killed
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}
anchor removed: ${(L.anchor[anchorname]) ? 'no' : 'yes'}`);
canvas.actionPacket(packet);
setTimeout(() => {
console.log(`${name} resurrected
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}
anchor removed: ${(L.anchor[anchorname]) ? 'no' : 'yes'}`);
finishResurrection();
}, 100);
}, 100);
}, time);
};To test Polyline artefact kill functionality
const killPolylineArtefact = (canvas, name, time, myline, restore = () => {}) => {
let groupname = 'mycanvas_base',
packet;
let checkGroupBucket = (name, groupname) => {
let res = L.group[groupname].artefactCalculateBuckets.filter(e => e.name === name );
return (res.length) ? 'no' : 'yes';
};
let checkPinsArray = (name) => {
if (myline.pins.indexOf(name) >= 0) return 'no';
let res = myline.pins.filter(e => e && e.name === name );
return (res.length) ? 'no' : 'yes';
};
setTimeout(() => {
console.log(`${name} alive
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from polyline pins array: ${checkPinsArray(name)}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
packet = L.artefact[name].saveAsPacket();
L.artefact[name].kill();
setTimeout(() => {
console.log(`${name} killed
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from polyline pins array: ${checkPinsArray(name)}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
canvas.actionPacket(packet);
setTimeout(() => {
if (restore) restore();
console.log(`${name} resurrected
removed from artefact: ${(L.artefact[name]) ? 'no' : 'yes'}
removed from artefactnames: ${(L.artefactnames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from entity: ${(L.entity[name]) ? 'no' : 'yes'}
removed from entitynames: ${(L.entitynames.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from polyline pins array: ${checkPinsArray(name)}
removed from group.artefacts: ${(L.group[groupname].artefacts.indexOf(name) >= 0) ? 'no' : 'yes'}
removed from group.artefactCalculateBuckets: ${checkGroupBucket(name, groupname)}`);
console.log(myline.saveAsPacket());
}, 500);
}, 500);
}, time);
};
const killTicker = (stack, name, time) => {
let packet;
setTimeout(() => {
console.log(`${name} alive
removed from tickers: ${(L.animationtickers[name]) ? 'no' : 'yes'}`);
packet = L.animationtickers[name].saveAsPacket();
L.animationtickers[name].kill();
setTimeout(() => {
console.log(`${name} killed
removed from tickers: ${(L.animationtickers[name]) ? 'no' : 'yes'}`);
stack.actionPacket(packet);
setTimeout(() => {
console.log(`${name} resurrected
removed from tickers: ${(L.animationtickers[name]) ? 'no' : 'yes'}`);
}, 100);
}, 100);
}, time);
};
const addImageDragAndDrop = (canvas, selector, targets, callback = () => {}) => { const store = document.querySelector(selector);
const timeoutDelay = 200;
let counter = 0;
const wrappers = [];
if (Array.isArray(canvas)) wrappers.push(...canvas);
else wrappers.push(canvas);
if (!Array.isArray(targets)) targets = [targets];
addNativeListener(['dragenter', 'dragover', 'dragleave'], (e) => {
e.preventDefault();
e.stopPropagation();
}, wrappers.map(w => w.domElement));
addNativeListener('drop', (e) => {
e.preventDefault();
e.stopPropagation();
const dt = e.dataTransfer;
if (dt) [...dt.files].forEach(addImageAsset);
}, wrappers.map(w => w.domElement));
const addImageAsset = (file) => {
if (file.type.indexOf('image/') === 0) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function() {Create a name for our new asset
const name = `user-upload-${counter}`;
counter++;Add the image to the DOM and create our asset from it
const img = document.createElement('img');@ts-expect-error
img.src = reader.result;
img.id = name;
store.appendChild(img);
importDomImage(`#${name}`);Update our Picture entity’s asset attribute so it displays the new image
targets.forEach(target => {
if (target.type === 'Group') {
target.setArtefacts({
asset: name,
});
}
else {
target.set({
asset: name,
});
}
});HOW TO: set the Picture entity’s copy dimensions to take into account any difference between the old and new image’s dimensions
setTimeout(() => {
const asset = L.asset[name];
const width = asset.get('width'),
height = asset.get('height');
let copyStartX = 0,
copyStartY = 0,
dim = 0;
if (width > height) {
copyStartX = (width - height) / 2;
dim = height;
}
else {
copyStartY = (height - width) / 2;
dim = width;
}
targets.forEach(target => {
if (target.type === 'Group') {
target.setArtefacts({
copyStartX,
copyStartY,
copyWidth: dim,
copyHeight: dim,
});
}
else {
target.set({
copyStartX,
copyStartY,
copyWidth: dim,
copyHeight: dim,
});
}
})
if (callback) setTimeout(callback, timeoutDelay);
}, timeoutDelay);
}
}
};
};
export {
reportSpeed,
killArtefact,
killArtefactAndAnchor,
killPolylineArtefact,
killStyle,
killTicker,
addImageDragAndDrop,
}