123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- 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;
|