UNPKG

scrawl-canvas

Version:
160 lines (106 loc) 4.84 kB
// # 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; };