import { constructors } from '../core/library.js';
import { mergeOver } from '../core/utilities.js';
import { requestVector, releaseVector } from './vector.js';
import baseMix from '../mixin/base.js';
import shapeMix from '../mixin/shapeBasic.js';A factory for generating star shape-based entitys
Path-defined entitys represent a diverse range of shapes rendered onto a DOM <canvas> element using the Canvas API’s Path2D interface. They use the shapeBasic and shapePathCalculation (some also use shapeCurve) mixins to define much of their functionality.
All path-defined entitys can be positioned, cloned, filtered etc:
scale instead.A path is a track - straight, or curved, or as complex as required - placed across a container which artefacts can use as a source of their positioning data. We can animate an artifact to move along the path:
useAsPath flag to true.path attribute to the path-defined entity’s name-String (or the entity itself), and set its lockTo Array values to "path".pathPosition attribute to a float Number value between 0.0 - 1.0, with 0 being the start of the path, and 1 being its end.addPathRotation flag to true.delta object, or triggering a Tween to perform the movement.import { constructors } from '../core/library.js';
import { mergeOver } from '../core/utilities.js';
import { requestVector, releaseVector } from './vector.js';
import baseMix from '../mixin/base.js';
import shapeMix from '../mixin/shapeBasic.js';const Star = function (items = {}) {
this.shapeInit(items);
return this;
};let P = Star.prototype = Object.create(Object.prototype);
P.type = 'Star';
P.lib = 'entity';
P.isArtefact = true;
P.isAsset = false;P = baseMix(P);
P = shapeMix(P);let defaultAttributes = {
radius1: 0,
radius2: 0,
points: 0,
twist: 0,
};
P.defs = mergeOver(P.defs, defaultAttributes);let S = P.setters,
D = P.deltaSetters;radius1, radius2
S.radius1 = function (item) {
this.radius1 = item;
this.updateDirty();
};
D.radius1 = function (item) {
this.radius1 += item;
this.updateDirty();
};
S.radius2 = function (item) {
this.radius2 = item;
this.updateDirty();
};
D.radius2 = function (item) {
this.radius2 += item;
this.updateDirty();
};points
S.points = function (item) {
this.points = item;
this.updateDirty();
};
D.points = function (item) {
this.points += item;
this.updateDirty();
};twist
S.twist = function (item) {
this.twist = item;
this.updateDirty();
};
D.twist = function (item) {
this.twist += item;
this.updateDirty();
};cleanSpecies - internal helper function - called by prepareStamp
P.cleanSpecies = function () {
this.dirtySpecies = false;
let p = 'M0,0';
p = this.makeStarPath();
this.pathDefinition = p;
};makeStarPath - internal helper function - called by cleanSpecies
P.makeStarPath = function () {
let points = this.points,
twist = this.twist,
radius1 = this.radius1,
radius2 = this.radius2,
turn = 360 / points,
xPts = [],
currentX, currentY, x, y,
myMin, myXoffset, myYoffset, i,
myPath = '';
if (radius1.substring || radius2.substring) {let here = this.getHere();
radius1 = (radius1.substring) ? (parseFloat(radius1) / 100) * here.w : radius1; radius2 = (radius2.substring) ? (parseFloat(radius2) / 100) * here.w : radius2;
let host = this.getHost();
if (host) {
let [hW, hH] = host.currentDimensions;
radius1 = (radius1.substring) ? (parseFloat(radius1) / 100) * hW : radius1;
radius2 = (radius2.substring) ? (parseFloat(radius2) / 100) * hW : radius2;
}
}
let v1 = requestVector({x: 0, y: -radius1}),
v2 = requestVector({x: 0, y: -radius2});
currentX = v1.x;
currentY = v1.y;
xPts.push(currentX);
v2.rotate(-turn/2);
v2.rotate(twist);
for (i = 0; i < points; i++) {
v2.rotate(turn);
x = parseFloat((v2.x - currentX).toFixed(1));
currentX += x;
xPts.push(currentX);
y = parseFloat((v2.y - currentY).toFixed(1));
currentY += y;
myPath += `${x},${y} `;
v1.rotate(turn);
x = parseFloat((v1.x - currentX).toFixed(1));
currentX += x;
xPts.push(currentX);
y = parseFloat((v1.y - currentY).toFixed(1));
currentY += y;
myPath += `${x},${y} `;
}
releaseVector(v1);
releaseVector(v2);
myMin = Math.min(...xPts);
myXoffset = Math.abs(myMin).toFixed(1);
myPath = `m${myXoffset},0l${myPath}z`;
return myPath;
};Accepts argument with attributes:
0 will produce a star with all of its sides of equal length and the star’s valleys falling midway between its connecting points.radius2 can be larger than radius1scrawl.makeStar({
name: '5star',
startX: 20,
startY: 100,
radius1: 80,
radius2: 50,
points: 5,
fillStyle: 'linen',
method: 'fillAndDraw',
});
const makeStar = function (items = {}) {
items.species = 'star';
return new Star(items);
};
constructors.Star = Star;export {
makeStar,
};