UNPKG

@belvo-finance/belvo-vue-components

Version:

## Project setup ``` npm install ```

441 lines (415 loc) 18.2 kB
var PropertyFactory = (function(){ var initFrame = initialDefaultFrame; var math_abs = Math.abs; function interpolateValue(frameNum, caching) { var offsetTime = this.offsetTime; var newValue; if (this.propType === 'multidimensional') { newValue = createTypedArray('float32', this.pv.length); } var iterationIndex = caching.lastIndex; var i = iterationIndex; var len = this.keyframes.length - 1, flag = true; var keyData, nextKeyData; while (flag) { keyData = this.keyframes[i]; nextKeyData = this.keyframes[i + 1]; if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime){ if(keyData.h){ keyData = nextKeyData; } iterationIndex = 0; break; } if ((nextKeyData.t - offsetTime) > frameNum){ iterationIndex = i; break; } if (i < len - 1){ i += 1; } else { iterationIndex = 0; flag = false; } } var k, kLen, perc, jLen, j, fnc; var nextKeyTime = nextKeyData.t - offsetTime; var keyTime = keyData.t - offsetTime; var endValue; if (keyData.to) { if (!keyData.bezierData) { keyData.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti); } var bezierData = keyData.bezierData; if (frameNum >= nextKeyTime || frameNum < keyTime) { var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0; kLen = bezierData.points[ind].point.length; for (k = 0; k < kLen; k += 1) { newValue[k] = bezierData.points[ind].point[k]; } // caching._lastKeyframeIndex = -1; } else { if (keyData.__fnct) { fnc = keyData.__fnct; } else { fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get; keyData.__fnct = fnc; } perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime)); var distanceInLine = bezierData.segmentLength*perc; var segmentPerc; var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0; j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0; flag = true; jLen = bezierData.points.length; while (flag) { addedLength += bezierData.points[j].partialLength; if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) { kLen = bezierData.points[j].point.length; for (k = 0; k < kLen; k += 1) { newValue[k] = bezierData.points[j].point[k]; } break; } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) { segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength; kLen = bezierData.points[j].point.length; for (k = 0; k < kLen; k += 1) { newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc; } break; } if (j < jLen - 1){ j += 1; } else { flag = false; } } caching._lastPoint = j; caching._lastAddedLength = addedLength - bezierData.points[j].partialLength; caching._lastKeyframeIndex = i; } } else { var outX, outY, inX, inY, keyValue; len = keyData.s.length; endValue = nextKeyData.s || keyData.e; if (this.sh && keyData.h !== 1) { if (frameNum >= nextKeyTime) { newValue[0] = endValue[0]; newValue[1] = endValue[1]; newValue[2] = endValue[2]; } else if (frameNum <= keyTime) { newValue[0] = keyData.s[0]; newValue[1] = keyData.s[1]; newValue[2] = keyData.s[2]; } else { var quatStart = createQuaternion(keyData.s); var quatEnd = createQuaternion(endValue); var time = (frameNum - keyTime) / (nextKeyTime - keyTime); quaternionToEuler(newValue, slerp(quatStart, quatEnd, time)); } } else { for(i = 0; i < len; i += 1) { if (keyData.h !== 1) { if (frameNum >= nextKeyTime) { perc = 1; } else if(frameNum < keyTime) { perc = 0; } else { if(keyData.o.x.constructor === Array) { if (!keyData.__fnct) { keyData.__fnct = []; } if (!keyData.__fnct[i]) { outX = (typeof keyData.o.x[i] === 'undefined') ? keyData.o.x[0] : keyData.o.x[i]; outY = (typeof keyData.o.y[i] === 'undefined') ? keyData.o.y[0] : keyData.o.y[i]; inX = (typeof keyData.i.x[i] === 'undefined') ? keyData.i.x[0] : keyData.i.x[i]; inY = (typeof keyData.i.y[i] === 'undefined') ? keyData.i.y[0] : keyData.i.y[i]; fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; keyData.__fnct[i] = fnc; } else { fnc = keyData.__fnct[i]; } } else { if (!keyData.__fnct) { outX = keyData.o.x; outY = keyData.o.y; inX = keyData.i.x; inY = keyData.i.y; fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get; keyData.__fnct = fnc; } else { fnc = keyData.__fnct; } } perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime )); } } endValue = nextKeyData.s || keyData.e; keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc; if (this.propType === 'multidimensional') { newValue[i] = keyValue; } else { newValue = keyValue; } } } } caching.lastIndex = iterationIndex; return newValue; } //based on @Toji's https://github.com/toji/gl-matrix/ function slerp(a, b, t) { var out = []; var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3] var omega, cosom, sinom, scale0, scale1; cosom = ax * bx + ay * by + az * bz + aw * bw; if (cosom < 0.0) { cosom = -cosom; bx = -bx; by = -by; bz = -bz; bw = -bw; } if ((1.0 - cosom) > 0.000001) { omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { scale0 = 1.0 - t; scale1 = t; } out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; } function quaternionToEuler(out, quat) { var qx = quat[0]; var qy = quat[1]; var qz = quat[2]; var qw = quat[3]; var heading = Math.atan2(2*qy*qw-2*qx*qz , 1 - 2*qy*qy - 2*qz*qz) var attitude = Math.asin(2*qx*qy + 2*qz*qw) var bank = Math.atan2(2*qx*qw-2*qy*qz , 1 - 2*qx*qx - 2*qz*qz); out[0] = heading/degToRads; out[1] = attitude/degToRads; out[2] = bank/degToRads; } function createQuaternion(values) { var heading = values[0] * degToRads; var attitude = values[1] * degToRads; var bank = values[2] * degToRads; var c1 = Math.cos(heading / 2); var c2 = Math.cos(attitude / 2); var c3 = Math.cos(bank / 2); var s1 = Math.sin(heading / 2); var s2 = Math.sin(attitude / 2); var s3 = Math.sin(bank / 2); var w = c1 * c2 * c3 - s1 * s2 * s3; var x = s1 * s2 * c3 + c1 * c2 * s3; var y = s1 * c2 * c3 + c1 * s2 * s3; var z = c1 * s2 * c3 - s1 * c2 * s3; return [x,y,z,w]; } function getValueAtCurrentTime(){ 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; if(!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))){ if(this._caching.lastFrame >= frameNum) { this._caching._lastKeyframeIndex = -1; this._caching.lastIndex = 0; } var renderResult = this.interpolateValue(frameNum, this._caching); this.pv = renderResult; } this._caching.lastFrame = frameNum; return this.pv; } function setVValue(val) { var multipliedValue; if(this.propType === 'unidimensional') { multipliedValue = val * this.mult; if(math_abs(this.v - multipliedValue) > 0.00001) { this.v = multipliedValue; this._mdf = true; } } else { var i = 0, len = this.v.length; while (i < len) { multipliedValue = val[i] * this.mult; if (math_abs(this.v[i] - multipliedValue) > 0.00001) { this.v[i] = multipliedValue; this._mdf = true; } i += 1; } } } function processEffectsSequence() { if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) { return; } if(this.lock) { this.setVValue(this.pv); return; } this.lock = true; this._mdf = this._isFirstFrame; var multipliedValue; var i, len = this.effectsSequence.length; var finalValue = this.kf ? this.pv : this.data.k; for(i = 0; i < len; i += 1) { finalValue = this.effectsSequence[i](finalValue); } this.setVValue(finalValue); this._isFirstFrame = false; this.lock = false; this.frameId = this.elem.globalData.frameId; } function addEffect(effectFunction) { this.effectsSequence.push(effectFunction); this.container.addDynamicProperty(this); } function ValueProperty(elem, data, mult, container){ this.propType = 'unidimensional'; this.mult = mult || 1; this.data = data; this.v = mult ? data.k * mult : data.k; this.pv = data.k; this._mdf = false; this.elem = elem; this.container = container; this.comp = elem.comp; this.k = false; this.kf = false; this.vel = 0; this.effectsSequence = []; this._isFirstFrame = true; this.getValue = processEffectsSequence; this.setVValue = setVValue; this.addEffect = addEffect; } function MultiDimensionalProperty(elem, data, mult, container) { this.propType = 'multidimensional'; this.mult = mult || 1; this.data = data; this._mdf = false; this.elem = elem; this.container = container; this.comp = elem.comp; this.k = false; this.kf = false; this.frameId = -1; var i, len = data.k.length; this.v = createTypedArray('float32', len); this.pv = createTypedArray('float32', len); var arr = createTypedArray('float32', len); this.vel = createTypedArray('float32', len); for (i = 0; i < len; i += 1) { this.v[i] = data.k[i] * this.mult; this.pv[i] = data.k[i]; } this._isFirstFrame = true; this.effectsSequence = []; this.getValue = processEffectsSequence; this.setVValue = setVValue; this.addEffect = addEffect; } function KeyframedValueProperty(elem, data, mult, container) { this.propType = 'unidimensional'; this.keyframes = data.k; this.offsetTime = elem.data.st; this.frameId = -1; this._caching = {lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1}; this.k = true; this.kf = true; this.data = data; this.mult = mult || 1; this.elem = elem; this.container = container; this.comp = elem.comp; this.v = initFrame; this.pv = initFrame; this._isFirstFrame = true; this.getValue = processEffectsSequence; this.setVValue = setVValue; this.interpolateValue = interpolateValue; this.effectsSequence = [getValueAtCurrentTime.bind(this)]; this.addEffect = addEffect; } function KeyframedMultidimensionalProperty(elem, data, mult, container){ this.propType = 'multidimensional'; var i, len = data.k.length; var s, e,to,ti; for (i = 0; i < len - 1; i += 1) { if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) { s = data.k[i].s; e = data.k[i + 1].s; to = data.k[i].to; ti = data.k[i].ti; if((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],s[0] + to[0],s[1] + to[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],e[0] + ti[0],e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],s[0] + to[0],s[1] + to[1],s[2] + to[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],e[0] + ti[0],e[1] + ti[1],e[2] + ti[2]))){ data.k[i].to = null; data.k[i].ti = null; } if(s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) { if(s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) { data.k[i].to = null; data.k[i].ti = null; } } } } this.effectsSequence = [getValueAtCurrentTime.bind(this)]; this.keyframes = data.k; this.offsetTime = elem.data.st; this.k = true; this.kf = true; this._isFirstFrame = true; this.mult = mult || 1; this.elem = elem; this.container = container; this.comp = elem.comp; this.getValue = processEffectsSequence; this.setVValue = setVValue; this.interpolateValue = interpolateValue; this.frameId = -1; var arrLen = data.k[0].s.length; this.v = createTypedArray('float32', arrLen); this.pv = createTypedArray('float32', arrLen); for (i = 0; i < arrLen; i += 1) { this.v[i] = initFrame; this.pv[i] = initFrame; } this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray('float32', arrLen)}; this.addEffect = addEffect; } function getProp(elem,data,type, mult, container) { var p; if(!data.k.length){ p = new ValueProperty(elem,data, mult, container); }else if(typeof(data.k[0]) === 'number'){ p = new MultiDimensionalProperty(elem,data, mult, container); }else{ switch(type){ case 0: p = new KeyframedValueProperty(elem,data,mult, container); break; case 1: p = new KeyframedMultidimensionalProperty(elem,data,mult, container); break; } } if(p.effectsSequence.length){ container.addDynamicProperty(p); } return p; } var ob = { getProp: getProp }; return ob; }());