scrawl-canvas
Version:
Version 8.9.4 - 19 Nov 2022
160 lines (106 loc) • 4.84 kB
JavaScript
// # Path mixin
// This mixin defines the attributes and functionality required by an artefact so that it can position and rotate itself along the contours of a shape-based entity.
// #### Imports
import { artefact } from '../core/library.js';
import { mergeOver, pushUnique, removeItem, isa_boolean, Ωempty } from '../core/utilities.js';
// #### Export function
export default function (P = Ωempty) {
// #### Shared attributes
let defaultAttributes = {
// __path__ - reference Shape entity object. Can also be set using the Shape's name-String.
path: '',
// __pathPosition__ - float Number between `0.0` - `1.0` representing the distance along the Shape path which is to be used as the reference coordinate.
pathPosition: 0,
// __addPathHandle__, __addPathOffset__, __addPathRotation__ - Boolean flags. When set, the artifact will add its own values to the reference artefact's values, rather than use them as replacement values.
addPathHandle: false,
addPathOffset: true,
addPathRotation: false,
// DEPRECATION WARNING: `constantSpeedAlongPath` replaces the old attribute `constantPathSpeed` which clashes with the attribute set by the ShapeBasic mixin.
constantSpeedAlongPath: false,
};
P.defs = mergeOver(P.defs, defaultAttributes);
mergeOver(P, defaultAttributes);
// #### Packet management
P.packetObjects = pushUnique(P.packetObjects, ['path']);
// #### Clone management
// No additional clone functionality defined here
// #### Kill management
// No additional kill functionality defined here
// #### Get, Set, deltaSet
let S = P.setters,
D = P.deltaSetters;
// #### Prototype functions
// __path__
S.path = function (item) {
if (isa_boolean(item) && !item) {
this.path = null;
if (this.lockTo[0] === 'path') this.lockTo[0] = 'start';
if (this.lockTo[1] === 'path') this.lockTo[1] = 'start';
this.dirtyStampPositions = true;
this.dirtyStampHandlePositions = true;
}
else {
let oldPath = this.path,
newPath = (item.substring) ? artefact[item] : item,
name = this.name;
if (newPath && newPath.name && newPath.useAsPath) {
if (oldPath && oldPath.name !== newPath.name) removeItem(oldPath.pathed, name);
pushUnique(newPath.pathed, name);
this.path = newPath;
this.dirtyStampPositions = true;
this.dirtyStampHandlePositions = true;
}
}
};
// __pathPosition__
// + TODO: current functionality is for pathPosition to loop - is there a case for adding a pathPosition loop flag? If yes, then when that flag is false values < 0 would be corrected back to 0, and vals > 1 would be corrected back to 1.
S.pathPosition = function (item) {
if (item < 0) item = Math.abs(item);
if (item > 1) item = item % 1;
this.pathPosition = parseFloat(item.toFixed(6));
this.dirtyStampPositions = true;
this.dirtyStampHandlePositions = true;
this.currentPathData = false;
};
D.pathPosition = function (item) {
let pos = this.pathPosition + item
if (pos < 0) pos += 1;
if (pos > 1) pos = pos % 1;
this.pathPosition = parseFloat(pos.toFixed(6));
this.dirtyStampPositions = true;
this.dirtyStampHandlePositions = true;
this.currentPathData = false;
};
// __addPathHandle__, __addPathOffset__, __addPathRotation__
S.addPathHandle = function (item) {
this.addPathHandle = item;
this.dirtyHandle = true;
};
S.addPathOffset = function (item) {
this.addPathOffset = item;
this.dirtyOffset = true;
};
S.addPathRotation = function (item) {
this.addPathRotation = item;
this.dirtyRotation = true;
};
// #### Prototype functions
// `getPathData`
P.getPathData = function () {
if (this.currentPathData) return this.currentPathData;
let pathPos = this.pathPosition,
path = this.path,
currentPathData;
if (path) {
// Note: the old attribute `constantPathSpeed` has been deprecated because the ShapeBasic mixin adds that attributes to shapes where it has different functionality. This code is temporary until Scrawl-canvas v9 is released
let speed = this.constantSpeedAlongPath || this.constantPathSpeed || false;
currentPathData = path.getPathPositionData(pathPos, speed);
if (this.addPathRotation) this.dirtyRotation = true;
this.currentPathData = currentPathData;
return currentPathData;
}
return false;
};
// Return the prototype
return P;
};