first commit

This commit is contained in:
becarta
2025-05-16 00:17:42 +02:00
parent ea5c866137
commit bacf566ec9
6020 changed files with 1715262 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import {
createSizedArray,
createTypedArray,
} from '../helpers/arrays';
import PropertyFactory from '../PropertyFactory';
function DashProperty(elem, data, renderer, container) {
this.elem = elem;
this.frameId = -1;
this.dataProps = createSizedArray(data.length);
this.renderer = renderer;
this.k = false;
this.dashStr = '';
this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
this.dashoffset = createTypedArray('float32', 1);
this.initDynamicPropertyContainer(container);
var i;
var len = data.length || 0;
var prop;
for (i = 0; i < len; i += 1) {
prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
this.k = prop.k || this.k;
this.dataProps[i] = { n: data[i].n, p: prop };
}
if (!this.k) {
this.getValue(true);
}
this._isAnimated = this.k;
}
DashProperty.prototype.getValue = function (forceRender) {
if (this.elem.globalData.frameId === this.frameId && !forceRender) {
return;
}
this.frameId = this.elem.globalData.frameId;
this.iterateDynamicProperties();
this._mdf = this._mdf || forceRender;
if (this._mdf) {
var i = 0;
var len = this.dataProps.length;
if (this.renderer === 'svg') {
this.dashStr = '';
}
for (i = 0; i < len; i += 1) {
if (this.dataProps[i].n !== 'o') {
if (this.renderer === 'svg') {
this.dashStr += ' ' + this.dataProps[i].p.v;
} else {
this.dashArray[i] = this.dataProps[i].p.v;
}
} else {
this.dashoffset[0] = this.dataProps[i].p.v;
}
}
}
};
extendPrototype([DynamicPropertyContainer], DashProperty);
export default DashProperty;

View File

@@ -0,0 +1,93 @@
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import {
createTypedArray,
} from '../helpers/arrays';
import PropertyFactory from '../PropertyFactory';
function GradientProperty(elem, data, container) {
this.data = data;
this.c = createTypedArray('uint8c', data.p * 4);
var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
this.o = createTypedArray('float32', cLength);
this._cmdf = false;
this._omdf = false;
this._collapsable = this.checkCollapsable();
this._hasOpacity = cLength;
this.initDynamicPropertyContainer(container);
this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
this.k = this.prop.k;
this.getValue(true);
}
GradientProperty.prototype.comparePoints = function (values, points) {
var i = 0;
var len = this.o.length / 2;
var diff;
while (i < len) {
diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
if (diff > 0.01) {
return false;
}
i += 1;
}
return true;
};
GradientProperty.prototype.checkCollapsable = function () {
if (this.o.length / 2 !== this.c.length / 4) {
return false;
}
if (this.data.k.k[0].s) {
var i = 0;
var len = this.data.k.k.length;
while (i < len) {
if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
return false;
}
i += 1;
}
} else if (!this.comparePoints(this.data.k.k, this.data.p)) {
return false;
}
return true;
};
GradientProperty.prototype.getValue = function (forceRender) {
this.prop.getValue();
this._mdf = false;
this._cmdf = false;
this._omdf = false;
if (this.prop._mdf || forceRender) {
var i;
var len = this.data.p * 4;
var mult;
var val;
for (i = 0; i < len; i += 1) {
mult = i % 4 === 0 ? 100 : 255;
val = Math.round(this.prop.v[i] * mult);
if (this.c[i] !== val) {
this.c[i] = val;
this._cmdf = !forceRender;
}
}
if (this.o.length) {
len = this.prop.v.length;
for (i = this.data.p * 4; i < len; i += 1) {
mult = i % 2 === 0 ? 100 : 1;
val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
if (this.o[i - this.data.p * 4] !== val) {
this.o[i - this.data.p * 4] = val;
this._omdf = !forceRender;
}
}
}
this._mdf = !forceRender;
}
};
extendPrototype([DynamicPropertyContainer], GradientProperty);
export default GradientProperty;

View File

@@ -0,0 +1,222 @@
import {
extendPrototype,
} from '../functionExtensions';
import {
ShapeModifiers,
ShapeModifier,
} from './ShapeModifiers';
function MouseModifier() {}
extendPrototype([ShapeModifier], MouseModifier);
MouseModifier.prototype.processKeys = function (forceRender) {
if (this.elem.globalData.frameId === this.frameId && !forceRender) {
return;
}
this._mdf = true;
};
MouseModifier.prototype.addShapeToModifier = function () {
this.positions.push([]);
};
MouseModifier.prototype.processPath = function (path, mouseCoords, positions) {
var i;
var len = path.v.length;
var vValues = [];
var oValues = [];
var iValues = [];
var theta;
var x;
var y;
/// / OPTION A
for (i = 0; i < len; i += 1) {
if (!positions.v[i]) {
positions.v[i] = [path.v[i][0], path.v[i][1]];
positions.o[i] = [path.o[i][0], path.o[i][1]];
positions.i[i] = [path.i[i][0], path.i[i][1]];
positions.distV[i] = 0;
positions.distO[i] = 0;
positions.distI[i] = 0;
}
theta = Math.atan2(
path.v[i][1] - mouseCoords[1],
path.v[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.v[i][0];
y = mouseCoords[1] - positions.v[i][1];
var distance = Math.sqrt((x * x) + (y * y));
positions.distV[i] += (distance - positions.distV[i]) * this.data.dc;
positions.v[i][0] = (Math.cos(theta) * Math.max(0, this.data.maxDist - positions.distV[i])) / 2 + (path.v[i][0]);
positions.v[i][1] = (Math.sin(theta) * Math.max(0, this.data.maxDist - positions.distV[i])) / 2 + (path.v[i][1]);
theta = Math.atan2(
path.o[i][1] - mouseCoords[1],
path.o[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.o[i][0];
y = mouseCoords[1] - positions.o[i][1];
distance = Math.sqrt((x * x) + (y * y));
positions.distO[i] += (distance - positions.distO[i]) * this.data.dc;
positions.o[i][0] = (Math.cos(theta) * Math.max(0, this.data.maxDist - positions.distO[i])) / 2 + (path.o[i][0]);
positions.o[i][1] = (Math.sin(theta) * Math.max(0, this.data.maxDist - positions.distO[i])) / 2 + (path.o[i][1]);
theta = Math.atan2(
path.i[i][1] - mouseCoords[1],
path.i[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.i[i][0];
y = mouseCoords[1] - positions.i[i][1];
distance = Math.sqrt((x * x) + (y * y));
positions.distI[i] += (distance - positions.distI[i]) * this.data.dc;
positions.i[i][0] = (Math.cos(theta) * Math.max(0, this.data.maxDist - positions.distI[i])) / 2 + (path.i[i][0]);
positions.i[i][1] = (Math.sin(theta) * Math.max(0, this.data.maxDist - positions.distI[i])) / 2 + (path.i[i][1]);
/// //OPTION 1
vValues.push(positions.v[i]);
oValues.push(positions.o[i]);
iValues.push(positions.i[i]);
/// //OPTION 2
// vValues.push(positions.v[i]);
// iValues.push([path.i[i][0]+(positions.v[i][0]-path.v[i][0]),path.i[i][1]+(positions.v[i][1]-path.v[i][1])]);
// oValues.push([path.o[i][0]+(positions.v[i][0]-path.v[i][0]),path.o[i][1]+(positions.v[i][1]-path.v[i][1])]);
/// //OPTION 3
// vValues.push(positions.v[i]);
// iValues.push(path.i[i]);
// oValues.push(path.o[i]);
/// //OPTION 4
// vValues.push(path.v[i]);
// oValues.push(positions.o[i]);
// iValues.push(positions.i[i]);
}
/// / OPTION B
/* for(i=0;i<len;i+=1){
if(!positions.v[i]){
positions.v[i] = [path.v[i][0],path.v[i][1]];
positions.o[i] = [path.o[i][0],path.o[i][1]];
positions.i[i] = [path.i[i][0],path.i[i][1]];
positions.distV[i] = 0;
}
theta = Math.atan2(
positions.v[i][1] - mouseCoords[1],
positions.v[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.v[i][0];
y = mouseCoords[1] - positions.v[i][1];
var distance = this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
positions.v[i][0] += Math.cos(theta) * distance + (path.v[i][0] - positions.v[i][0]) * this.data.dc;
positions.v[i][1] += Math.sin(theta) * distance + (path.v[i][1] - positions.v[i][1]) * this.data.dc;
theta = Math.atan2(
positions.o[i][1] - mouseCoords[1],
positions.o[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.o[i][0];
y = mouseCoords[1] - positions.o[i][1];
var distance = this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
positions.o[i][0] += Math.cos(theta) * distance + (path.o[i][0] - positions.o[i][0]) * this.data.dc;
positions.o[i][1] += Math.sin(theta) * distance + (path.o[i][1] - positions.o[i][1]) * this.data.dc;
theta = Math.atan2(
positions.i[i][1] - mouseCoords[1],
positions.i[i][0] - mouseCoords[0]
);
x = mouseCoords[0] - positions.i[i][0];
y = mouseCoords[1] - positions.i[i][1];
var distance = this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
positions.i[i][0] += Math.cos(theta) * distance + (path.i[i][0] - positions.i[i][0]) * this.data.dc;
positions.i[i][1] += Math.sin(theta) * distance + (path.i[i][1] - positions.i[i][1]) * this.data.dc;
/////OPTION 1
//vValues.push(positions.v[i]);
// oValues.push(positions.o[i]);
// iValues.push(positions.i[i]);
/////OPTION 2
//vValues.push(positions.v[i]);
// iValues.push([path.i[i][0]+(positions.v[i][0]-path.v[i][0]),path.i[i][1]+(positions.v[i][1]-path.v[i][1])]);
// oValues.push([path.o[i][0]+(positions.v[i][0]-path.v[i][0]),path.o[i][1]+(positions.v[i][1]-path.v[i][1])]);
/////OPTION 3
//vValues.push(positions.v[i]);
//iValues.push(path.i[i]);
//oValues.push(path.o[i]);
/////OPTION 4
//vValues.push(path.v[i]);
// oValues.push(positions.o[i]);
// iValues.push(positions.i[i]);
} */
return {
v: vValues,
o: oValues,
i: iValues,
c: path.c,
};
};
MouseModifier.prototype.processShapes = function () {
var mouseX = this.elem.globalData.mouseX;
var mouseY = this.elem.globalData.mouseY;
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
if (mouseX) {
var localMouseCoords = this.elem.globalToLocal([mouseX, mouseY, 0]);
var shapeData;
var newPaths = [];
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
if (!shapeData.shape._mdf && !this._mdf) {
shapeData.shape.paths = shapeData.last;
} else {
shapeData.shape._mdf = true;
shapePaths = shapeData.shape.paths;
jLen = shapePaths.length;
for (j = 0; j < jLen; j += 1) {
if (!this.positions[i][j]) {
this.positions[i][j] = {
v: [],
o: [],
i: [],
distV: [],
distO: [],
distI: [],
};
}
newPaths.push(this.processPath(shapePaths[j], localMouseCoords, this.positions[i][j]));
}
shapeData.shape.paths = newPaths;
shapeData.last = newPaths;
}
}
}
};
MouseModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.data = data;
this.positions = [];
};
ShapeModifiers.registerModifier('ms', MouseModifier);
export default MouseModifier;

View File

@@ -0,0 +1,306 @@
import {
roundCorner,
} from '../common';
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import shapePool from '../pooling/shape_pool';
import {
ShapeModifier,
} from './ShapeModifiers';
import {
PolynomialBezier,
polarOffset,
lineIntersection,
pointDistance,
pointEqual,
floatEqual,
} from '../PolynomialBezier';
function linearOffset(p1, p2, amount) {
var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
return [
polarOffset(p1, angle, amount),
polarOffset(p2, angle, amount),
];
}
function offsetSegment(segment, amount) {
var p0; var p1a; var p1b; var p2b; var p2a; var
p3;
var e;
e = linearOffset(segment.points[0], segment.points[1], amount);
p0 = e[0];
p1a = e[1];
e = linearOffset(segment.points[1], segment.points[2], amount);
p1b = e[0];
p2b = e[1];
e = linearOffset(segment.points[2], segment.points[3], amount);
p2a = e[0];
p3 = e[1];
var p1 = lineIntersection(p0, p1a, p1b, p2b);
if (p1 === null) p1 = p1a;
var p2 = lineIntersection(p2a, p3, p1b, p2b);
if (p2 === null) p2 = p2a;
return new PolynomialBezier(p0, p1, p2, p3);
}
function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
var p0 = seg1.points[3];
var p1 = seg2.points[0];
// Bevel
if (lineJoin === 3) return p0;
// Connected, they don't need a joint
if (pointEqual(p0, p1)) return p0;
// Round
if (lineJoin === 2) {
var angleOut = -seg1.tangentAngle(1);
var angleIn = -seg2.tangentAngle(0) + Math.PI;
var center = lineIntersection(
p0,
polarOffset(p0, angleOut + Math.PI / 2, 100),
p1,
polarOffset(p1, angleOut + Math.PI / 2, 100)
);
var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
return p1;
}
// Miter
var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
var intersection = lineIntersection(t0, p0, p1, t1);
if (intersection && pointDistance(intersection, p0) < miterLimit) {
outputBezier.setTripleAt(
intersection[0],
intersection[1],
intersection[0],
intersection[1],
intersection[0],
intersection[1],
outputBezier.length()
);
return intersection;
}
return p0;
}
function getIntersection(a, b) {
const intersect = a.intersections(b);
if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
if (intersect.length) return intersect[0];
return null;
}
function pruneSegmentIntersection(a, b) {
var outa = a.slice();
var outb = b.slice();
var intersect = getIntersection(a[a.length - 1], b[0]);
if (intersect) {
outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
outb[0] = b[0].split(intersect[1])[1];
}
if (a.length > 1 && b.length > 1) {
intersect = getIntersection(a[0], b[b.length - 1]);
if (intersect) {
return [
[a[0].split(intersect[0])[0]],
[b[b.length - 1].split(intersect[1])[1]],
];
}
}
return [outa, outb];
}
function pruneIntersections(segments) {
var e;
for (var i = 1; i < segments.length; i += 1) {
e = pruneSegmentIntersection(segments[i - 1], segments[i]);
segments[i - 1] = e[0];
segments[i] = e[1];
}
if (segments.length > 1) {
e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
segments[segments.length - 1] = e[0];
segments[0] = e[1];
}
return segments;
}
function offsetSegmentSplit(segment, amount) {
/*
We split each bezier segment into smaller pieces based
on inflection points, this ensures the control point
polygon is convex.
(A cubic bezier can have none, one, or two inflection points)
*/
var flex = segment.inflectionPoints();
var left;
var right;
var split;
var mid;
if (flex.length === 0) {
return [offsetSegment(segment, amount)];
}
if (flex.length === 1 || floatEqual(flex[1], 1)) {
split = segment.split(flex[0]);
left = split[0];
right = split[1];
return [
offsetSegment(left, amount),
offsetSegment(right, amount),
];
}
split = segment.split(flex[0]);
left = split[0];
var t = (flex[1] - flex[0]) / (1 - flex[0]);
split = split[1].split(t);
mid = split[0];
right = split[1];
return [
offsetSegment(left, amount),
offsetSegment(mid, amount),
offsetSegment(right, amount),
];
}
function OffsetPathModifier() {}
extendPrototype([ShapeModifier], OffsetPathModifier);
OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
this.lineJoin = data.lj;
this._isAnimated = this.amount.effectsSequence.length !== 0;
};
OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
var outputBezier = shapePool.newElement();
outputBezier.c = inputBezier.c;
var count = inputBezier.length();
if (!inputBezier.c) {
count -= 1;
}
var i; var j; var segment;
var multiSegments = [];
for (i = 0; i < count; i += 1) {
segment = PolynomialBezier.shapeSegment(inputBezier, i);
multiSegments.push(offsetSegmentSplit(segment, amount));
}
if (!inputBezier.c) {
for (i = count - 1; i >= 0; i -= 1) {
segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
multiSegments.push(offsetSegmentSplit(segment, amount));
}
}
multiSegments = pruneIntersections(multiSegments);
// Add bezier segments to the output and apply line joints
var lastPoint = null;
var lastSeg = null;
for (i = 0; i < multiSegments.length; i += 1) {
var multiSegment = multiSegments[i];
if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
lastSeg = multiSegment[multiSegment.length - 1];
for (j = 0; j < multiSegment.length; j += 1) {
segment = multiSegment[j];
if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
} else {
outputBezier.setTripleAt(
segment.points[0][0],
segment.points[0][1],
segment.points[1][0],
segment.points[1][1],
segment.points[0][0],
segment.points[0][1],
outputBezier.length()
);
}
outputBezier.setTripleAt(
segment.points[3][0],
segment.points[3][1],
segment.points[3][0],
segment.points[3][1],
segment.points[2][0],
segment.points[2][1],
outputBezier.length()
);
lastPoint = segment.points[3];
}
}
if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
return outputBezier;
};
OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
var amount = this.amount.v;
var miterLimit = this.miterLimit.v;
var lineJoin = this.lineJoin;
if (amount !== 0) {
var shapeData;
var localShapeCollection;
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
localShapeCollection = shapeData.localShapeCollection;
if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
localShapeCollection.releaseShapes();
shapeData.shape._mdf = true;
shapePaths = shapeData.shape.paths.shapes;
jLen = shapeData.shape.paths._length;
for (j = 0; j < jLen; j += 1) {
localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
}
}
shapeData.shape.paths = shapeData.localShapeCollection;
}
}
if (!this.dynamicProperties.length) {
this._mdf = false;
}
};
export default OffsetPathModifier;

View File

@@ -0,0 +1,80 @@
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import shapePool from '../pooling/shape_pool';
import {
ShapeModifier,
} from './ShapeModifiers';
function PuckerAndBloatModifier() {}
extendPrototype([ShapeModifier], PuckerAndBloatModifier);
PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
this._isAnimated = !!this.amount.effectsSequence.length;
};
PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
var percent = amount / 100;
var centerPoint = [0, 0];
var pathLength = path._length;
var i = 0;
for (i = 0; i < pathLength; i += 1) {
centerPoint[0] += path.v[i][0];
centerPoint[1] += path.v[i][1];
}
centerPoint[0] /= pathLength;
centerPoint[1] /= pathLength;
var clonedPath = shapePool.newElement();
clonedPath.c = path.c;
var vX;
var vY;
var oX;
var oY;
var iX;
var iY;
for (i = 0; i < pathLength; i += 1) {
vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
}
return clonedPath;
};
PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
var amount = this.amount.v;
if (amount !== 0) {
var shapeData;
var localShapeCollection;
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
localShapeCollection = shapeData.localShapeCollection;
if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
localShapeCollection.releaseShapes();
shapeData.shape._mdf = true;
shapePaths = shapeData.shape.paths.shapes;
jLen = shapeData.shape.paths._length;
for (j = 0; j < jLen; j += 1) {
localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
}
}
shapeData.shape.paths = shapeData.localShapeCollection;
}
}
if (!this.dynamicProperties.length) {
this._mdf = false;
}
};
export default PuckerAndBloatModifier;

View File

@@ -0,0 +1,232 @@
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import Matrix from '../../3rd_party/transformation-matrix';
import TransformPropertyFactory from '../TransformProperty';
import {
ShapeModifier,
} from './ShapeModifiers';
function RepeaterModifier() {}
extendPrototype([ShapeModifier], RepeaterModifier);
RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
this.data = data;
if (!this.dynamicProperties.length) {
this.getValue(true);
}
this._isAnimated = !!this.dynamicProperties.length;
this.pMatrix = new Matrix();
this.rMatrix = new Matrix();
this.sMatrix = new Matrix();
this.tMatrix = new Matrix();
this.matrix = new Matrix();
};
RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
var dir = inv ? -1 : 1;
var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
rMatrix.rotate(-transform.r.v * dir * perc);
rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
};
RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
this.elem = elem;
this.arr = arr;
this.pos = pos;
this.elemsData = elemsData;
this._currentCopies = 0;
this._elements = [];
this._groups = [];
this.frameId = -1;
this.initDynamicPropertyContainer(elem);
this.initModifierProperties(elem, arr[pos]);
while (pos > 0) {
pos -= 1;
// this._elements.unshift(arr.splice(pos,1)[0]);
this._elements.unshift(arr[pos]);
}
if (this.dynamicProperties.length) {
this.k = true;
} else {
this.getValue(true);
}
};
RepeaterModifier.prototype.resetElements = function (elements) {
var i;
var len = elements.length;
for (i = 0; i < len; i += 1) {
elements[i]._processed = false;
if (elements[i].ty === 'gr') {
this.resetElements(elements[i].it);
}
}
};
RepeaterModifier.prototype.cloneElements = function (elements) {
var newElements = JSON.parse(JSON.stringify(elements));
this.resetElements(newElements);
return newElements;
};
RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
var i;
var len = elements.length;
for (i = 0; i < len; i += 1) {
elements[i]._render = renderFlag;
if (elements[i].ty === 'gr') {
this.changeGroupRender(elements[i].it, renderFlag);
}
}
};
RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
var items;
var itemsTransform;
var i;
var dir;
var cont;
var hasReloaded = false;
if (this._mdf || _isFirstFrame) {
var copies = Math.ceil(this.c.v);
if (this._groups.length < copies) {
while (this._groups.length < copies) {
var group = {
it: this.cloneElements(this._elements),
ty: 'gr',
};
group.it.push({
a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
});
this.arr.splice(0, 0, group);
this._groups.splice(0, 0, group);
this._currentCopies += 1;
}
this.elem.reloadShapes();
hasReloaded = true;
}
cont = 0;
var renderFlag;
for (i = 0; i <= this._groups.length - 1; i += 1) {
renderFlag = cont < copies;
this._groups[i]._render = renderFlag;
this.changeGroupRender(this._groups[i].it, renderFlag);
if (!renderFlag) {
var elems = this.elemsData[i].it;
var transformData = elems[elems.length - 1];
if (transformData.transform.op.v !== 0) {
transformData.transform.op._mdf = true;
transformData.transform.op.v = 0;
} else {
transformData.transform.op._mdf = false;
}
}
cont += 1;
}
this._currentCopies = copies;
/// /
var offset = this.o.v;
var offsetModulo = offset % 1;
var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
var pProps = this.pMatrix.props;
var rProps = this.rMatrix.props;
var sProps = this.sMatrix.props;
this.pMatrix.reset();
this.rMatrix.reset();
this.sMatrix.reset();
this.tMatrix.reset();
this.matrix.reset();
var iteration = 0;
if (offset > 0) {
while (iteration < roundOffset) {
this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
iteration += 1;
}
if (offsetModulo) {
this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
iteration += offsetModulo;
}
} else if (offset < 0) {
while (iteration > roundOffset) {
this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
iteration -= 1;
}
if (offsetModulo) {
this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
iteration -= offsetModulo;
}
}
i = this.data.m === 1 ? 0 : this._currentCopies - 1;
dir = this.data.m === 1 ? 1 : -1;
cont = this._currentCopies;
var j;
var jLen;
while (cont) {
items = this.elemsData[i].it;
itemsTransform = items[items.length - 1].transform.mProps.v.props;
jLen = itemsTransform.length;
items[items.length - 1].transform.mProps._mdf = true;
items[items.length - 1].transform.op._mdf = true;
items[items.length - 1].transform.op.v = this._currentCopies === 1
? this.so.v
: this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
if (iteration !== 0) {
if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
}
this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
for (j = 0; j < jLen; j += 1) {
itemsTransform[j] = this.matrix.props[j];
}
this.matrix.reset();
} else {
this.matrix.reset();
for (j = 0; j < jLen; j += 1) {
itemsTransform[j] = this.matrix.props[j];
}
}
iteration += 1;
cont -= 1;
i += dir;
}
} else {
cont = this._currentCopies;
i = 0;
dir = 1;
while (cont) {
items = this.elemsData[i].it;
itemsTransform = items[items.length - 1].transform.mProps.v.props;
items[items.length - 1].transform.mProps._mdf = false;
items[items.length - 1].transform.op._mdf = false;
cont -= 1;
i += dir;
}
}
return hasReloaded;
};
RepeaterModifier.prototype.addShape = function () {};
export default RepeaterModifier;

View File

@@ -0,0 +1,122 @@
import {
roundCorner,
} from '../common';
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import shapePool from '../pooling/shape_pool';
import {
ShapeModifier,
} from './ShapeModifiers';
function RoundCornersModifier() {}
extendPrototype([ShapeModifier], RoundCornersModifier);
RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
this._isAnimated = !!this.rd.effectsSequence.length;
};
RoundCornersModifier.prototype.processPath = function (path, round) {
var clonedPath = shapePool.newElement();
clonedPath.c = path.c;
var i;
var len = path._length;
var currentV;
var currentI;
var currentO;
var closerV;
var distance;
var newPosPerc;
var index = 0;
var vX;
var vY;
var oX;
var oY;
var iX;
var iY;
for (i = 0; i < len; i += 1) {
currentV = path.v[i];
currentO = path.o[i];
currentI = path.i[i];
if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
if ((i === 0 || i === len - 1) && !path.c) {
clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
/* clonedPath.v[index] = currentV;
clonedPath.o[index] = currentO;
clonedPath.i[index] = currentI; */
index += 1;
} else {
if (i === 0) {
closerV = path.v[len - 1];
} else {
closerV = path.v[i - 1];
}
distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
vX = iX;
iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
vY = iY;
oX = vX - (vX - currentV[0]) * roundCorner;
oY = vY - (vY - currentV[1]) * roundCorner;
clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
index += 1;
if (i === len - 1) {
closerV = path.v[0];
} else {
closerV = path.v[i + 1];
}
distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
vX = oX;
oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
vY = oY;
iX = vX - (vX - currentV[0]) * roundCorner;
iY = vY - (vY - currentV[1]) * roundCorner;
clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
index += 1;
}
} else {
clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
index += 1;
}
}
return clonedPath;
};
RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
var rd = this.rd.v;
if (rd !== 0) {
var shapeData;
var localShapeCollection;
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
localShapeCollection = shapeData.localShapeCollection;
if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
localShapeCollection.releaseShapes();
shapeData.shape._mdf = true;
shapePaths = shapeData.shape.paths.shapes;
jLen = shapeData.shape.paths._length;
for (j = 0; j < jLen; j += 1) {
localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
}
}
shapeData.shape.paths = shapeData.localShapeCollection;
}
}
if (!this.dynamicProperties.length) {
this._mdf = false;
}
};
export default RoundCornersModifier;

View File

@@ -0,0 +1,29 @@
import {
createSizedArray,
} from '../helpers/arrays';
import shapePool from '../pooling/shape_pool';
function ShapeCollection() {
this._length = 0;
this._maxLength = 4;
this.shapes = createSizedArray(this._maxLength);
}
ShapeCollection.prototype.addShape = function (shapeData) {
if (this._length === this._maxLength) {
this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
this._maxLength *= 2;
}
this.shapes[this._length] = shapeData;
this._length += 1;
};
ShapeCollection.prototype.releaseShapes = function () {
var i;
for (i = 0; i < this._length; i += 1) {
shapePool.release(this.shapes[i]);
}
this._length = 0;
};
export default ShapeCollection;

View File

@@ -0,0 +1,71 @@
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import {
initialDefaultFrame,
} from '../../main';
import shapeCollectionPool from '../pooling/shapeCollection_pool';
const ShapeModifiers = (function () {
var ob = {};
var modifiers = {};
ob.registerModifier = registerModifier;
ob.getModifier = getModifier;
function registerModifier(nm, factory) {
if (!modifiers[nm]) {
modifiers[nm] = factory;
}
}
function getModifier(nm, elem, data) {
return new modifiers[nm](elem, data);
}
return ob;
}());
function ShapeModifier() {}
ShapeModifier.prototype.initModifierProperties = function () {};
ShapeModifier.prototype.addShapeToModifier = function () {};
ShapeModifier.prototype.addShape = function (data) {
if (!this.closed) {
// Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
data.sh.container.addDynamicProperty(data.sh);
var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
this.shapes.push(shapeData);
this.addShapeToModifier(shapeData);
if (this._isAnimated) {
data.setAsAnimated();
}
}
};
ShapeModifier.prototype.init = function (elem, data) {
this.shapes = [];
this.elem = elem;
this.initDynamicPropertyContainer(elem);
this.initModifierProperties(elem, data);
this.frameId = initialDefaultFrame;
this.closed = false;
this.k = false;
if (this.dynamicProperties.length) {
this.k = true;
} else {
this.getValue(true);
}
};
ShapeModifier.prototype.processKeys = function () {
if (this.elem.globalData.frameId === this.frameId) {
return;
}
this.frameId = this.elem.globalData.frameId;
this.iterateDynamicProperties();
};
extendPrototype([DynamicPropertyContainer], ShapeModifier);
export {
ShapeModifiers,
ShapeModifier,
};

View File

@@ -0,0 +1,100 @@
import {
createSizedArray,
} from '../helpers/arrays';
import pointPool from '../pooling/point_pool';
function ShapePath() {
this.c = false;
this._length = 0;
this._maxLength = 8;
this.v = createSizedArray(this._maxLength);
this.o = createSizedArray(this._maxLength);
this.i = createSizedArray(this._maxLength);
}
ShapePath.prototype.setPathData = function (closed, len) {
this.c = closed;
this.setLength(len);
var i = 0;
while (i < len) {
this.v[i] = pointPool.newElement();
this.o[i] = pointPool.newElement();
this.i[i] = pointPool.newElement();
i += 1;
}
};
ShapePath.prototype.setLength = function (len) {
while (this._maxLength < len) {
this.doubleArrayLength();
}
this._length = len;
};
ShapePath.prototype.doubleArrayLength = function () {
this.v = this.v.concat(createSizedArray(this._maxLength));
this.i = this.i.concat(createSizedArray(this._maxLength));
this.o = this.o.concat(createSizedArray(this._maxLength));
this._maxLength *= 2;
};
ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
var arr;
this._length = Math.max(this._length, pos + 1);
if (this._length >= this._maxLength) {
this.doubleArrayLength();
}
switch (type) {
case 'v':
arr = this.v;
break;
case 'i':
arr = this.i;
break;
case 'o':
arr = this.o;
break;
default:
arr = [];
break;
}
if (!arr[pos] || (arr[pos] && !replace)) {
arr[pos] = pointPool.newElement();
}
arr[pos][0] = x;
arr[pos][1] = y;
};
ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
this.setXYAt(vX, vY, 'v', pos, replace);
this.setXYAt(oX, oY, 'o', pos, replace);
this.setXYAt(iX, iY, 'i', pos, replace);
};
ShapePath.prototype.reverse = function () {
var newPath = new ShapePath();
newPath.setPathData(this.c, this._length);
var vertices = this.v;
var outPoints = this.o;
var inPoints = this.i;
var init = 0;
if (this.c) {
newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
init = 1;
}
var cnt = this._length - 1;
var len = this._length;
var i;
for (i = init; i < len; i += 1) {
newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
cnt -= 1;
}
return newPath;
};
ShapePath.prototype.length = function () {
return this._length;
};
export default ShapePath;

View File

@@ -0,0 +1,546 @@
import {
degToRads,
roundCorner,
bmMin,
} from '../common';
import {
extendPrototype,
} from '../functionExtensions';
import DynamicPropertyContainer from '../helpers/dynamicProperties';
import PropertyFactory from '../PropertyFactory';
import BezierFactory from '../../3rd_party/BezierEaser';
import shapePool from '../pooling/shape_pool';
import shapeCollectionPool from '../pooling/shapeCollection_pool';
const ShapePropertyFactory = (function () {
var initFrame = -999999;
function interpolateShape(frameNum, previousValue, caching) {
var iterationIndex = caching.lastIndex;
var keyPropS;
var keyPropE;
var isHold;
var j;
var k;
var jLen;
var kLen;
var perc;
var vertexValue;
var kf = this.keyframes;
if (frameNum < kf[0].t - this.offsetTime) {
keyPropS = kf[0].s[0];
isHold = true;
iterationIndex = 0;
} else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
/* if(kf[kf.length - 1].s){
keyPropS = kf[kf.length - 1].s[0];
}else{
keyPropS = kf[kf.length - 2].e[0];
} */
isHold = true;
} else {
var i = iterationIndex;
var len = kf.length - 1;
var flag = true;
var keyData;
var nextKeyData;
var keyframeMetadata;
while (flag) {
keyData = kf[i];
nextKeyData = kf[i + 1];
if ((nextKeyData.t - this.offsetTime) > frameNum) {
break;
}
if (i < len - 1) {
i += 1;
} else {
flag = false;
}
}
keyframeMetadata = this.keyframesMetadata[i] || {};
isHold = keyData.h === 1;
iterationIndex = i;
if (!isHold) {
if (frameNum >= nextKeyData.t - this.offsetTime) {
perc = 1;
} else if (frameNum < keyData.t - this.offsetTime) {
perc = 0;
} else {
var fnc;
if (keyframeMetadata.__fnct) {
fnc = keyframeMetadata.__fnct;
} else {
fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
keyframeMetadata.__fnct = fnc;
}
perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
}
keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
}
keyPropS = keyData.s[0];
}
jLen = previousValue._length;
kLen = keyPropS.i[0].length;
caching.lastIndex = iterationIndex;
for (j = 0; j < jLen; j += 1) {
for (k = 0; k < kLen; k += 1) {
vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
previousValue.i[j][k] = vertexValue;
vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
previousValue.o[j][k] = vertexValue;
vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
previousValue.v[j][k] = vertexValue;
}
}
}
function interpolateShapeCurrentTime() {
var frameNum = this.comp.renderedFrame - this.offsetTime;
var initTime = this.keyframes[0].t - this.offsetTime;
var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
var lastFrame = this._caching.lastFrame;
if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
/// /
this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
this.interpolateShape(frameNum, this.pv, this._caching);
/// /
}
this._caching.lastFrame = frameNum;
return this.pv;
}
function resetShape() {
this.paths = this.localShapeCollection;
}
function shapesEqual(shape1, shape2) {
if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
return false;
}
var i;
var len = shape1._length;
for (i = 0; i < len; i += 1) {
if (shape1.v[i][0] !== shape2.v[i][0]
|| shape1.v[i][1] !== shape2.v[i][1]
|| shape1.o[i][0] !== shape2.o[i][0]
|| shape1.o[i][1] !== shape2.o[i][1]
|| shape1.i[i][0] !== shape2.i[i][0]
|| shape1.i[i][1] !== shape2.i[i][1]) {
return false;
}
}
return true;
}
function setVValue(newPath) {
if (!shapesEqual(this.v, newPath)) {
this.v = shapePool.clone(newPath);
this.localShapeCollection.releaseShapes();
this.localShapeCollection.addShape(this.v);
this._mdf = true;
this.paths = this.localShapeCollection;
}
}
function processEffectsSequence() {
if (this.elem.globalData.frameId === this.frameId) {
return;
} if (!this.effectsSequence.length) {
this._mdf = false;
return;
}
if (this.lock) {
this.setVValue(this.pv);
return;
}
this.lock = true;
this._mdf = false;
var finalValue;
if (this.kf) {
finalValue = this.pv;
} else if (this.data.ks) {
finalValue = this.data.ks.k;
} else {
finalValue = this.data.pt.k;
}
var i;
var len = this.effectsSequence.length;
for (i = 0; i < len; i += 1) {
finalValue = this.effectsSequence[i](finalValue);
}
this.setVValue(finalValue);
this.lock = false;
this.frameId = this.elem.globalData.frameId;
}
function ShapeProperty(elem, data, type) {
this.propType = 'shape';
this.comp = elem.comp;
this.container = elem;
this.elem = elem;
this.data = data;
this.k = false;
this.kf = false;
this._mdf = false;
var pathData = type === 3 ? data.pt.k : data.ks.k;
this.v = shapePool.clone(pathData);
this.pv = shapePool.clone(this.v);
this.localShapeCollection = shapeCollectionPool.newShapeCollection();
this.paths = this.localShapeCollection;
this.paths.addShape(this.v);
this.reset = resetShape;
this.effectsSequence = [];
}
function addEffect(effectFunction) {
this.effectsSequence.push(effectFunction);
this.container.addDynamicProperty(this);
}
ShapeProperty.prototype.interpolateShape = interpolateShape;
ShapeProperty.prototype.getValue = processEffectsSequence;
ShapeProperty.prototype.setVValue = setVValue;
ShapeProperty.prototype.addEffect = addEffect;
function KeyframedShapeProperty(elem, data, type) {
this.propType = 'shape';
this.comp = elem.comp;
this.elem = elem;
this.container = elem;
this.offsetTime = elem.data.st;
this.keyframes = type === 3 ? data.pt.k : data.ks.k;
this.keyframesMetadata = [];
this.k = true;
this.kf = true;
var len = this.keyframes[0].s[0].i.length;
this.v = shapePool.newElement();
this.v.setPathData(this.keyframes[0].s[0].c, len);
this.pv = shapePool.clone(this.v);
this.localShapeCollection = shapeCollectionPool.newShapeCollection();
this.paths = this.localShapeCollection;
this.paths.addShape(this.v);
this.lastFrame = initFrame;
this.reset = resetShape;
this._caching = { lastFrame: initFrame, lastIndex: 0 };
this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
}
KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
KeyframedShapeProperty.prototype.setVValue = setVValue;
KeyframedShapeProperty.prototype.addEffect = addEffect;
var EllShapeProperty = (function () {
var cPoint = roundCorner;
function EllShapePropertyFactory(elem, data) {
this.v = shapePool.newElement();
this.v.setPathData(true, 4);
this.localShapeCollection = shapeCollectionPool.newShapeCollection();
this.paths = this.localShapeCollection;
this.localShapeCollection.addShape(this.v);
this.d = data.d;
this.elem = elem;
this.comp = elem.comp;
this.frameId = -1;
this.initDynamicPropertyContainer(elem);
this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
if (this.dynamicProperties.length) {
this.k = true;
} else {
this.k = false;
this.convertEllToPath();
}
}
EllShapePropertyFactory.prototype = {
reset: resetShape,
getValue: function () {
if (this.elem.globalData.frameId === this.frameId) {
return;
}
this.frameId = this.elem.globalData.frameId;
this.iterateDynamicProperties();
if (this._mdf) {
this.convertEllToPath();
}
},
convertEllToPath: function () {
var p0 = this.p.v[0];
var p1 = this.p.v[1];
var s0 = this.s.v[0] / 2;
var s1 = this.s.v[1] / 2;
var _cw = this.d !== 3;
var _v = this.v;
_v.v[0][0] = p0;
_v.v[0][1] = p1 - s1;
_v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
_v.v[1][1] = p1;
_v.v[2][0] = p0;
_v.v[2][1] = p1 + s1;
_v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
_v.v[3][1] = p1;
_v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
_v.i[0][1] = p1 - s1;
_v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
_v.i[1][1] = p1 - s1 * cPoint;
_v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
_v.i[2][1] = p1 + s1;
_v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
_v.i[3][1] = p1 + s1 * cPoint;
_v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
_v.o[0][1] = p1 - s1;
_v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
_v.o[1][1] = p1 + s1 * cPoint;
_v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
_v.o[2][1] = p1 + s1;
_v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
_v.o[3][1] = p1 - s1 * cPoint;
},
};
extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
return EllShapePropertyFactory;
}());
var StarShapeProperty = (function () {
function StarShapePropertyFactory(elem, data) {
this.v = shapePool.newElement();
this.v.setPathData(true, 0);
this.elem = elem;
this.comp = elem.comp;
this.data = data;
this.frameId = -1;
this.d = data.d;
this.initDynamicPropertyContainer(elem);
if (data.sy === 1) {
this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
this.convertToPath = this.convertStarToPath;
} else {
this.convertToPath = this.convertPolygonToPath;
}
this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
this.localShapeCollection = shapeCollectionPool.newShapeCollection();
this.localShapeCollection.addShape(this.v);
this.paths = this.localShapeCollection;
if (this.dynamicProperties.length) {
this.k = true;
} else {
this.k = false;
this.convertToPath();
}
}
StarShapePropertyFactory.prototype = {
reset: resetShape,
getValue: function () {
if (this.elem.globalData.frameId === this.frameId) {
return;
}
this.frameId = this.elem.globalData.frameId;
this.iterateDynamicProperties();
if (this._mdf) {
this.convertToPath();
}
},
convertStarToPath: function () {
var numPts = Math.floor(this.pt.v) * 2;
var angle = (Math.PI * 2) / numPts;
/* this.v.v.length = numPts;
this.v.i.length = numPts;
this.v.o.length = numPts; */
var longFlag = true;
var longRad = this.or.v;
var shortRad = this.ir.v;
var longRound = this.os.v;
var shortRound = this.is.v;
var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
var i;
var rad;
var roundness;
var perimSegment;
var currentAng = -Math.PI / 2;
currentAng += this.r.v;
var dir = this.data.d === 3 ? -1 : 1;
this.v._length = 0;
for (i = 0; i < numPts; i += 1) {
rad = longFlag ? longRad : shortRad;
roundness = longFlag ? longRound : shortRound;
perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
var x = rad * Math.cos(currentAng);
var y = rad * Math.sin(currentAng);
var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
x += +this.p.v[0];
y += +this.p.v[1];
this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
/* this.v.v[i] = [x,y];
this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
this.v._length = numPts; */
longFlag = !longFlag;
currentAng += angle * dir;
}
},
convertPolygonToPath: function () {
var numPts = Math.floor(this.pt.v);
var angle = (Math.PI * 2) / numPts;
var rad = this.or.v;
var roundness = this.os.v;
var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
var i;
var currentAng = -Math.PI * 0.5;
var dir = this.data.d === 3 ? -1 : 1;
currentAng += this.r.v;
this.v._length = 0;
for (i = 0; i < numPts; i += 1) {
var x = rad * Math.cos(currentAng);
var y = rad * Math.sin(currentAng);
var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
x += +this.p.v[0];
y += +this.p.v[1];
this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
currentAng += angle * dir;
}
this.paths.length = 0;
this.paths[0] = this.v;
},
};
extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
return StarShapePropertyFactory;
}());
var RectShapeProperty = (function () {
function RectShapePropertyFactory(elem, data) {
this.v = shapePool.newElement();
this.v.c = true;
this.localShapeCollection = shapeCollectionPool.newShapeCollection();
this.localShapeCollection.addShape(this.v);
this.paths = this.localShapeCollection;
this.elem = elem;
this.comp = elem.comp;
this.frameId = -1;
this.d = data.d;
this.initDynamicPropertyContainer(elem);
this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
if (this.dynamicProperties.length) {
this.k = true;
} else {
this.k = false;
this.convertRectToPath();
}
}
RectShapePropertyFactory.prototype = {
convertRectToPath: function () {
var p0 = this.p.v[0];
var p1 = this.p.v[1];
var v0 = this.s.v[0] / 2;
var v1 = this.s.v[1] / 2;
var round = bmMin(v0, v1, this.r.v);
var cPoint = round * (1 - roundCorner);
this.v._length = 0;
if (this.d === 2 || this.d === 1) {
this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
if (round !== 0) {
this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
} else {
this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
}
} else {
this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
if (round !== 0) {
this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
} else {
this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
}
}
},
getValue: function () {
if (this.elem.globalData.frameId === this.frameId) {
return;
}
this.frameId = this.elem.globalData.frameId;
this.iterateDynamicProperties();
if (this._mdf) {
this.convertRectToPath();
}
},
reset: resetShape,
};
extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
return RectShapePropertyFactory;
}());
function getShapeProp(elem, data, type) {
var prop;
if (type === 3 || type === 4) {
var dataProp = type === 3 ? data.pt : data.ks;
var keys = dataProp.k;
if (keys.length) {
prop = new KeyframedShapeProperty(elem, data, type);
} else {
prop = new ShapeProperty(elem, data, type);
}
} else if (type === 5) {
prop = new RectShapeProperty(elem, data);
} else if (type === 6) {
prop = new EllShapeProperty(elem, data);
} else if (type === 7) {
prop = new StarShapeProperty(elem, data);
}
if (prop.k) {
elem.addDynamicProperty(prop);
}
return prop;
}
function getConstructorFunction() {
return ShapeProperty;
}
function getKeyframedConstructorFunction() {
return KeyframedShapeProperty;
}
var ob = {};
ob.getShapeProp = getShapeProp;
ob.getConstructorFunction = getConstructorFunction;
ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
return ob;
}());
export default ShapePropertyFactory;

View File

@@ -0,0 +1,359 @@
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import shapePool from '../pooling/shape_pool';
import bez from '../bez';
import {
ShapeModifier,
} from './ShapeModifiers';
import segmentsLengthPool from '../pooling/segments_length_pool';
function TrimModifier() {
}
extendPrototype([ShapeModifier], TrimModifier);
TrimModifier.prototype.initModifierProperties = function (elem, data) {
this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
this.sValue = 0;
this.eValue = 0;
this.getValue = this.processKeys;
this.m = data.m;
this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
};
TrimModifier.prototype.addShapeToModifier = function (shapeData) {
shapeData.pathsData = [];
};
TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
var segments = [];
if (e <= 1) {
segments.push({
s: s,
e: e,
});
} else if (s >= 1) {
segments.push({
s: s - 1,
e: e - 1,
});
} else {
segments.push({
s: s,
e: 1,
});
segments.push({
s: 0,
e: e - 1,
});
}
var shapeSegments = [];
var i;
var len = segments.length;
var segmentOb;
for (i = 0; i < len; i += 1) {
segmentOb = segments[i];
if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
var shapeS;
var shapeE;
if (segmentOb.s * totalModifierLength <= addedLength) {
shapeS = 0;
} else {
shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
}
if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
shapeE = 1;
} else {
shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
}
shapeSegments.push([shapeS, shapeE]);
}
}
if (!shapeSegments.length) {
shapeSegments.push([0, 0]);
}
return shapeSegments;
};
TrimModifier.prototype.releasePathsData = function (pathsData) {
var i;
var len = pathsData.length;
for (i = 0; i < len; i += 1) {
segmentsLengthPool.release(pathsData[i]);
}
pathsData.length = 0;
return pathsData;
};
TrimModifier.prototype.processShapes = function (_isFirstFrame) {
var s;
var e;
if (this._mdf || _isFirstFrame) {
var o = (this.o.v % 360) / 360;
if (o < 0) {
o += 1;
}
if (this.s.v > 1) {
s = 1 + o;
} else if (this.s.v < 0) {
s = 0 + o;
} else {
s = this.s.v + o;
}
if (this.e.v > 1) {
e = 1 + o;
} else if (this.e.v < 0) {
e = 0 + o;
} else {
e = this.e.v + o;
}
if (s > e) {
var _s = s;
s = e;
e = _s;
}
s = Math.round(s * 10000) * 0.0001;
e = Math.round(e * 10000) * 0.0001;
this.sValue = s;
this.eValue = e;
} else {
s = this.sValue;
e = this.eValue;
}
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
var pathsData;
var pathData;
var totalShapeLength;
var totalModifierLength = 0;
if (e === s) {
for (i = 0; i < len; i += 1) {
this.shapes[i].localShapeCollection.releaseShapes();
this.shapes[i].shape._mdf = true;
this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
if (this._mdf) {
this.shapes[i].pathsData.length = 0;
}
}
} else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
var segments = [];
var shapeData;
var localShapeCollection;
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
// if shape hasn't changed and trim properties haven't changed, cached previous path can be used
if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
shapeData.shape.paths = shapeData.localShapeCollection;
} else {
shapePaths = shapeData.shape.paths;
jLen = shapePaths._length;
totalShapeLength = 0;
if (!shapeData.shape._mdf && shapeData.pathsData.length) {
totalShapeLength = shapeData.totalShapeLength;
} else {
pathsData = this.releasePathsData(shapeData.pathsData);
for (j = 0; j < jLen; j += 1) {
pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
pathsData.push(pathData);
totalShapeLength += pathData.totalLength;
}
shapeData.totalShapeLength = totalShapeLength;
shapeData.pathsData = pathsData;
}
totalModifierLength += totalShapeLength;
shapeData.shape._mdf = true;
}
}
var shapeS = s;
var shapeE = e;
var addedLength = 0;
var edges;
for (i = len - 1; i >= 0; i -= 1) {
shapeData = this.shapes[i];
if (shapeData.shape._mdf) {
localShapeCollection = shapeData.localShapeCollection;
localShapeCollection.releaseShapes();
// if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
if (this.m === 2 && len > 1) {
edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
addedLength += shapeData.totalShapeLength;
} else {
edges = [[shapeS, shapeE]];
}
jLen = edges.length;
for (j = 0; j < jLen; j += 1) {
shapeS = edges[j][0];
shapeE = edges[j][1];
segments.length = 0;
if (shapeE <= 1) {
segments.push({
s: shapeData.totalShapeLength * shapeS,
e: shapeData.totalShapeLength * shapeE,
});
} else if (shapeS >= 1) {
segments.push({
s: shapeData.totalShapeLength * (shapeS - 1),
e: shapeData.totalShapeLength * (shapeE - 1),
});
} else {
segments.push({
s: shapeData.totalShapeLength * shapeS,
e: shapeData.totalShapeLength,
});
segments.push({
s: 0,
e: shapeData.totalShapeLength * (shapeE - 1),
});
}
var newShapesData = this.addShapes(shapeData, segments[0]);
if (segments[0].s !== segments[0].e) {
if (segments.length > 1) {
var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
if (lastShapeInCollection.c) {
var lastShape = newShapesData.pop();
this.addPaths(newShapesData, localShapeCollection);
newShapesData = this.addShapes(shapeData, segments[1], lastShape);
} else {
this.addPaths(newShapesData, localShapeCollection);
newShapesData = this.addShapes(shapeData, segments[1]);
}
}
this.addPaths(newShapesData, localShapeCollection);
}
}
shapeData.shape.paths = localShapeCollection;
}
}
} else if (this._mdf) {
for (i = 0; i < len; i += 1) {
// Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
// Don't remove this even if it's losing cached info.
this.shapes[i].pathsData.length = 0;
this.shapes[i].shape._mdf = true;
}
}
};
TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
var i;
var len = newPaths.length;
for (i = 0; i < len; i += 1) {
localShapeCollection.addShape(newPaths[i]);
}
};
TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
if (newShape) {
shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
}
shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
};
TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
shapePath.setXYAt(points[1], points[5], 'o', pos);
shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
if (newShape) {
shapePath.setXYAt(points[0], points[4], 'v', pos);
}
shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
};
TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
var pathsData = shapeData.pathsData;
var shapePaths = shapeData.shape.paths.shapes;
var i;
var len = shapeData.shape.paths._length;
var j;
var jLen;
var addedLength = 0;
var currentLengthData;
var segmentCount;
var lengths;
var segment;
var shapes = [];
var initPos;
var newShape = true;
if (!shapePath) {
shapePath = shapePool.newElement();
segmentCount = 0;
initPos = 0;
} else {
segmentCount = shapePath._length;
initPos = shapePath._length;
}
shapes.push(shapePath);
for (i = 0; i < len; i += 1) {
lengths = pathsData[i].lengths;
shapePath.c = shapePaths[i].c;
jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
for (j = 1; j < jLen; j += 1) {
currentLengthData = lengths[j - 1];
if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
addedLength += currentLengthData.addedLength;
shapePath.c = false;
} else if (addedLength > shapeSegment.e) {
shapePath.c = false;
break;
} else {
if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
newShape = false;
} else {
segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
// this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
newShape = false;
shapePath.c = false;
}
addedLength += currentLengthData.addedLength;
segmentCount += 1;
}
}
if (shapePaths[i].c && lengths.length) {
currentLengthData = lengths[j - 1];
if (addedLength <= shapeSegment.e) {
var segmentLength = lengths[j - 1].addedLength;
if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
newShape = false;
} else {
segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
// this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
newShape = false;
shapePath.c = false;
}
} else {
shapePath.c = false;
}
addedLength += currentLengthData.addedLength;
segmentCount += 1;
}
if (shapePath._length) {
shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
}
if (addedLength > shapeSegment.e) {
break;
}
if (i < len - 1) {
shapePath = shapePool.newElement();
newShape = true;
shapes.push(shapePath);
segmentCount = 0;
}
}
return shapes;
};
export default TrimModifier;

View File

@@ -0,0 +1,174 @@
import {
extendPrototype,
} from '../functionExtensions';
import PropertyFactory from '../PropertyFactory';
import shapePool from '../pooling/shape_pool';
import {
ShapeModifier,
} from './ShapeModifiers';
import { PolynomialBezier } from '../PolynomialBezier';
function ZigZagModifier() {}
extendPrototype([ShapeModifier], ZigZagModifier);
ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
this.getValue = this.processKeys;
this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
};
function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
var angO = angle - Math.PI / 2;
var angI = angle + Math.PI / 2;
var px = point[0] + Math.cos(angle) * direction * amplitude;
var py = point[1] - Math.sin(angle) * direction * amplitude;
outputBezier.setTripleAt(
px,
py,
px + Math.cos(angO) * outAmplitude,
py - Math.sin(angO) * outAmplitude,
px + Math.cos(angI) * inAmplitude,
py - Math.sin(angI) * inAmplitude,
outputBezier.length()
);
}
function getPerpendicularVector(pt1, pt2) {
var vector = [
pt2[0] - pt1[0],
pt2[1] - pt1[1],
];
var rot = -Math.PI * 0.5;
var rotatedVector = [
Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
];
return rotatedVector;
}
function getProjectingAngle(path, cur) {
var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
var nextIndex = (cur + 1) % path.length();
var prevPoint = path.v[prevIndex];
var nextPoint = path.v[nextIndex];
var pVector = getPerpendicularVector(prevPoint, nextPoint);
return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
}
function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
var angle = getProjectingAngle(path, cur);
var point = path.v[cur % path._length];
var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
var nextPoint = path.v[(cur + 1) % path._length];
var prevDist = pointType === 2
? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
: 0;
var nextDist = pointType === 2
? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
: 0;
setPoint(
outputBezier,
path.v[cur % path._length],
angle,
direction,
amplitude,
nextDist / ((frequency + 1) * 2),
prevDist / ((frequency + 1) * 2),
pointType
);
}
function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
for (var i = 0; i < frequency; i += 1) {
var t = (i + 1) / (frequency + 1);
var dist = pointType === 2
? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
: 0;
var angle = segment.normalAngle(t);
var point = segment.point(t);
setPoint(
outputBezier,
point,
angle,
direction,
amplitude,
dist / ((frequency + 1) * 2),
dist / ((frequency + 1) * 2),
pointType
);
direction = -direction;
}
return direction;
}
ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
var count = path._length;
var clonedPath = shapePool.newElement();
clonedPath.c = path.c;
if (!path.c) {
count -= 1;
}
if (count === 0) return clonedPath;
var direction = -1;
var segment = PolynomialBezier.shapeSegment(path, 0);
zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
for (var i = 0; i < count; i += 1) {
direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
if (i === count - 1 && !path.c) {
segment = null;
} else {
segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
}
zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
}
return clonedPath;
};
ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
var shapePaths;
var i;
var len = this.shapes.length;
var j;
var jLen;
var amplitude = this.amplitude.v;
var frequency = Math.max(0, Math.round(this.frequency.v));
var pointType = this.pointsType.v;
if (amplitude !== 0) {
var shapeData;
var localShapeCollection;
for (i = 0; i < len; i += 1) {
shapeData = this.shapes[i];
localShapeCollection = shapeData.localShapeCollection;
if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
localShapeCollection.releaseShapes();
shapeData.shape._mdf = true;
shapePaths = shapeData.shape.paths.shapes;
jLen = shapeData.shape.paths._length;
for (j = 0; j < jLen; j += 1) {
localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
}
}
shapeData.shape.paths = shapeData.localShapeCollection;
}
}
if (!this.dynamicProperties.length) {
this._mdf = false;
}
};
export default ZigZagModifier;

View File

@@ -0,0 +1,20 @@
const buildShapeString = function (pathNodes, length, closed, mat) {
if (length === 0) {
return '';
}
var _o = pathNodes.o;
var _i = pathNodes.i;
var _v = pathNodes.v;
var i;
var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
for (i = 1; i < length; i += 1) {
shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
}
if (closed && length) {
shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
shapeString += 'z';
}
return shapeString;
};
export default buildShapeString;