UNPKG

scrawl-canvas

Version:
444 lines (309 loc) 14.9 kB
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 = () => {}) => { // #### Drag-and-Drop image loading functionality 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 // + Because of asynch stuff, we need to wait for stuff to complete before performing this functionality // + The Picture entity copies (for the sake of our sanity) a square part of the image. Thus we shall use the new image's shorter dimension as the copy dimension and offset the longer copy start so we are viewing the middle of it 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, }