import scrawl from '../source/scrawl.js'
Animate a DOM element using the delta attribute object; dynamically change classes on a DOM element
import scrawl from '../source/scrawl.js'
let artefact = scrawl.library.artefact,
stack = artefact.mystack,
flower = artefact.flower,
leftbox = artefact.leftbox,
rightbox = artefact.rightbox,
deltaX = 0.4,
deltaY = -0.3,
currentClass = '';
Create a new Group for the box elements, against which we will be checking for hits
.set()
let hitgroup = scrawl.makeGroup({
name: 'hitareas',
host: 'mystack',
});
Update the Stack
stack.set({
width: 600,
height: 400,
This gets the browser to add a drag icon to the stack element’s lower right corner, which in turn allows the user to drag-resize the element in real time.
css: {
overflow: 'hidden',
resize: 'both'
},
Switch on automated element resize capture and processing
checkForResize: true,
});
Update the boxes
rightbox.set({
group: 'hitareas',
startX: '55%',
startY: '15%',
roll: 10,
css: { backgroundColor: 'red' },
});
leftbox.set({
group: hitgroup.name,
startX: '10%',
startY: '35%',
css: { backgroundColor: 'blue' },
});
Batch-update the box artefacts using their shared Group
hitgroup.setArtefacts({
width: '25%',
height: '50%',
css: { opacity: '0.4' },
});
Update the flower wheel
flower.set({
width: 200,
height: 200,
startX: '50%',
startY: '50%',
handleX: 'center',
handleY: 'center',
classes: 'make_round',
delta: {
startX: `${deltaX}%`,
startY: `${deltaY}%`,
roll: 0.5,
},
});
Boundary checking can get very messy very quickly, particularly when using delta animation. The following boilerplate will work in many situations:
let checkForFlowerBoundaryCollisions = function () {
Step 0 - determine the current boundary values (in this case they are dynamic, relative to the current dimensions of the Stack) and the current position of the flower element (again, a dynamic coordinate relative to Stack dimensions)
let [x, y] = flower.get('start'),
[minX, minY] = stack.get('dimensions');
minX /= 10;
minY /= 10;
let maxX = minX * 9,
maxY = minY * 9;
Step 1 - check for boundary crossings
if (x < minX || x > maxX || y < minY || y > maxY) {
Step 2 - reverse out of danger
flower.reverseByDelta();
Step 3 - update the appropriate delta values for the flower
let changes = {};
if (x < minX || x > maxX) {
deltaX = -deltaX;
changes.startX = `${deltaX}%`;
}
if (y < minY || y > maxY) {
deltaY = -deltaY;
changes.startY = `${deltaY}%`;
}
flower.set({
delta: changes
});
Step 4 - move forward away from the boundary
flower.updateByDelta();
}
};
Updating the flower’s DOM element’s class attribute
let checkForFlowerClassUpdates = function () {
let current = hitgroup.getArtefactAt([flower.get('start')]).artefact;
if (current && !currentClass) {
currentClass = (current.name === 'leftbox') ? 'make_blue' : 'make_red';
flower.addClasses(currentClass);
}
else if (!current && currentClass) {
flower.removeClasses(currentClass);
currentClass = '';
}
};
Combining the two check functions above into a single function
let commenceActions = function () {
checkForFlowerBoundaryCollisions();
checkForFlowerClassUpdates();
};
Function to display frames-per-second data, and other information relevant to the demo
let report = function () {
let testTicker = Date.now(),
testTime, testNow,
testMessage = document.querySelector('#reportmessage');
return function () {
testNow = Date.now();
testTime = testNow - testTicker;
testTicker = testNow;
testMessage.textContent = `Screen refresh: ${Math.ceil(testTime)}ms; fps: ${Math.floor(1000 / testTime)}
Current classes: "${flower.get('classes')}"`;
};
}();
Create the Display cycle animation
scrawl.makeRender({
name: 'demo-animation',
commence: commenceActions,
target: stack,
afterShow: report,
We need to finalize the stack’s display after the first Display cycle completes
height
attribute should cascade through to its constituent elements, so that they can finalize their own dimensions and positioning (which in this case are both set relative to the stack’s dimensions). afterCreated: () => {
stack.set({height: 400.1});
scrawl.startCoreListeners();
},
});