* added ESLint and updated all code base 
* updated SVGPathCommander, CubicBezier, shorter-js, minifill
* updated polyfills
* minor CSS fixes
This commit is contained in:
thednp 2021-03-30 09:23:29 +00:00
parent bfc3fabc92
commit 933d61de19
141 changed files with 13482 additions and 8791 deletions

View file

@ -41,6 +41,20 @@ All above mentioned components have a BASE version which doesn't include value p
# Wiki
For a complete developer guide, usage and stuff like npm, visit [the wiki](https://github.com/thednp/kute.js/wiki).
# ESLint
If you include KUTE.js in your project, we recommend using the following ESLint rule:
```js
rules: {
// Disable bitwise for isArcCommand & isPathCommand from SVGPathCommander
// as well as the KUTE.js interpolation functions
"no-bitwise": 0,
}
```
Some **SVGPathCommander** as well as **KUTE.js** interpolation functions make use of `|` (OR) and `>>` operators for fastest number operations.
# Browser Support
KUTE.js is redeveloped for maximum performance on modern browsers. Some legacy browsers might some help, so give them a small polyfill set with most essential features required by KUTE.js to work, powered by [minifill](https://github.com/thednp/minifill), try it. For broader projects you might want to consider <a href="https://cdn.polyfill.io/v2/docs/">polyfills</a>.

View file

@ -440,7 +440,7 @@ pre.language-markup:after {
font-size: 12px; color: #999;
}
pre.language-javascript:after {content: 'Javascript';}
pre.language-javascript:after {content: 'JavaScript';}
pre.language-clike:after {content: 'node';}
pre.language-markup:after {content: 'HTML';}
pre code {background: none;padding: 0; font-weight: normal; font-size: 100%;}

View file

@ -6,10 +6,11 @@ var translateExamples = document.getElementById('translate-examples'),
trx = translateExamples.getElementsByTagName('div')[1],
trry = translateExamples.getElementsByTagName('div')[2],
trz = translateExamples.getElementsByTagName('div')[3],
tr2dTween = KUTE.to(tr2d, {translate:[170,0]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trxTween = KUTE.to(trx, {translateX:-170}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500})
tr2dTween = KUTE.to(tr2d, {translate:[170,170]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trxTween = KUTE.to(trx, {translateX:-170}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trryTween = KUTE.to(trry, {translate3d:[0,170,0]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}),
trzTween = KUTE.to(trz, {perspective:200, translate3d:[0,0,-100]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500});
translateBtn.addEventListener('click', function(){
!tr2dTween.playing && tr2dTween.start();
!trxTween.playing && trxTween.start();
@ -27,6 +28,7 @@ var rotExamples = document.getElementById('rotExamples'),
rxTween = KUTE.to(rx, {rotateX:180}, {easing:'linear', yoyo:true, repeat: 1, duration:1500}),
ryTween = KUTE.to(ry, {perspective:200, rotate3d:[0,-180,0],scale:1.2}, {easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500}),
rzTween = KUTE.to(rz, {rotateZ:360}, {easing:'easingBackOut', yoyo:true, repeat: 1, duration:1500});
rotBtn.addEventListener('click', function(){
!r2dTween.playing && r2dTween.start();
!rxTween.playing && rxTween.start();

View file

@ -145,7 +145,7 @@ let fe4 = KUTE.to('selector4', {filter :{ url: '#mySVGFilter', opacity: 40, drop
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE1</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE2</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE3</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat; filter: url(#mySVGFilter)">FE4</div>
<div class="example-item example-box" style="background: url('https://picsum.photos/400/300') center center no-repeat">FE4</div>
<div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a>

View file

@ -1,5 +1,5 @@
/*!
* KUTE.js Base v2.1.0 (http://thednp.github.io/kute.js)
* KUTE.js Base v2.1.1-alpha1 (http://thednp.github.io/kute.js)
* Copyright 2015-2021 © thednp
* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE)
*/
@ -9,118 +9,153 @@
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory());
}(this, (function () { 'use strict';
var version = "2.1.0";
var version = "2.1.1-alpha1";
var KUTE = {};
var Tweens = [];
var globalObject = typeof (global) !== 'undefined' ? global
: typeof(self) !== 'undefined' ? self
: typeof(window) !== 'undefined' ? window : {};
var globalObject;
if (typeof (global) !== 'undefined') { globalObject = global; }
else if (typeof (window.self) !== 'undefined') { globalObject = window.self; }
else if (typeof (window) !== 'undefined') { globalObject = window; }
else { globalObject = {}; }
var globalObject$1 = globalObject;
// KUTE.js INTERPOLATE FUNCTIONS
// =============================
var Interpolate = {};
// schedule property specific function on animation start
// link property update function to KUTE.js execution context
var onStart = {};
var Time = {};
Time.now = self.performance.now.bind(self.performance);
var that = window.self || window || {};
Time.now = that.performance.now.bind(that.performance);
var Tick = 0;
var Ticker = function (time) {
var i = 0;
while ( i < Tweens.length ) {
if ( Tweens[i].update(time) ) {
i++;
while (i < Tweens.length) {
if (Tweens[i].update(time)) {
i += 1;
} else {
Tweens.splice(i, 1);
}
}
Tick = requestAnimationFrame(Ticker);
};
// stop requesting animation frame
function stop() {
setTimeout(function () {
setTimeout(function () { // re-added for #81
if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick);
Tick = null;
for (var obj in onStart) {
Object.keys(onStart).forEach(function (obj) {
if (typeof (onStart[obj]) === 'function') {
KUTE[obj] && (delete KUTE[obj]);
if (KUTE[obj]) { delete KUTE[obj]; }
} else {
for (var prop in onStart[obj]) {
KUTE[prop] && (delete KUTE[prop]);
}
Object.keys(onStart[obj]).forEach(function (prop) {
if (KUTE[prop]) { delete KUTE[prop]; }
});
}
}
for (var i in Interpolate) {
KUTE[i] && (delete KUTE[i]);
}
});
Object.keys(Interpolate).forEach(function (i) {
if (KUTE[i]) { delete KUTE[i]; }
});
}
},64);
}, 64);
}
var Render = {Tick: Tick,Ticker: Ticker,Tweens: Tweens,Time: Time};
for ( var blob in Render ) {
// KUTE.js render update functions
// ===============================
var Render = {
Tick: Tick, Ticker: Ticker, Tweens: Tweens, Time: Time,
};
Object.keys(Render).forEach(function (blob) {
if (!KUTE[blob]) {
KUTE[blob] = blob === 'Time' ? Time.now : Render[blob];
}
}
globalObject["_KUTE"] = KUTE;
});
globalObject$1._KUTE = KUTE;
var defaultOptions = {
duration: 700,
delay: 0,
easing: 'linear'
easing: 'linear',
};
// link properties to interpolate functions
var linkProperty = {};
// schedule property specific function on animation complete
var onComplete = {};
var Objects = {
defaultOptions: defaultOptions,
linkProperty: linkProperty,
onStart: onStart,
onComplete: onComplete
onComplete: onComplete,
};
// util - a general object for utils like rgbToHex, processEasing
var Util = {};
var connect = {};
// Select Robert Penner's Easing Functions
// updated for ESLint
var Easing = {
linear : function (t) { return t; },
easingQuadraticIn : function (t) { return t*t; },
easingQuadraticOut : function (t) { return t*(2-t); },
easingQuadraticInOut : function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t; },
easingCubicIn : function (t) { return t*t*t; },
easingCubicOut : function (t) { return (--t)*t*t+1; },
easingCubicInOut : function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; },
easingCircularIn : function (t) { return -(Math.sqrt(1 - (t * t)) - 1); },
easingCircularOut : function (t) { return Math.sqrt(1 - (t = t - 1) * t); },
easingCircularInOut : function (t) { return ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); },
easingBackIn : function (t) { var s = 1.70158; return t * t * ((s + 1) * t - s) },
easingBackOut : function (t) { var s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 },
easingBackInOut : function (t) {
linear: function (t) { return t; },
easingQuadraticIn: function (t) { return t * t; },
easingQuadraticOut: function (t) { return t * (2 - t); },
easingQuadraticInOut: function (t) { return (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t); },
easingCubicIn: function (t) { return t * t * t; },
easingCubicOut: function (t0) { var t = t0 - 1; return t * t * t + 1; },
easingCubicInOut: function (t) { return (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1); },
easingCircularIn: function (t) { return -(Math.sqrt(1 - (t * t)) - 1); },
easingCircularOut: function (t0) { },
easingCircularInOut: function (t0) {
var t = t0 * 2;
if (t < 1) { return -0.5 * (Math.sqrt(1 - t * t) - 1); }
t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1);
},
easingBackIn: function (t) { var s = 1.70158; return t * t * ((s + 1) * t - s); },
easingBackOut: function (t0) {
var s = 1.70158;
var t = t0 - 1;
return t * t * ((s + 1) * t + s) + 1;
},
easingBackInOut: function (t0) {
var s = 1.70158 * 1.525;
if ((t *= 2) < 1) { return 0.5 * (t * t * ((s + 1) * t - s)) }
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2)
}
var t = t0 * 2;
if (t < 1) { return 0.5 * (t * t * ((s + 1) * t - s)); }
t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2);
},
};
function processEasing(fn) {
if ( typeof fn === 'function') {
if (typeof fn === 'function') {
return fn;
} else if ( typeof Easing[fn] === 'function' ) {
return Easing[fn];
} else {
return Easing.linear
} if (typeof Easing[fn] === 'function') {
return Easing[fn]; // regular Robert Penner Easing Functions
}
return Easing.linear;
}
connect.processEasing = processEasing;
function add (tw) { return Tweens.push(tw); }
function remove (tw) {
var i = Tweens.indexOf(tw);
i !== -1 && Tweens.splice(i, 1);
if (i !== -1) { Tweens.splice(i, 1); }
}
function getAll () { return Tweens; }
@ -131,33 +166,33 @@
function linkInterpolation() {
var this$1 = this;
var loop = function ( component ) {
// DON'T change
Object.keys(linkProperty).forEach(function (component) {
var componentLink = linkProperty[component];
var componentProps = supportedProperties[component];
for ( var fnObj in componentLink ) {
if ( typeof(componentLink[fnObj]) === 'function'
&& Object.keys(this$1.valuesEnd).some(function (i) { return componentProps && componentProps.includes(i)
|| i=== 'attr' && Object.keys(this$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); }); } ) )
{
!KUTE[fnObj] && (KUTE[fnObj] = componentLink[fnObj]);
Object.keys(componentLink).forEach(function (fnObj) {
if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius
&& Object.keys(this$1.valuesEnd).some(function (i) { return (componentProps && componentProps.includes(i))
|| (i === 'attr' && Object.keys(this$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); })); })) {
if (!KUTE[fnObj]) { KUTE[fnObj] = componentLink[fnObj]; }
} else {
for ( var prop in this$1.valuesEnd ) {
for ( var i in this$1.valuesEnd[prop] ) {
if ( typeof(componentLink[i]) === 'function' ) {
!KUTE[i] && (KUTE[i] = componentLink[i]);
Object.keys(this$1.valuesEnd).forEach(function (prop) {
Object.keys(this$1.valuesEnd[prop]).forEach(function (i) {
if (typeof (componentLink[i]) === 'function') { // transformCSS3
if (!KUTE[i]) { KUTE[i] = componentLink[i]; }
} else {
for (var j in componentLink[fnObj]){
if (componentLink[i] && typeof(componentLink[i][j]) === 'function' ) {
!KUTE[j] && (KUTE[j] = componentLink[i][j]);
Object.keys(componentLink[fnObj]).forEach(function (j) {
if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix
if (!KUTE[j]) { KUTE[j] = componentLink[i][j]; }
}
}
});
}
}
}
});
});
}
}
};
for (var component in linkProperty)loop( component );
});
});
}
var Internals = {
@ -166,136 +201,203 @@
getAll: getAll,
removeAll: removeAll,
stop: stop,
linkInterpolation: linkInterpolation
linkInterpolation: linkInterpolation,
};
// a public selector utility
function selector(el, multi) {
try{
try {
var requestedElem;
if (multi){
requestedElem = el instanceof HTMLCollection
|| el instanceof NodeList
|| el instanceof Array && el.every(function (x) { return x instanceof Element; })
? el : document.querySelectorAll(el);
var itemsArray;
if (multi) {
itemsArray = el instanceof Array && el.every(function (x) { return x instanceof Element; });
requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray
? el : document.querySelectorAll(el);
} else {
requestedElem = el instanceof Element
|| el === window
? el : document.querySelector(el);
requestedElem = el instanceof Element || el === window // scroll
? el : document.querySelector(el);
}
return requestedElem;
} catch(e){
console.error(("KUTE.js - Element(s) not found: " + el + "."));
} catch (e) {
throw TypeError(("KUTE.js - Element(s) not found: " + el + "."));
}
}
var AnimationBase = function AnimationBase(Component){
return this.setComponent(Component)
// Animation class
var AnimationBase = function AnimationBase(Component) {
return this.setComponent(Component);
};
AnimationBase.prototype.setComponent = function setComponent (Component){
AnimationBase.prototype.setComponent = function setComponent (Component) {
var ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
var Functions = { onStart: onStart, onComplete: onComplete };
var Category = Component.category;
var Property = Component.property;
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property;
// ESLint
this._ = 0;
// set supported category/property
supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set additional options
if (Component.defaultOptions) {
for (var op in Component.defaultOptions) {
Object.keys(Component.defaultOptions).forEach(function (op) {
defaultOptions[op] = Component.defaultOptions[op];
}
});
}
// set functions
if (Component.functions) {
for (var fn in Functions) {
Object.keys(Functions).forEach(function (fn) {
if (fn in Component.functions) {
if ( typeof (Component.functions[fn]) === 'function') {
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {});
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn]);
} else {
for ( var ofn in Component.functions[fn] ){
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {});
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]);
if (typeof (Component.functions[fn]) === 'function') {
// if (!Functions[fn][ Category||Property ]) {
// Functions[fn][ Category||Property ] = Component.functions[fn];
// }
if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; }
if (!Functions[fn][ComponentName][Category || Property]) {
Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
}
} else {
Object.keys(Component.functions[fn]).forEach(function (ofn) {
// if (!Functions[fn][ofn]) Functions[fn][ofn] = Component.functions[fn][ofn];
if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; }
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
}
}
}
});
}
// set interpolate
if (Component.Interpolate) {
for (var fni in Component.Interpolate) {
Object.keys(Component.Interpolate).forEach(function (fni) {
var compIntObj = Component.Interpolate[fni];
if ( typeof(compIntObj) === 'function' && !Interpolate[fni] ) {
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
for ( var sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) {
Object.keys(compIntObj).forEach(function (sfn) {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
}
});
}
}
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
for (var fnu in Component.Util){
!Util[fnu] && (Util[fnu] = Component.Util[fnu]);
}
Object.keys(Component.Util).forEach(function (fnu) {
if (!Util[fnu]) { Util[fnu] = Component.Util[fnu]; }
});
}
return {name:ComponentName}
return { name: ComponentName };
};
function queueStart(){
for (var obj in onStart) {
function queueStart() {
var this$1 = this;
// fire onStart actions
Object.keys(onStart).forEach(function (obj) {
if (typeof (onStart[obj]) === 'function') {
onStart[obj].call(this,obj);
onStart[obj].call(this$1, obj); // easing functions
} else {
for (var prop in onStart[obj]) {
onStart[obj][prop].call(this,prop);
}
Object.keys(onStart[obj]).forEach(function (prop) {
onStart[obj][prop].call(this$1, prop);
});
}
}
});
// add interpolations
linkInterpolation.call(this);
}
var TweenBase = function TweenBase(targetElement, startObject, endObject, options){
// single Tween object construct
// TweenBase is meant to be use for pre-processed values
var TweenBase = function TweenBase(targetElement, startObject, endObject, opsObject) {
var this$1 = this;
// element animation is applied to
this.element = targetElement;
this.playing = false;
this._startTime = null;
this._startFired = false;
this.valuesEnd = endObject;
this.valuesStart = startObject;
options = options || {};
this.valuesEnd = endObject; // valuesEnd
this.valuesStart = startObject; // valuesStart
// OPTIONS
var options = opsObject || {};
// internal option to process inline/computed style at start instead of init
// used by to() method and expects object : {} / false
this._resetStart = options.resetStart || 0;
// you can only set a core easing function as default
this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing);
this._duration = options.duration || defaultOptions.duration;
this._delay = options.delay || defaultOptions.delay;
for (var op in options) {
this._duration = options.duration || defaultOptions.duration; // duration option | default
this._delay = options.delay || defaultOptions.delay; // delay option | default
// set other options
Object.keys(options).forEach(function (op) {
var internalOption = "_" + op;
if( !(internalOption in this ) ) { this[internalOption] = options[op]; }
}
if (!(internalOption in this$1)) { this$1[internalOption] = options[op]; }
});
// callbacks should not be set as undefined
// this._onStart = options.onStart
// this._onUpdate = options.onUpdate
// this._onStop = options.onStop
// this._onComplete = options.onComplete
// queue the easing
var easingFnName = this._easing.name;
if (!onStart[easingFnName]) {
onStart[easingFnName] = function(prop){
!KUTE[prop] && prop === this._easing.name && (KUTE[prop] = this._easing);
onStart[easingFnName] = function easingFn(prop) {
if (!KUTE[prop] && prop === this._easing.name) { KUTE[prop] = this._easing; }
};
}
return this;
};
// tween prototype
// queue tween object to main frame update
// move functions that use the ticker outside the prototype to be in the same scope with it
TweenBase.prototype.start = function start (time) {
// now it's a good time to start
add(this);
this.playing = true;
this._startTime = typeof time !== 'undefined' ? time : KUTE.Time();
this._startTime += this._delay;
if (!this._startFired) {
if (this._onStart) {
this._onStart.call(this);
}
queueStart.call(this);
this._startFired = true;
}
!Tick && Ticker();
if (!Tick) { Ticker(); }
return this;
};
TweenBase.prototype.stop = function stop () {
if (this.playing) {
remove(this);
this.playing = false;
if (this._onStop) {
this._onStop.call(this);
}
@ -303,157 +405,254 @@
}
return this;
};
TweenBase.prototype.close = function close () {
for (var component in onComplete){
for (var toClose in onComplete[component]){
onComplete[component][toClose].call(this,toClose);
}
}
var this$1 = this;
// scroll|transformMatrix need this
Object.keys(onComplete).forEach(function (component) {
Object.keys(onComplete[component]).forEach(function (toClose) {
onComplete[component][toClose].call(this$1, toClose);
});
});
// when all animations are finished, stop ticking after ~3 frames
this._startFired = false;
stop.call(this);
};
TweenBase.prototype.chain = function chain (args) {
this._chain = [];
this._chain = args.length ? args : this._chain.concat(args);
return this;
};
TweenBase.prototype.stopChainedTweens = function stopChainedTweens () {
this._chain && this._chain.length && this._chain.map(function (tw){ return tw.stop(); });
if (this._chain && this._chain.length) { this._chain.forEach(function (tw) { return tw.stop(); }); }
};
TweenBase.prototype.update = function update (time) {
time = time !== undefined ? time : KUTE.Time();
var elapsed, progress;
if ( time < this._startTime && this.playing ) { return true; }
elapsed = (time - this._startTime) / this._duration;
var this$1 = this;
var T = time !== undefined ? time : KUTE.Time();
var elapsed;
if (T < this._startTime && this.playing) { return true; }
elapsed = (T - this._startTime) / this._duration;
elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed;
progress = this._easing(elapsed);
for (var tweenProp in this.valuesEnd){
KUTE[tweenProp](this.element,this.valuesStart[tweenProp],this.valuesEnd[tweenProp],progress);
}
// calculate progress
var progress = this._easing(elapsed);
// render the update
Object.keys(this.valuesEnd).forEach(function (tweenProp) {
KUTE[tweenProp](this$1.element,
this$1.valuesStart[tweenProp],
this$1.valuesEnd[tweenProp],
progress);
});
// fire the updateCallback
if (this._onUpdate) {
this._onUpdate.call(this);
}
if (elapsed === 1) {
// fire the complete callback
if (this._onComplete) {
this._onComplete.call(this);
}
// now we're sure no animation is running
this.playing = false;
// stop ticking when finished
this.close();
if (this._chain !== undefined && this._chain.length){
this._chain.map(function (tw){ return tw.start(); });
// start animating chained tweens
if (this._chain !== undefined && this._chain.length) {
this._chain.map(function (tw) { return tw.start(); });
}
return false;
}
return true;
};
// Update Tween Interface
connect.tween = TweenBase;
function fromTo(element, startObject, endObject, optionsObj) {
optionsObj = optionsObj || {};
return new connect.tween(selector(element), startObject, endObject, optionsObj)
var options = optionsObj || {};
var TweenConstructor = connect.tween;
return new TweenConstructor(selector(element), startObject, endObject, options);
}
function numbers(a, b, v) {
a = +a; b -= a; return a + b * v;
function numbers(a, b, v) { // number1, number2, progress
var A = +a;
var B = b - a;
// a = +a; b -= a;
return A + B * v;
}
function arrays(a,b,v){
function arrays(a, b, v) {
var result = [];
for ( var i=0, l=b.length; i<l; i++ ) {
result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0 ) / 1000;
for (var i = 0, l = b.length; i < l; i += 1) {
result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0) / 1000;
}
return result
return result;
}
/* transformMatrix = {
property : 'transform',
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component name
var matrixComponent = 'transformMatrixBase';
var CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix
: null;
// Component special
// this component is restricted to modern browsers only
var CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
// Component Functions
var onStartTransform = {
transform : function(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
transform: function transform(tweenProp) {
if (CSS3Matrix && this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = function (elem, a, b, v) {
var matrix = new CSS3Matrix(), transformObject = {};
for ( var p in b ) {
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v);
var matrix = new CSS3Matrix();
var tObject = {};
Object.keys(b).forEach(function (p) {
tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v);
});
// set perspective
if (tObject.perspective) { matrix.m34 = -1 / tObject.perspective; }
// set translate
matrix = tObject.translate3d
? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2])
: matrix;
// set rotation
matrix = tObject.rotate3d
? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2])
: matrix;
// set skew
if (tObject.skew) {
matrix = tObject.skew[0] ? matrix.skewX(tObject.skew[0]) : matrix;
matrix = tObject.skew[1] ? matrix.skewY(tObject.skew[1]) : matrix;
}
transformObject.perspective && (matrix.m34 = -1/transformObject.perspective);
matrix = transformObject.translate3d ? (matrix.translate(transformObject.translate3d[0],transformObject.translate3d[1],transformObject.translate3d[2])) : matrix;
matrix = transformObject.rotate3d ? (matrix.rotate(transformObject.rotate3d[0],transformObject.rotate3d[1],transformObject.rotate3d[2])) : matrix;
if (transformObject.skew) {
matrix = transformObject.skew[0] ? matrix.skewX(transformObject.skew[0]) : matrix;
matrix = transformObject.skew[1] ? matrix.skewY(transformObject.skew[1]) : matrix;
}
matrix = transformObject.scale3d ? (matrix.scale(transformObject.scale3d[0],transformObject.scale3d[1],transformObject.scale3d[2])): matrix;
// set scale
matrix = tObject.scale3d
? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2])
: matrix;
// set element style
elem.style[tweenProp] = matrix.toString();
};
}
},
CSS3Matrix: function(prop) {
if (this.valuesEnd.transform){
!KUTE[prop] && (KUTE[prop] = CSS3Matrix);
CSS3Matrix: function CSS3Matrix$1(prop) {
if (CSS3Matrix && this.valuesEnd.transform) {
if (!KUTE[prop]) { KUTE[prop] = CSS3Matrix; }
}
},
};
// Component Base Object
var baseMatrixTransform = {
component: matrixComponent,
property: 'transform',
functions: {onStart: onStartTransform},
functions: { onStart: onStartTransform },
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
scale3d: arrays,
},
};
function boxModelOnStart(tweenProp){
// Component Functions
function boxModelOnStart(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = function (elem, a, b, v) {
elem.style[tweenProp] = (v > 0.99 || v < 0.01 ? ((numbers(a,b,v)*10)>>0)/10 : (numbers(a,b,v) ) >> 0) + "px";
elem.style[tweenProp] = (v > 0.99 || v < 0.01
? ((numbers(a, b, v) * 10) >> 0) / 10
: (numbers(a, b, v)) >> 0) + "px";
};
}
}
var baseBoxProps = ['top','left','width','height'];
// Component Base Props
var baseBoxProps = ['top', 'left', 'width', 'height'];
var baseBoxOnStart = {};
baseBoxProps.map(function (x){ return baseBoxOnStart[x] = boxModelOnStart; });
baseBoxProps.forEach(function (x) { baseBoxOnStart[x] = boxModelOnStart; });
// Component Base
var baseBoxModel = {
component: 'baseBoxModel',
category: 'boxModel',
properties: baseBoxProps,
Interpolate: {numbers: numbers},
functions: {onStart: baseBoxOnStart}
Interpolate: { numbers: numbers },
functions: { onStart: baseBoxOnStart },
};
function onStartOpacity(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
/* opacityProperty = {
property: 'opacity',
defaultValue: 1,
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
function onStartOpacity(tweenProp/* , value */) {
// opacity could be 0 sometimes, we need to check regardless
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = function (elem, a, b, v) {
elem.style[tweenProp] = ((numbers(a,b,v) * 1000)>>0)/1000;
elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000;
};
}
}
// Base Component
var baseOpacity = {
component: 'baseOpacity',
property: 'opacity',
Interpolate: {numbers: numbers},
functions: {onStart: onStartOpacity}
// defaultValue: 1,
Interpolate: { numbers: numbers },
functions: { onStart: onStartOpacity },
};
// import {baseCrossBrowserMove} from './components/crossBrowserMove.js'
// const Transform = new Animation(baseTransform)
var Transform = new AnimationBase(baseMatrixTransform);
var BoxModel = new AnimationBase(baseBoxModel);
var Opacity = new AnimationBase(baseOpacity);
// const Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here
var indexBase = {
Animation: AnimationBase,
Components: {
Transform: Transform,
BoxModel: BoxModel,
Opacity: Opacity,
// Move
},
Tween: TweenBase,
fromTo: fromTo,
Objects: Objects,
Easing: Easing,
Util: Util,
@ -461,7 +660,7 @@
Interpolate: Interpolate,
Internals: Internals,
Selector: selector,
Version: version
Version: version,
};
return indexBase;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.14 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;if(Function.prototype.bind||(Function.prototype.bind=function(){var r=Array.prototype.slice,t=this,n=arguments[0],e=r.call(arguments,1);if("function"!=typeof t)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");return function(){var o=e.concat(r.call(arguments));return t.apply(n,o)}}),Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),p=t(n)?Object(new n(f)):new Array(f),c=0;c<f;)u=o[c],p[c]=a?void 0===i?a(u,c):a.call(i,u,c):u,c+=1;return p.length=f,p})),Array.prototype.map||(Array.prototype.map=function(r){var t,n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(t=arguments[1]),n=new Array(i),e=0;e<i;){var a,u;e in o&&(a=o[e],u=r.call(t,a,e,o),n[e]=u),e++}return n}),Array.prototype.some||(Array.prototype.some=function(r,t){if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof r)throw new TypeError;for(var n=Object(this),e=n.length>>>0,o=0;o<e;o++)if(o in n&&r.call(t,n[o],o,n))return!0;return!1}),Array.prototype.every||(Array.prototype.every=function(r,t){var n,e;if(null==this)throw new TypeError("this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof r&&"[object Function]"!==Object.prototype.toString.call(r))throw new TypeError;for(arguments.length>1&&(n=t),e=0;e<i;){var a;if(e in o)if(a=o[e],!(n?r.call(n,a,e,o):r(a,e,o)))return!1;e++}return!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(n,e){return Array.isArray(e)?n.push.apply(n,r.call(e,t-1)):n.push(e),n}),[]):Array.prototype.slice.call(this)},writable:!0}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Date.now||(Date.now=function(){return(new Date).getTime()}),self.performance||(self.performance={}),!self.performance.now){var o=Date.now();self.performance.now=function(){return Date.now()-o}}if(!window.requestAnimationFrame){var i=Date.now();window.requestAnimationFrame=function(r){if("function"!=typeof r)throw new TypeError(r+"is not a function");var t=Date.now(),n=16+i-t;return n<0&&(n=0),i=t,setTimeout((function(){i=Date.now(),r(performance.now())}),n)},window.cancelAnimationFrame=function(r){clearTimeout(r)}}

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.14 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),c=t(n)?Object(new n(f)):new Array(f),p=0;p<f;)u=o[p],c[p]=a?void 0===i?a(u,p):a.call(i,u,p):u,p+=1;return c.length=f,c})),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)});
var r,t,e,n;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},e=Math.pow(2,53)-1,n=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),e)},function(r){var e=this,i=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var u,f=n(i.length),p=t(e)?Object(new e(f)):new Array(f),c=0;c<f;)u=i[c],p[c]=a?void 0===o?a(u,c):a.call(o,u,c):u,c+=1;return p.length=f,p})),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(e,n){return Array.isArray(n)?e.push.apply(e,r.call(n,t-1)):e.push(n),e}),[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),e=parseInt(t.length)||0;if(0===e)return!1;var n,i,o=parseInt(arguments[1])||0;for(o>=0?n=o:(n=e+o)<0&&(n=0);n<e;){if(r===(i=t[n])||r!=r&&i!=i)return!0;n++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Number.isFinite||(Number.isFinite=function(r){return"number"==typeof r&&isFinite(r)}),Number.isInteger||(Number.isInteger=function(r){return"number"==typeof r&&isFinite(r)&&Math.floor(r)===r}),Number.isNaN||(Number.isNaN=function(r){return"number"==typeof r&&r!=r});

View file

@ -419,7 +419,8 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
<!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script>
<script src="./src/kute.min.js"></script>
<!-- <script src="./src/kute.min.js"></script> -->
<script src="../dist/kute.js"></script>
<script src="./assets/js/prism.js"></script>
<script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgMorph.js"></script>

3347
dist/kute.esm.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

3347
dist/kute.js vendored

File diff suppressed because it is too large Load diff

4
dist/kute.min.js vendored

File diff suppressed because one or more lines are too long

55
dist/polyfill.js vendored
View file

@ -1,6 +1,6 @@
/*!
* KUTE.js Polyfill v2.0.14 (http://thednp.github.io/kute.js)
* Copyright 2015-2020 © thednp
* KUTE.js Polyfill v2.1.1-alpha1 (http://thednp.github.io/kute.js)
* Copyright 2015-2021 © thednp
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/
"use strict";
@ -21,7 +21,8 @@ if (!Array.from) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
return function from(arrayLike) {
return function from(arrayLike/*, mapFn, thisArg */) {
var C = this, items = Object(arrayLike);
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
@ -31,12 +32,14 @@ if (!Array.from) {
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
if (arguments.length > 2) {
T = arguments[2];
}
}
var len = toLength(items.length);
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
var k = 0;
var kValue;
while (k < len) {
@ -54,8 +57,30 @@ if (!Array.from) {
}());
}
// https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat () {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);
return depth ? Array.prototype.reduce.call(this, function (acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}
return acc;
}, []) : Array.prototype.slice.call(this);
},
writable: true
});
}
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement ) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
@ -91,3 +116,25 @@ if (!String.prototype.includes) {
return this.indexOf(search, start) !== -1;
};
}
if (!Number.isFinite) {
Number.isFinite = function(value) {
return typeof value === 'number'
&& isFinite(value);
};
}
if (!Number.isInteger) {
Number.isInteger = function(value) {
return typeof value === 'number'
&& isFinite(value)
&& Math.floor(value) === value;
};
}
if (!Number.isNaN) {
Number.isNaN = function(value) {
return typeof value === 'number'
&& value !== value;
};
}

View file

@ -1,3 +1,3 @@
// KUTE.js Polyfill v2.0.14 | 2020 © thednp | MIT-License
// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License
"use strict";
var r,t,n,e;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=Math.pow(2,53)-1,e=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),n)},function(r){var n=this,o=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var u,f=e(o.length),c=t(n)?Object(new n(f)):new Array(f),p=0;p<f;)u=o[p],c[p]=a?void 0===i?a(u,p):a.call(i,u,p):u,p+=1;return c.length=f,c})),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),n=parseInt(t.length)||0;if(0===n)return!1;var e,o,i=parseInt(arguments[1])||0;for(i>=0?e=i:(e=n+i)<0&&(e=0);e<n;){if(r===(o=t[e])||r!=r&&o!=o)return!0;e++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)});
var r,t,e,n;Array.from||(Array.from=(r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},e=Math.pow(2,53)-1,n=function(r){var t=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t}(r);return Math.min(Math.max(t,0),e)},function(r){var e=this,i=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!t(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var u,f=n(i.length),p=t(e)?Object(new e(f)):new Array(f),c=0;c<f;)u=i[c],p[c]=a?void 0===o?a(u,c):a.call(o,u,c):u,c+=1;return p.length=f,p})),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(e,n){return Array.isArray(n)?e.push.apply(e,r.call(n,t-1)):e.push(n),e}),[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.includes||(Array.prototype.includes=function(r){var t=Object(this),e=parseInt(t.length)||0;if(0===e)return!1;var n,i,o=parseInt(arguments[1])||0;for(o>=0?n=o:(n=e+o)<0&&(n=0);n<e;){if(r===(i=t[n])||r!=r&&i!=i)return!0;n++}return!1}),String.prototype.includes||(String.prototype.includes=function(r,t){if(r instanceof RegExp)throw TypeError("first argument must not be a RegExp");return void 0===t&&(t=0),-1!==this.indexOf(r,t)}),Number.isFinite||(Number.isFinite=function(r){return"number"==typeof r&&isFinite(r)}),Number.isInteger||(Number.isInteger=function(r){return"number"==typeof r&&isFinite(r)&&Math.floor(r)===r}),Number.isNaN||(Number.isNaN=function(r){return"number"==typeof r&&r!=r});

View file

@ -1,7 +1,7 @@
{
"name": "kute.js",
"version": "2.1.0",
"description": "JavaScript animation engine of the future is called KUTE.js.",
"version": "2.1.1-alpha1",
"description": "JavaScript animation engine",
"main": "dist/kute.min.js",
"module": "dist/kute.esm.js",
"jsnext": "src/index.js",
@ -13,8 +13,11 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"help": "rollup --help",
"build": "npm-run-all --parallel copy-build build-*",
"build1": "npm-run-all --parallel copy-build build-*",
"build": "npm run lint:js && npm-run-all --parallel copy-build build-*",
"custom": "rollup -c --environment",
"fix:js": "eslint src/ --config .eslintrc --fix",
"lint:js": "eslint src/ --config .eslintrc",
"copy-build": "rollup --environment OUTPUTFILE:demo/src/kute.min.js,DIST:standard,MIN:true,FORMAT:umd -c",
"build-standard": "rollup --environment DIST:standard,MIN:false,FORMAT:umd -c",
"build-standard-min": "rollup --environment DIST:standard,MIN:true,FORMAT:umd -c",
@ -54,18 +57,21 @@
},
"homepage": "http://thednp.github.io/kute.js",
"dependencies": {
"cubic-bezier-easing": "^1.0.2",
"minifill": "^0.0.14",
"shorter-js": "^0.1.7",
"svg-path-commander": "0.1.0"
"cubic-bezier-easing": "^1.0.3-alpha1",
"minifill": "^0.0.16",
"shorter-js": "^0.2.0-alpha1",
"svg-path-commander": "0.1.3-alpha4"
},
"devDependencies": {
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-vue": "^7.7.0",
"npm-run-all": "^4.1.5",
"rollup": "^2.36.1",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-terser": "^7.0.2"
}
}

View file

@ -2,7 +2,6 @@
import buble from '@rollup/plugin-buble'
import {terser} from 'rollup-plugin-terser'
import node from '@rollup/plugin-node-resolve'
import cleanup from 'rollup-plugin-cleanup'
import json from '@rollup/plugin-json'
import * as pkg from "./package.json"
@ -35,7 +34,6 @@ const PLUGINS = [
node({mainFields: ['jsnext','module'], dedupe: ['svg-path-commander']}) ,
json(),
buble(),
cleanup()
]
if (MIN){

View file

@ -3,7 +3,6 @@ import buble from '@rollup/plugin-buble'
import node from '@rollup/plugin-node-resolve'
import json from '@rollup/plugin-json'
import {terser} from 'rollup-plugin-terser'
import cleanup from 'rollup-plugin-cleanup'
import * as pkg from "./package.json";
// set headers
@ -34,7 +33,6 @@ const PLUGINS = [
node(),
json(),
buble(),
cleanup()
]
if (MIN){

View file

@ -1,14 +1,14 @@
import supportedProperties from '../objects/supportedProperties.js'
import defaultValues from '../objects/defaultValues.js'
import defaultOptions from '../objects/defaultOptions.js'
import prepareProperty from '../objects/prepareProperty.js'
import prepareStart from '../objects/prepareStart.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import crossCheck from '../objects/crossCheck.js'
import linkProperty from '../objects/linkProperty.js'
import Util from '../objects/util.js'
import Interpolate from '../objects/interpolate.js'
import supportedProperties from '../objects/supportedProperties.js';
import defaultValues from '../objects/defaultValues.js';
import defaultOptions from '../objects/defaultOptions.js';
import prepareProperty from '../objects/prepareProperty.js';
import prepareStart from '../objects/prepareStart.js';
import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js';
import crossCheck from '../objects/crossCheck.js';
import linkProperty from '../objects/linkProperty.js';
import Util from '../objects/util.js';
import Interpolate from '../objects/interpolate.js';
// Animation class
// * builds KUTE components
@ -16,101 +16,120 @@ import Interpolate from '../objects/interpolate.js'
// * AnimatonBase creates a KUTE.js build for pre-made Tween objects
// * AnimatonDevelopment can help you debug your new components
export default class Animation {
constructor(Component){
constructor(Component) {
try {
if ( Component.component in supportedProperties ) {
console.error(`KUTE.js - ${Component.component} already registered`);
} else if ( Component.property in defaultValues ) {
console.error(`KUTE.js - ${Component.property} already registered`);
if (Component.component in supportedProperties) {
throw Error(`KUTE.js - ${Component.component} already registered`);
} else if (Component.property in defaultValues) {
throw Error(`KUTE.js - ${Component.property} already registered`);
} else {
this.setComponent(Component)
this.setComponent(Component);
}
} catch(e){
console.error(e)
} catch (e) {
throw Error(e);
}
}
setComponent(Component){
const propertyInfo = this
const ComponentName = Component.component
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = { prepareProperty, prepareStart, onStart, onComplete, crossCheck }
const Category = Component.category
const Property = Component.property
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length
// {property,defaultvalue,defaultOptions,Interpolate,functions} // single property
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions} // category colors, boxModel, borderRadius
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg transform, filter
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg attr
setComponent(Component) {
const propertyInfo = this;
const ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
};
const Category = Component.category;
const Property = Component.property;
const Length = (Component.properties && Component.properties.length)
|| (Component.subProperties && Component.subProperties.length);
// single property
// {property,defaultvalue,defaultOptions,Interpolate,functions}
// category colors, boxModel, borderRadius
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg transform, filter
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg htmlAttributes
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate
defaultValues[ Property ] = Component.defaultValue
if ('defaultValue' in Component) { // value 0 will invalidate
defaultValues[Property] = Component.defaultValue;
// minimal info
propertyInfo.supports = `${Property} property`
propertyInfo.supports = `${Property} property`;
} else if (Component.defaultValues) {
for (const dv in Component.defaultValues) {
defaultValues[dv] = Component.defaultValues[dv]
}
Object.keys(Component.defaultValues).forEach((dv) => {
defaultValues[dv] = Component.defaultValues[dv];
});
// minimal info
propertyInfo.supports = `${Length||Property} ${Property||Category} properties`
propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
}
// set additional options
if (Component.defaultOptions) {
for (const op in Component.defaultOptions) {
defaultOptions[op] = Component.defaultOptions[op]
}
Object.keys(Component.defaultOptions).forEach((op) => {
defaultOptions[op] = Component.defaultOptions[op];
});
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
if (typeof (Component.functions[fn]) === 'function' ) {
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn])
} else {
for ( const ofn in Component.functions[fn] ){
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn])
if (typeof (Component.functions[fn]) === 'function') {
// if (!Functions[fn][ Category||Property ]) {
// Functions[fn][ Category||Property ] = Component.functions[fn];
// }
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][Category || Property]) {
Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
}
} else {
Object.keys(Component.functions[fn]).forEach((ofn) => {
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
}
}
}
});
}
// set component interpolate
if (Component.Interpolate) {
for (const fni in Component.Interpolate) {
const compIntObj = Component.Interpolate[fni]
if ( typeof(compIntObj) === 'function' && !Interpolate[fni] ) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
for ( const sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
}
});
}
}
linkProperty[ComponentName] = Component.Interpolate
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
for (const fnu in Component.Util){
!Util[fnu] && (Util[fnu] = Component.Util[fnu])
}
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
return propertyInfo
return propertyInfo;
}
}

View file

@ -1,76 +1,87 @@
import supportedProperties from '../objects/supportedProperties.js'
import defaultOptions from '../objects/defaultOptions.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import linkProperty from '../objects/linkProperty.js'
import Util from '../objects/util.js'
import Interpolate from '../objects/interpolate.js'
import supportedProperties from '../objects/supportedProperties.js';
import defaultOptions from '../objects/defaultOptions.js';
import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js';
import linkProperty from '../objects/linkProperty.js';
import Util from '../objects/util.js';
import Interpolate from '../objects/interpolate.js';
// Animation class
export default class AnimationBase {
constructor(Component){
return this.setComponent(Component)
constructor(Component) {
return this.setComponent(Component);
}
setComponent(Component){
const ComponentName = Component.component
setComponent(Component) {
const ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
const Functions = { onStart, onComplete }
const Category = Component.category
const Property = Component.property
const Functions = { onStart, onComplete };
const Category = Component.category;
const Property = Component.property;
// ESLint
this._ = 0;
// set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set additional options
if (Component.defaultOptions) {
for (const op in Component.defaultOptions) {
defaultOptions[op] = Component.defaultOptions[op]
}
Object.keys(Component.defaultOptions).forEach((op) => {
defaultOptions[op] = Component.defaultOptions[op];
});
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
if ( typeof (Component.functions[fn]) === 'function' ) {
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn])
} else {
for ( const ofn in Component.functions[fn] ){
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn])
if (typeof (Component.functions[fn]) === 'function') {
// if (!Functions[fn][ Category||Property ]) {
// Functions[fn][ Category||Property ] = Component.functions[fn];
// }
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][Category || Property]) {
Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
}
} else {
Object.keys(Component.functions[fn]).forEach((ofn) => {
// if (!Functions[fn][ofn]) Functions[fn][ofn] = Component.functions[fn][ofn];
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
}
}
}
});
}
// set interpolate
if (Component.Interpolate) {
for (const fni in Component.Interpolate) {
const compIntObj = Component.Interpolate[fni]
if ( typeof(compIntObj) === 'function' && !Interpolate[fni] ) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
for ( const sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
}
});
}
}
linkProperty[ComponentName] = Component.Interpolate
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
for (const fnu in Component.Util){
!Util[fnu] && (Util[fnu] = Component.Util[fnu])
}
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
return {name:ComponentName}
return { name: ComponentName };
}
}

View file

@ -1,103 +1,131 @@
import prepareProperty from '../objects/prepareProperty.js'
import prepareStart from '../objects/prepareStart.js'
import onStart from '../objects/onStart.js'
import onComplete from '../objects/onComplete.js'
import crossCheck from '../objects/crossCheck.js'
import Interpolate from '../objects/interpolate.js'
import prepareProperty from '../objects/prepareProperty.js';
import prepareStart from '../objects/prepareStart.js';
import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js';
import crossCheck from '../objects/crossCheck.js';
import Interpolate from '../objects/interpolate.js';
import Animation from './animation.js'
import Animation from './animation.js';
// AnimationDevelopment class
export default class AnimationDevelopment extends Animation {
constructor(...args){
super(...args)
}
setComponent(Component){
super.setComponent(Component)
constructor(...args) {
super(...args);
const propertyInfo = this
this.setComponent(...args);
}
setComponent(Component) {
super.setComponent(Component);
const propertyInfo = this;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = { prepareProperty,prepareStart,onStart,onComplete,crossCheck }
const Category = Component.category
const Property = Component.property
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length
const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
};
const Category = Component.category;
const Property = Component.property;
const Length = (Component.properties && Component.properties.length)
|| (Component.subProperties && Component.subProperties.length);
// set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate
propertyInfo.supports = `${Property} property`
propertyInfo.defaultValue = `${(Component.defaultValue+'').length?"YES":"not set or incorrect"}`
if ('defaultValue' in Component) { // value 0 will invalidate
propertyInfo.supports = `${Property} property`;
propertyInfo.defaultValue = `${(`${Component.defaultValue}`).length ? 'YES' : 'not set or incorrect'}`;
} else if (Component.defaultValues) {
propertyInfo.supports = `${Length||Property} ${Property||Category} properties`
propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? `YES` : `Not set or incomplete`
propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? 'YES' : 'Not set or incomplete';
}
// set additional options
if (Component.defaultOptions) {
propertyInfo.extends = []
propertyInfo.extends = [];
for (const op in Component.defaultOptions) {
propertyInfo.extends.push(op)
Object.keys(Component.defaultOptions).forEach((op) => {
propertyInfo.extends.push(op);
});
if (propertyInfo.extends.length) {
propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)`;
} else {
delete propertyInfo.extends;
}
propertyInfo.extends.length ? propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)` : delete propertyInfo.extends
}
// set functions
if (Component.functions) {
propertyInfo.interface = []
propertyInfo.render = []
propertyInfo.warning = []
for (const fnf in Functions) {
propertyInfo.interface = [];
propertyInfo.render = [];
propertyInfo.warning = [];
Object.keys(Functions).forEach((fnf) => {
if (fnf in Component.functions) {
fnf === 'prepareProperty' ? propertyInfo.interface.push(`fromTo()`) : 0
fnf === 'prepareStart' ? propertyInfo.interface.push(`to()`) : 0
fnf === 'onStart' ? propertyInfo.render = `can render update` : 0
if (fnf === 'prepareProperty') propertyInfo.interface.push('fromTo()');
if (fnf === 'prepareStart') propertyInfo.interface.push('to()');
if (fnf === 'onStart') propertyInfo.render = 'can render update';
} else {
fnf === 'prepareProperty' ? propertyInfo.warning.push(`fromTo()`) : 0
fnf === 'prepareStart' ? propertyInfo.warning.push(`to()`) : 0
fnf === 'onStart' ? propertyInfo.render = `no function to render update` : 0
if (fnf === 'prepareProperty') propertyInfo.warning.push('fromTo()');
if (fnf === 'prepareStart') propertyInfo.warning.push('to()');
if (fnf === 'onStart') propertyInfo.render = 'no function to render update';
}
});
if (propertyInfo.interface.length) {
propertyInfo.interface = `${Category || Property} can use [${propertyInfo.interface.join(', ')}] method(s)`;
} else {
delete propertyInfo.uses;
}
if (propertyInfo.warning.length) {
propertyInfo.warning = `${Category || Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed`;
} else {
delete propertyInfo.warning;
}
propertyInfo.interface.length ? propertyInfo.interface = `${Category||Property} can use [${propertyInfo.interface.join(', ')}] method(s)` : delete propertyInfo.uses
propertyInfo.warning.length ? propertyInfo.warning = `${Category||Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed` : delete propertyInfo.warning
}
// register Interpolation functions
if (Component.Interpolate) {
propertyInfo.uses = []
propertyInfo.adds = []
propertyInfo.uses = [];
propertyInfo.adds = [];
for (let fni in Component.Interpolate) {
let compIntObj = Component.Interpolate[fni]
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
// register new Interpolation functions
if ( typeof(compIntObj) === 'function' ) {
if ( !Interpolate[fni] ) {
propertyInfo.adds.push(`${fni}`)
if (typeof (compIntObj) === 'function') {
if (!Interpolate[fni]) {
propertyInfo.adds.push(`${fni}`);
}
propertyInfo.uses.push(`${fni}`)
propertyInfo.uses.push(`${fni}`);
} else {
for ( let sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) {
propertyInfo.adds.push(`${sfn}`)
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
propertyInfo.adds.push(`${sfn}`);
}
propertyInfo.uses.push(`${sfn}`)
}
propertyInfo.uses.push(`${sfn}`);
});
}
});
if (propertyInfo.uses.length) {
propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)`;
} else {
delete propertyInfo.uses;
}
propertyInfo.uses.length ? propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)` : delete propertyInfo.uses
propertyInfo.adds.length ? propertyInfo.adds = `new [${propertyInfo.adds.join(', ')}] interpolation function(s)` : delete propertyInfo.adds
if (propertyInfo.adds.length) {
propertyInfo.adds = `new [${propertyInfo.adds.join(', ')}] interpolation function(s)`;
} else {
delete propertyInfo.adds;
}
} else {
propertyInfo.critical = `For ${Property||Category} no interpolation function[s] is set`
propertyInfo.critical = `For ${Property || Category} no interpolation function[s] is set`;
}
// set component util
if (Component.Util) {
propertyInfo.hasUtil = Object.keys(Component.Util).join(',')
propertyInfo.hasUtil = Object.keys(Component.Util).join(',');
}
return propertyInfo
return propertyInfo;
}
}

View file

@ -1,46 +1,52 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import numbers from '../interpolation/numbers.js'
import trueDimension from '../util/trueDimension.js'
import {onStartBgPos} from './backgroundPositionBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import numbers from '../interpolation/numbers.js';
import trueDimension from '../util/trueDimension.js';
import { onStartBgPos } from './backgroundPositionBase.js';
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* bgPosProp = {
property: 'backgroundPosition',
defaultValue: [0,0],
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
function getBgPos(prop){
return getStyleForProperty(this.element,prop) || defaultValues[prop];
function getBgPos(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
function prepareBgPos(prop,value){
if ( value instanceof Array ){
const x = trueDimension(value[0]).v,
y = trueDimension(value[1]).v;
return [ x !== NaN ? x : 50, y !== NaN ? y : 50 ];
} else {
let posxy = value.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);
posxy = posxy.split(/(\,|\s)/g);
posxy = posxy.length === 2 ? posxy : [posxy[0],50];
return [ trueDimension(posxy[0]).v, trueDimension(posxy[1]).v ];
function prepareBgPos(prop, value) {
if (value instanceof Array) {
const x = trueDimension(value[0]).v;
const y = trueDimension(value[1]).v;
return [!Number.isNaN(x * 1) ? x : 50, !Number.isNaN(y * 1) ? y : 50];
}
let posxy = value.replace(/top|left/g, 0)
.replace(/right|bottom/g, 100)
.replace(/center|middle/g, 50);
posxy = posxy.split(/(,|\s)/g);
posxy = posxy.length === 2 ? posxy : [posxy[0], 50];
return [trueDimension(posxy[0]).v, trueDimension(posxy[1]).v];
}
// All Component Functions
const bgPositionFunctions = {
prepareStart: getBgPos,
prepareProperty: prepareBgPos,
onStart: onStartBgPos
}
onStart: onStartBgPos,
};
// Component Full Object
const BackgroundPosition = {
component: 'backgroundPositionProp',
property: 'backgroundPosition',
defaultValue: [50,50],
Interpolate: {numbers},
defaultValue: [50, 50],
Interpolate: { numbers },
functions: bgPositionFunctions,
Util: {trueDimension}
}
Util: { trueDimension },
};
export default BackgroundPosition
Components.BackgroundPosition = BackgroundPosition
export default BackgroundPosition;

View file

@ -1,14 +1,19 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* bgPosProp = {
property: 'backgroundPosition',
defaultValue: [0,0],
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
export function onStartBgPos(prop){
if ( this.valuesEnd[prop] && !KUTE[prop]) { // opacity could be 0
export function onStartBgPos(prop) {
if (this.valuesEnd[prop] && !KUTE[prop]) {
KUTE[prop] = (elem, a, b, v) => {
elem.style[prop] = `${(numbers(a[0],b[0],v)*100>>0)/100}% ${((numbers(a[1],b[1],v)*100>>0)/100)}%`;
}
elem.style[prop] = `${(numbers(a[0], b[0], v) * 100 >> 0) / 100}% ${((numbers(a[1], b[1], v) * 100 >> 0) / 100)}%`;
};
}
}
@ -16,7 +21,7 @@ export function onStartBgPos(prop){
const baseBgPosOps = {
component: 'baseBackgroundPosition',
property: 'backgroundPosition',
Interpolate: {numbers},
functions: {onStart: onStartBgPos}
}
export default baseBgPosOps
Interpolate: { numbers },
functions: { onStart: onStartBgPos },
};
export default baseBgPosOps;

View file

@ -1,27 +1,34 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import units from '../interpolation/units.js'
import {radiusOnStartFn} from './borderRadiusBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueDimension from '../util/trueDimension.js';
import units from '../interpolation/units.js';
import { radiusOnStartFn } from './borderRadiusBase.js';
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
/* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
const radiusValues = {}
const radiusProps = ['borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
radiusProps.map(x => radiusValues[x] = 0);
const radiusValues = {};
radiusProps.forEach((x) => { radiusValues[x] = 0; });
// Component Functions
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
export function getRadius(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
export function getRadius(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
export function prepareRadius(tweenProp,value){
export function prepareRadius(tweenProp, value) {
return trueDimension(value);
}
@ -29,8 +36,8 @@ export function prepareRadius(tweenProp,value){
export const radiusFunctions = {
prepareStart: getRadius,
prepareProperty: prepareRadius,
onStart: radiusOnStart
}
onStart: radiusOnStart,
};
// Full Component
const BorderRadius = {
@ -38,11 +45,9 @@ const BorderRadius = {
category: 'borderRadius',
properties: radiusProps,
defaultValues: radiusValues,
Interpolate: {units},
Interpolate: { units },
functions: radiusFunctions,
Util: {trueDimension}
}
Util: { trueDimension },
};
export default BorderRadius
Components.BorderRadiusProperties = BorderRadius
export default BorderRadius;

View file

@ -1,29 +1,35 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js';
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
/* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
const radiusProps = ['borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
// Component Functions
export function radiusOnStartFn(tweenProp){
export function radiusOnStartFn(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = units(a.v,b.v,b.u,v);
}
elem.style[tweenProp] = units(a.v, b.v, b.u, v);
};
}
}
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
// Base Component
const baseBorderRadius = {
component: 'baseBorderRadius',
category: 'borderRadius',
Interpolate: {units},
functions: {onStart: radiusOnStart}
}
export default baseBorderRadius
Interpolate: { units },
functions: { onStart: radiusOnStart },
};
export default baseBorderRadius;

View file

@ -1,35 +1,36 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {boxModelOnStart} from './boxModelBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueDimension from '../util/trueDimension.js';
import numbers from '../interpolation/numbers.js';
import { boxModelOnStart } from './boxModelBase.js';
// Component Properties
const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
'padding', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight',
'margin', 'marginTop','marginBottom', 'marginLeft', 'marginRight',
'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth']
const boxModelValues = {}
boxModelProperties.map(x => boxModelValues[x] = 0);
'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight',
'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth'];
const boxModelValues = {};
boxModelProperties.forEach((x) => { boxModelValues[x] = 0; });
// Component Functions
function getBoxModel(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
function getBoxModel(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
function prepareBoxModel(tweenProp,value){
const boxValue = trueDimension(value), offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v;
function prepareBoxModel(tweenProp, value) {
const boxValue = trueDimension(value); const
offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v;
}
const boxPropsOnStart = {}
boxModelProperties.map(x => boxPropsOnStart[x] = boxModelOnStart );
const boxPropsOnStart = {};
boxModelProperties.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; });
// All Component Functions
const boxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart
}
onStart: boxPropsOnStart,
};
// Component Full Component
const boxModel = {
@ -37,10 +38,8 @@ const boxModel = {
category: 'boxModel',
properties: boxModelProperties,
defaultValues: boxModelValues,
Interpolate: {numbers},
functions: boxModelFunctions
}
Interpolate: { numbers },
functions: boxModelFunctions,
};
export default boxModel
Components.BoxModelProperties = boxModel
export default boxModel;

View file

@ -1,28 +1,29 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// Component Functions
export function boxModelOnStart(tweenProp){
export function boxModelOnStart(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = `${v > 0.99 || v < 0.01 ? ((numbers(a,b,v)*10)>>0)/10 : (numbers(a,b,v) ) >> 0}px`;
// elem.style[tweenProp] = `${(numbers(a,b,v) ) >> 0}px`;
}
elem.style[tweenProp] = `${v > 0.99 || v < 0.01
? ((numbers(a, b, v) * 10) >> 0) / 10
: (numbers(a, b, v)) >> 0}px`;
};
}
}
// Component Base Props
const baseBoxProps = ['top','left','width','height']
const baseBoxOnStart = {}
baseBoxProps.map(x=>baseBoxOnStart[x] = boxModelOnStart)
const baseBoxProps = ['top', 'left', 'width', 'height'];
const baseBoxOnStart = {};
baseBoxProps.forEach((x) => { baseBoxOnStart[x] = boxModelOnStart; });
// Component Base
const baseBoxModel = {
component: 'baseBoxModel',
category: 'boxModel',
properties: baseBoxProps,
Interpolate: {numbers},
functions: {onStart: baseBoxOnStart}
}
Interpolate: { numbers },
functions: { onStart: baseBoxOnStart },
};
export default baseBoxModel
export default baseBoxModel;

View file

@ -1,32 +1,34 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {boxModelOnStart} from './boxModelBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueDimension from '../util/trueDimension.js';
import numbers from '../interpolation/numbers.js';
import { boxModelOnStart } from './boxModelBase.js';
// Component Functions
function getBoxModel(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
function getBoxModel(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
function prepareBoxModel(tweenProp,value){
const boxValue = trueDimension(value), offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v;
function prepareBoxModel(tweenProp, value) {
const boxValue = trueDimension(value);
const offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v;
}
// Component Base Props
const essentialBoxProps = ['top','left','width','height']
const essentialBoxPropsValues = {top:0,left:0,width:0,height:0}
const essentialBoxOnStart = {}
essentialBoxProps.map(x=>essentialBoxOnStart[x] = boxModelOnStart)
const essentialBoxProps = ['top', 'left', 'width', 'height'];
const essentialBoxPropsValues = {
top: 0, left: 0, width: 0, height: 0,
};
const essentialBoxOnStart = {};
essentialBoxProps.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; });
// All Component Functions
const essentialBoxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart
}
onStart: essentialBoxOnStart,
};
// Component Essential
const essentialBoxModel = {
@ -34,11 +36,9 @@ const essentialBoxModel = {
category: 'boxModel',
properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues,
Interpolate: {numbers},
Interpolate: { numbers },
functions: essentialBoxModelFunctions,
Util:{trueDimension}
}
Util: { trueDimension },
};
export default essentialBoxModel
Components.BoxModelEssential = essentialBoxModel
export default essentialBoxModel;

View file

@ -1,43 +1,39 @@
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import {onStartClip} from './clipPropertyBase.js'
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueDimension from '../util/trueDimension.js';
import numbers from '../interpolation/numbers.js';
import { onStartClip } from './clipPropertyBase.js';
// Component Functions
function getClip(tweenProp,v){
const currentClip = getStyleForProperty(this.element,tweenProp),
width = getStyleForProperty(this.element,'width'),
height = getStyleForProperty(this.element,'height');
function getClip(tweenProp/* , value */) {
const currentClip = getStyleForProperty(this.element, tweenProp);
const width = getStyleForProperty(this.element, 'width');
const height = getStyleForProperty(this.element, 'height');
return !/rect/.test(currentClip) ? [0, width, height, 0] : currentClip;
}
function prepareClip(tweenProp,value) {
if ( value instanceof Array ){
return [ trueDimension(value[0]), trueDimension(value[1]), trueDimension(value[2]), trueDimension(value[3]) ];
} else {
var clipValue = value.replace(/rect|\(|\)/g,'');
clipValue = /\,/g.test(clipValue) ? clipValue.split(/\,/g) : clipValue.split(/\s/g);
return [ trueDimension(clipValue[0]), trueDimension(clipValue[1]), trueDimension(clipValue[2]), trueDimension(clipValue[3]) ];
function prepareClip(tweenProp, value) {
if (value instanceof Array) {
return value.map((x) => trueDimension(x));
}
let clipValue = value.replace(/rect|\(|\)/g, '');
clipValue = /,/g.test(clipValue) ? clipValue.split(',') : clipValue.split(/\s/);
return clipValue.map((x) => trueDimension(x));
}
// All Component Functions
const clipFunctions = {
prepareStart: getClip,
prepareProperty: prepareClip,
onStart: onStartClip
}
onStart: onStartClip,
};
// Component Full
const clipProperty = {
const clipProperty = {
component: 'clipProperty',
property: 'clip',
defaultValue: [0,0,0,0],
Interpolate: {numbers},
defaultValue: [0, 0, 0, 0],
Interpolate: { numbers },
functions: clipFunctions,
Util: {trueDimension}
}
Util: { trueDimension },
};
export default clipProperty
Components.ClipProperty = clipProperty
export default clipProperty;

View file

@ -1,17 +1,19 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// Component Functions
export function onStartClip(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
var h = 0, cl = [];
for (h;h<4;h++){
var c1 = a[h].v, c2 = b[h].v, cu = b[h].u || 'px';
cl[h] = ((numbers(c1,c2,v)*100 >> 0)/100) + cu;
let h = 0; const
cl = [];
for (h; h < 4; h += 1) {
const c1 = a[h].v; const c2 = b[h].v; const
cu = b[h].u || 'px';
cl[h] = ((numbers(c1, c2, v) * 100 >> 0) / 100) + cu;
}
elem.style.clip = `rect(${cl})`;
}
};
}
}
@ -20,8 +22,8 @@ const baseClip = {
component: 'baseClip',
property: 'clip',
// defaultValue: [0,0,0,0],
Interpolate: {numbers},
functions: {onStart:onStartClip}
}
Interpolate: { numbers },
functions: { onStart: onStartClip },
};
export default baseClip
export default baseClip;

View file

@ -1,30 +1,31 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {onStartColors} from './colorPropertiesBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueColor from '../util/trueColor.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
import { onStartColors } from './colorPropertiesBase.js';
// Component Interpolation
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = ['color', 'backgroundColor','borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor']
const defaultColors = {}
const supportedColors = ['color', 'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'];
supportedColors.map(tweenProp => {
defaultColors[tweenProp] = '#000'
const defaultColors = {};
supportedColors.forEach((tweenProp) => {
defaultColors[tweenProp] = '#000';
});
// Component Functions
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
const colorsOnStart = {};
supportedColors.forEach((x) => {
colorsOnStart[x] = onStartColors;
});
function getColor(prop,value) {
return getStyleForProperty(this.element,prop) || defaultValues[prop];
function getColor(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
function prepareColor(prop,value) {
function prepareColor(prop, value) {
return trueColor(value);
}
@ -32,8 +33,8 @@ function prepareColor(prop,value) {
const colorFunctions = {
prepareStart: getColor,
prepareProperty: prepareColor,
onStart: colorsOnStart
}
onStart: colorsOnStart,
};
// Component Full
const colorProperties = {
@ -41,11 +42,9 @@ const colorProperties = {
category: 'colors',
properties: supportedColors,
defaultValues: defaultColors,
Interpolate: {numbers,colors},
Interpolate: { numbers, colors },
functions: colorFunctions,
Util: {trueColor}
}
Util: { trueColor },
};
export default colorProperties
Components.ColorProperties = colorProperties
export default colorProperties;

View file

@ -1,26 +1,27 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// Component Interpolation
// rgba1, rgba2, progress
// Component Properties
// supported formats
// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+)
const supportedColors = ['color', 'backgroundColor','borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor']
const supportedColors = ['color', 'backgroundColor', 'borderColor',
'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'];
// Component Functions
export function onStartColors(tweenProp){
export function onStartColors(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = colors(a,b,v);
}
elem.style[tweenProp] = colors(a, b, v);
};
}
}
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
const colorsOnStart = {};
supportedColors.forEach((x) => { colorsOnStart[x] = onStartColors; });
// Component Base
export const baseColors = {
@ -28,8 +29,8 @@ export const baseColors = {
category: 'colors',
// properties: supportedColors,
// defaultValues: defaultColors,
Interpolate: {numbers,colors},
functions: {onStart:colorsOnStart}
}
Interpolate: { numbers, colors },
functions: { onStart: colorsOnStart },
};
export default baseColors
export default baseColors;

View file

@ -1,50 +1,52 @@
import KUTE from '../objects/kute.js'
import getInlineStyle from '../process/getInlineStyle.js'
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import trueProperty from '../util/trueProperty.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import getInlineStyle from '../process/getInlineStyle.js';
import defaultValues from '../objects/defaultValues.js';
import trueProperty from '../util/trueProperty.js';
import numbers from '../interpolation/numbers.js';
// Component Const
const transformProperty = trueProperty('transform');
const supportTransform = transformProperty in document.body.style ? 1 : 0;
// Component Functions
function getComponentCurrentValue(tweenProp,value){
let currentTransform = getInlineStyle(this.element);
let left = this.element.style.left;
let top = this.element.style.top;
let x = supportTransform && currentTransform.translate ? currentTransform.translate[0]
: isFinite(left*1) ? left
: defaultValues.move[0];
let y = supportTransform && currentTransform.translate ? currentTransform.translate[1]
: isFinite(top*1) ? top
: defaultValues.move[1];
return [x,y]
}
function prepareComponentValue(tweenProp,value){
let x = isFinite(value*1) ? parseInt(value) : parseInt(value[0]) || 0;
let y = parseInt(value[1]) || 0;
function getComponentCurrentValue(/* tweenProp, value */) {
const currentTransform = getInlineStyle(this.element);
const { left } = this.element.style;
const { top } = this.element.style;
let x = 0;
let y = 0;
return [ x, y ]
if (supportTransform && currentTransform.translate) {
[x, y] = currentTransform.translate;
} else {
x = Number.isFinite(left * 1) ? left : defaultValues.move[0];
y = Number.isFinite(top * 1) ? top : defaultValues.move[1];
}
return [x, y];
}
function prepareComponentValue(tweenProp, value) {
const x = Number.isFinite(value * 1) ? parseInt(value, 10) : parseInt(value[0], 10) || 0;
const y = parseInt(value[1], 10) || 0;
return [x, y];
}
export function onStartComponent(tweenProp,value){
export function onStartComponent(tweenProp/* , value */) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
if (supportTransform){
if (supportTransform) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] = 'translate('+numbers(a[0],b[0],v)+'px,'+numbers(a[1],b[1],v)+'px)';
}
elem.style[transformProperty] = `translate(${numbers(a[0], b[0], v)}px,${numbers(a[1], b[1], v)}px)`;
};
} else {
KUTE[tweenProp] = (elem, a, b, v) => {
if (a[0]||b[0]) {
elem.style.left = numbers(a[0],b[0],v)+'px';
if (a[0] || b[0]) {
elem.style.left = `${numbers(a[0], b[0], v)}px`;
}
if (a[1]||b[1]) {
elem.style.top = numbers(a[1],b[1],v)+'px';
if (a[1] || b[1]) {
elem.style.top = `${numbers(a[1], b[1], v)}px`;
}
}
};
}
}
}
@ -53,27 +55,25 @@ export function onStartComponent(tweenProp,value){
const componentFunctions = {
prepareStart: getComponentCurrentValue,
prepareProperty: prepareComponentValue,
onStart: onStartComponent
}
onStart: onStartComponent,
};
// Base Component
export const baseCrossBrowserMove = {
component: 'baseCrossBrowserMove',
property: 'move',
Interpolate: {numbers},
functions: {onStart:onStartComponent}
}
Interpolate: { numbers },
functions: { onStart: onStartComponent },
};
// Full Component
const crossBrowserMove = {
component: 'crossBrowserMove',
property: 'move',
defaultValue: [0,0],
Interpolate: {numbers},
defaultValue: [0, 0],
Interpolate: { numbers },
functions: componentFunctions,
Util: {trueProperty}
}
Util: { trueProperty },
};
export default crossBrowserMove
Components.CrossBrowserMove = crossBrowserMove
export default crossBrowserMove;

View file

@ -1,29 +1,34 @@
import getStyleForProperty from '../process/getStyleForProperty.js'
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {dropShadow,onStartFilter} from './filterEffectsBase.js'
import getStyleForProperty from '../process/getStyleForProperty.js';
import defaultValues from '../objects/defaultValues.js';
import trueColor from '../util/trueColor.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
import { dropShadow, onStartFilter } from './filterEffectsBase.js';
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* filterEffects = {
property: 'filter',
subProperties: {},
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Util
function replaceDashNamespace(str){
return str.replace('-r','R').replace('-s','S')
function replaceDashNamespace(str) {
return str.replace('-r', 'R').replace('-s', 'S');
}
function parseDropShadow (shadow){
let newShadow
function parseDropShadow(shadow) {
let newShadow;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
newShadow = [shadow[0], shadow[1], 0, shadow[2] ];
newShadow = [shadow[0], shadow[1], 0, shadow[2]];
} else if (shadow.length === 4) { // ideal [<offset-x>, <offset-y>, <blur-radius>, <color>]
newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]];
}
// make sure the values are ready to tween
for (let i=0;i<3;i++){
for (let i = 0; i < 3; i += 1) {
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
@ -31,71 +36,85 @@ function parseDropShadow (shadow){
return newShadow;
}
function parseFilterString(currentStyle){
let result = {}
let fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g
let matches = currentStyle.match(fnReg);
const fnArray = currentStyle !== 'none' ? matches : 'none'
function parseFilterString(currentStyle) {
const result = {};
const fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g;
const matches = currentStyle.match(fnReg);
const fnArray = currentStyle !== 'none' ? matches : 'none';
if (fnArray instanceof Array) {
for (let j=0, jl = fnArray.length; j<jl; j++){
let p = fnArray[j].trim().split(/\((.+)/);
let pp = replaceDashNamespace(p[0]);
if ( pp === 'dropShadow' ) {
let shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0]
let params = p[1].replace(shadowColor,'').split(/\s/).map(parseFloat)
result[pp] = params.filter((el)=>!isNaN(el)).concat(shadowColor);
for (let j = 0, jl = fnArray.length; j < jl; j += 1) {
const p = fnArray[j].trim().split(/\((.+)/);
const pp = replaceDashNamespace(p[0]);
if (pp === 'dropShadow') {
const shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0];
const params = p[1].replace(shadowColor, '').split(/\s/).map(parseFloat);
result[pp] = params.filter((el) => !Number.isNaN(el)).concat(shadowColor);
} else {
result[pp] = p[1].replace(/\'|\"|\)/g,'');
result[pp] = p[1].replace(/'|"|\)/g, '');
}
}
}
return result
return result;
}
// Component Functions
function getFilter(tweenProp,value) {
let currentStyle = getStyleForProperty(this.element,tweenProp),
filterObject = parseFilterString(currentStyle), fnp
function getFilter(tweenProp, value) {
const currentStyle = getStyleForProperty(this.element, tweenProp);
const filterObject = parseFilterString(currentStyle);
let fnp;
for (let fn in value){
fnp = replaceDashNamespace(fn)
if ( !filterObject[fnp] ){
filterObject[fnp] = defaultValues[tweenProp][fn]
Object.keys(value).forEach((fn) => {
fnp = replaceDashNamespace(fn);
if (!filterObject[fnp]) {
filterObject[fnp] = defaultValues[tweenProp][fn];
}
}
});
return filterObject;
}
function prepareFilter(tweenProp,value) {
let filterObject = {}, fnp
function prepareFilter(tweenProp, value) {
const filterObject = {};
let fnp;
// {opacity: [0-100%], blur: [0-Nem], saturate: [0-N%], invert: 0, grayscale: [0-100%], brightness: [0-N%], contrast: [0-N%], sepia: [0-N%], 'hueRotate': [0-Ndeg], 'dropShadow': [0,0,0,(r:0,g:0,b:0)], url:''},
// {opacity: 100, blur: 0, saturate: 100, invert: 0, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, 'hueRotate':0, 'dropShadow': 0, url:''},
// property: range | default
// opacity: [0-100%] | 100
// blur: [0-Nem] | 0
// saturate: [0-N%] | 100
// invert: [0-100%] | 0
// grayscale: [0-100%] | 0
// brightness: [0-N%] | 100
// contrast: [0-N%] | 100
// sepia: [0-N%] | 0
// 'hueRotate': [0-Ndeg] | 0
// 'dropShadow': [0,0,0,(r:0,g:0,b:0)] | 0
// url: '' | ''
for (let fn in value){
fnp = replaceDashNamespace(fn)
if ( /hue/.test(fn) ) {
filterObject[fnp] = parseFloat(value[fn])
} else if ( /drop/.test(fn) ) {
filterObject[fnp] = parseDropShadow(value[fn])
} else if ( fn === 'url' ) {
filterObject[fn] = value[fn]
Object.keys(value).forEach((fn) => {
fnp = replaceDashNamespace(fn);
if (/hue/.test(fn)) {
filterObject[fnp] = parseFloat(value[fn]);
} else if (/drop/.test(fn)) {
filterObject[fnp] = parseDropShadow(value[fn]);
} else if (fn === 'url') {
filterObject[fn] = value[fn];
// } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) {
} else {
filterObject[fn] = parseFloat(value[fn])
filterObject[fn] = parseFloat(value[fn]);
}
}
});
return filterObject;
}
function crossCheckFilter(tweenProp){
if ( this.valuesEnd[tweenProp] ) {
for (const fn in this.valuesStart[tweenProp]){
if (!this.valuesEnd[tweenProp][fn]){
this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn]
function crossCheckFilter(tweenProp) {
if (this.valuesEnd[tweenProp]) {
Object.keys(this.valuesStart[tweenProp]).forEach((fn) => {
if (!this.valuesEnd[tweenProp][fn]) {
this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn];
}
}
});
}
}
@ -104,15 +123,31 @@ const filterFunctions = {
prepareStart: getFilter,
prepareProperty: prepareFilter,
onStart: onStartFilter,
crossCheck: crossCheckFilter
}
crossCheck: crossCheckFilter,
};
// Full Component
const filterEffects = {
component: 'filterEffects',
property: 'filter',
// subProperties: ['blur', 'brightness','contrast','dropShadow','hueRotate','grayscale','invert','opacity','saturate','sepia','url'], // opacity function interfere with opacityProperty
defaultValue: {opacity: 100, blur: 0, saturate: 100, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0, dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''},
// opacity function interfere with opacityProperty
// subProperties: [
// 'blur', 'brightness','contrast','dropShadow',
// 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'
// ],
defaultValue: {
opacity: 100,
blur: 0,
saturate: 100,
grayscale: 0,
brightness: 100,
contrast: 100,
sepia: 0,
invert: 0,
hueRotate: 0,
dropShadow: [0, 0, 0, { r: 0, g: 0, b: 0 }],
url: '',
},
Interpolate: {
opacity: numbers,
blur: numbers,
@ -123,12 +158,12 @@ const filterEffects = {
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
dropShadow: { numbers, colors, dropShadow },
},
functions: filterFunctions,
Util: {parseDropShadow,parseFilterString,replaceDashNamespace,trueColor}
}
Util: {
parseDropShadow, parseFilterString, replaceDashNamespace, trueColor,
},
};
export default filterEffects
Components.FilterEffects = filterEffects
export default filterEffects;

View file

@ -1,44 +1,56 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* filterEffects = {
property: 'filter',
subProperties: {},
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Interpolation
export function dropShadow(a,b,v){
let params = [], unit = 'px'
export function dropShadow(a, b, v) {
const params = [];
const unit = 'px';
for (let i=0; i<3; i++){
params[i] = ((numbers(a[i],b[i],v) * 100 >>0) /100) + unit
for (let i = 0; i < 3; i += 1) {
params[i] = ((numbers(a[i], b[i], v) * 100 >> 0) / 100) + unit;
}
return `drop-shadow(${params.concat( colors(a[3],b[3],v) ).join(' ') })`
return `drop-shadow(${params.concat(colors(a[3], b[3], v)).join(' ')})`;
}
// Component Functions
export function onStartFilter(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = (b.url ? `url(${b.url})` : '')
+ (a.opacity||b.opacity ? `opacity(${((numbers(a.opacity,b.opacity,v) * 100)>>0)/100}%)` : '')
+ (a.blur||b.blur ? `blur(${((numbers(a.blur,b.blur,v) * 100)>>0)/100}em)` : '')
+ (a.saturate||b.saturate ? `saturate(${((numbers(a.saturate,b.saturate,v) * 100)>>0)/100}%)` : '')
+ (a.invert||b.invert ? `invert(${((numbers(a.invert,b.invert,v) * 100)>>0)/100}%)` : '')
+ (a.grayscale||b.grayscale ? `grayscale(${((numbers(a.grayscale,b.grayscale,v) * 100)>>0)/100}%)` : '')
+ (a.hueRotate||b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate,b.hueRotate,v) * 100)>>0)/100 }deg)` : '')
+ (a.sepia||b.sepia ? `sepia(${((numbers(a.sepia,b.sepia,v) * 100)>>0)/100 }%)` : '')
+ (a.brightness||b.brightness ? `brightness(${((numbers(a.brightness,b.brightness,v) * 100)>>0)/100 }%)` : '')
+ (a.contrast||b.contrast ? `contrast(${((numbers(a.contrast,b.contrast,v) * 100)>>0)/100 }%)` : '')
+ (a.dropShadow||b.dropShadow ? dropShadow(a.dropShadow,b.dropShadow,v) : '')
}
elem.style[tweenProp] = (b.url ? `url(${b.url})` : '')
+ (a.opacity || b.opacity ? `opacity(${((numbers(a.opacity, b.opacity, v) * 100) >> 0) / 100}%)` : '')
+ (a.blur || b.blur ? `blur(${((numbers(a.blur, b.blur, v) * 100) >> 0) / 100}em)` : '')
+ (a.saturate || b.saturate ? `saturate(${((numbers(a.saturate, b.saturate, v) * 100) >> 0) / 100}%)` : '')
+ (a.invert || b.invert ? `invert(${((numbers(a.invert, b.invert, v) * 100) >> 0) / 100}%)` : '')
+ (a.grayscale || b.grayscale ? `grayscale(${((numbers(a.grayscale, b.grayscale, v) * 100) >> 0) / 100}%)` : '')
+ (a.hueRotate || b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate, b.hueRotate, v) * 100) >> 0) / 100}deg)` : '')
+ (a.sepia || b.sepia ? `sepia(${((numbers(a.sepia, b.sepia, v) * 100) >> 0) / 100}%)` : '')
+ (a.brightness || b.brightness ? `brightness(${((numbers(a.brightness, b.brightness, v) * 100) >> 0) / 100}%)` : '')
+ (a.contrast || b.contrast ? `contrast(${((numbers(a.contrast, b.contrast, v) * 100) >> 0) / 100}%)` : '')
+ (a.dropShadow || b.dropShadow ? dropShadow(a.dropShadow, b.dropShadow, v) : '');
};
}
}
// Base Component
const baseFilter = {
component: 'baseFilter',
property: 'filter',
// subProperties: ['blur', 'brightness','contrast','dropShadow','hueRotate','grayscale','invert','opacity','saturate','sepia','url'], // opacity function interfere with opacityProperty
// defaultValue: {opacity: 100, blur: 0, saturate: 100, grayscale: 0, brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0, dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''},
// opacity function interfere with opacityProperty
// subProperties: ['blur', 'brightness','contrast','dropShadow',
// 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'],
// defaultValue: {
// opacity: 100, blur: 0, saturate: 100, grayscale: 0,
// brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0,
// dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''
// },
Interpolate: {
opacity: numbers,
blur: numbers,
@ -49,9 +61,9 @@ const baseFilter = {
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
dropShadow: { numbers, colors, dropShadow },
},
functions: {onStart:onStartFilter}
}
functions: { onStart: onStartFilter },
};
export default baseFilter
export default baseFilter;

View file

@ -1,71 +1,84 @@
import defaultValues from '../objects/defaultValues.js'
import onStart from '../objects/onStart.js'
import Components from '../objects/components.js'
import trueColor from '../util/trueColor.js'
import trueDimension from '../util/trueDimension.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {attributes,onStartAttr} from './htmlAttributesBase.js'
import defaultValues from '../objects/defaultValues.js';
import onStart from '../objects/onStart.js';
import trueColor from '../util/trueColor.js';
import trueDimension from '../util/trueDimension.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
import { attributes, onStartAttr } from './htmlAttributesBase.js';
// Component Name
let ComponentName = 'htmlAttributes'
const ComponentName = 'htmlAttributes';
// Component Properties
const svgColors = ['fill','stroke','stop-color'];
const svgColors = ['fill', 'stroke', 'stop-color'];
// Component Util
function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); }
function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); }
// Component Functions
export function getAttr(tweenProp,value){
let attrStartValues = {};
for (let attr in value){
let attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px'
currentValue = this.element.getAttribute(attribute);
attrStartValues[attribute] = svgColors.includes(attribute) ? (currentValue || 'rgba(0,0,0,0)') : (currentValue || (/opacity/i.test(attr) ? 1 : 0));
}
export function getAttr(tweenProp, value) {
const attrStartValues = {};
Object.keys(value).forEach((attr) => {
// get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px'
const attribute = replaceUppercase(attr).replace(/_+[a-z]+/, '');
const currentValue = this.element.getAttribute(attribute);
attrStartValues[attribute] = svgColors.includes(attribute)
? (currentValue || 'rgba(0,0,0,0)')
: (currentValue || (/opacity/i.test(attr) ? 1 : 0));
});
return attrStartValues;
}
export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object)
let attributesObject = {};
for ( let p in attrObj ) {
let prop = replaceUppercase(p),
regex = /(%|[a-z]+)$/,
currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,''));
if ( !svgColors.includes(prop)) {
if ( currentValue !== null && regex.test(currentValue) ) { // attributes set with unit suffixes
let unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u,
suffix = /%/.test(unit) ? '_percent' : `_${unit}`;
onStart[ComponentName][prop+suffix] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
attributes[tp] = (elem, p, a, b, v) => {
let _p = p.replace(suffix,'');
elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u );
}
}
}
attributesObject[prop+suffix] = trueDimension(attrObj[p]);
} else if ( !regex.test(attrObj[p]) || currentValue === null || currentValue !== null && !regex.test(currentValue) ) {
onStart[ComponentName][prop] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
export function prepareAttr(tweenProp, attrObj) { // attr (string),attrObj (object)
const attributesObject = {};
Object.keys(attrObj).forEach((p) => {
const prop = replaceUppercase(p);
const regex = /(%|[a-z]+)$/;
const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/, ''));
if (!svgColors.includes(prop)) {
// attributes set with unit suffixes
if (currentValue !== null && regex.test(currentValue)) {
const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u;
const suffix = /%/.test(unit) ? '_percent' : `_${unit}`;
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop + suffix] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, (numbers(a,b,v) * 1000 >> 0) / 1000 );
}
const _p = oneAttr.replace(suffix, '');
elem.setAttribute(_p, ((numbers(a.v, b.v, v) * 1000 >> 0) / 1000) + b.u);
};
}
}
};
attributesObject[prop + suffix] = trueDimension(attrObj[p]);
} else if (!regex.test(attrObj[p]) || currentValue === null
|| (currentValue !== null && !regex.test(currentValue))) {
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000);
};
}
};
attributesObject[prop] = parseFloat(attrObj[p]);
}
} else { // colors
onStart[ComponentName][prop] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
// most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop] = (tp) => {
if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, colors(a,b,v));
}
elem.setAttribute(oneAttr, colors(a, b, v));
};
}
}
};
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
}
}
});
return attributesObject;
}
@ -73,21 +86,27 @@ export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object
const attrFunctions = {
prepareStart: getAttr,
prepareProperty: prepareAttr,
onStart: onStartAttr
}
onStart: onStartAttr,
};
// Component Full
const htmlAttributes = {
component: ComponentName,
property: 'attr',
subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], // the Animation class will need some values to validate this Object attribute
defaultValue: {fill : 'rgb(0,0,0)', stroke: 'rgb(0,0,0)', 'stop-color': 'rgb(0,0,0)', opacity: 1, 'stroke-opacity': 1,'fill-opacity': 1}, // same here
Interpolate: { numbers,colors },
// the Animation class will need some values to validate this Object attribute
subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'],
defaultValue: {
fill: 'rgb(0,0,0)',
stroke: 'rgb(0,0,0)',
'stop-color': 'rgb(0,0,0)',
opacity: 1,
'stroke-opacity': 1,
'fill-opacity': 1, // same here
},
Interpolate: { numbers, colors },
functions: attrFunctions,
// export to global for faster execution
Util: { replaceUppercase, trueColor, trueDimension }
}
Util: { replaceUppercase, trueColor, trueDimension },
};
export default htmlAttributes
Components.HTMLAttributes = htmlAttributes
export default htmlAttributes;

View file

@ -1,39 +1,47 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// Component Name
let ComponentName = 'baseHTMLAttributes'
const ComponentName = 'baseHTMLAttributes';
// Component Special
let attributes = {};
export {attributes}
const attributes = {};
export { attributes };
export const onStartAttr = {
attr : function(tweenProp){
attr(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, vS, vE, v) => {
for ( const oneAttr in vE ){
KUTE.attributes[oneAttr](elem,oneAttr,vS[oneAttr],vE[oneAttr],v);
}
}
Object.keys(vE).forEach((oneAttr) => {
KUTE.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v);
});
};
}
},
attributes : function(tweenProp){
attributes(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd.attr) {
KUTE[tweenProp] = attributes
KUTE[tweenProp] = attributes;
}
}
}
},
};
// Component Base
const baseAttributes = {
component: ComponentName,
property: 'attr',
// subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], // the Animation class will need some values to validate this Object attribute
// defaultValue: {fill : 'rgb(0,0,0)', stroke: 'rgb(0,0,0)', 'stop-color': 'rgb(0,0,0)', opacity: 1, 'stroke-opacity': 1,'fill-opacity': 1}, // same here
Interpolate: { numbers,colors },
functions: {onStart:onStartAttr}
}
// the Animation class will need some values to validate this Object attribute
// subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'],
// defaultValue:
// fill : 'rgb(0,0,0)',
// stroke: 'rgb(0,0,0)',
// 'stop-color': 'rgb(0,0,0)',
// opacity: 1,
// 'stroke-opacity': 1,
// 'fill-opacity': 1 // same here
// },
Interpolate: { numbers, colors },
functions: { onStart: onStartAttr },
};
export default baseAttributes
export default baseAttributes;

View file

@ -1,34 +1,37 @@
import getStyleForProperty from '../process/getStyleForProperty.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import {onStartOpacity} from './opacityPropertyBase.js'
import getStyleForProperty from '../process/getStyleForProperty.js';
import numbers from '../interpolation/numbers.js';
import { onStartOpacity } from './opacityPropertyBase.js';
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* opacityProperty = {
property: 'opacity',
defaultValue: 1,
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
function getOpacity(tweenProp){
return getStyleForProperty(this.element,tweenProp)
function getOpacity(tweenProp/* , value */) {
return getStyleForProperty(this.element, tweenProp);
}
function prepareOpacity(tweenProp,value){
return parseFloat(value); // opacity always FLOAT
function prepareOpacity(tweenProp, value) {
return parseFloat(value); // opacity always FLOAT
}
// All Component Functions
const opacityFunctions = {
prepareStart: getOpacity,
prepareProperty: prepareOpacity,
onStart: onStartOpacity
}
onStart: onStartOpacity,
};
// Full Component
const opacityProperty = {
component: 'opacityProperty',
property: 'opacity',
defaultValue: 1,
Interpolate: {numbers},
functions: opacityFunctions
}
Interpolate: { numbers },
functions: opacityFunctions,
};
export default opacityProperty
Components.OpacityProperty = opacityProperty
export default opacityProperty;

View file

@ -1,14 +1,20 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* opacityProperty = {
property: 'opacity',
defaultValue: 1,
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
export function onStartOpacity(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // opacity could be 0
export function onStartOpacity(tweenProp/* , value */) {
// opacity could be 0 sometimes, we need to check regardless
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = ((numbers(a,b,v) * 1000)>>0)/1000;
}
elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000;
};
}
}
@ -17,8 +23,8 @@ const baseOpacity = {
component: 'baseOpacity',
property: 'opacity',
// defaultValue: 1,
Interpolate: {numbers},
functions: {onStart: onStartOpacity}
}
Interpolate: { numbers },
functions: { onStart: onStartOpacity },
};
export default baseOpacity
export default baseOpacity;

View file

@ -1,17 +1,29 @@
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js';
import numbers from '../interpolation/numbers.js';
import {scrollContainer,onStartScroll,onCompleteScroll,scrollIn,scrollOut,getScrollTargets,preventScroll,toggleScrollEvents} from './scrollPropertyBase.js'
import {
scrollContainer,
onStartScroll,
onCompleteScroll,
scrollIn,
scrollOut,
getScrollTargets,
preventScroll,
toggleScrollEvents,
} from './scrollPropertyBase.js';
// Component Functions
function getScroll(){
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element;
return this.element === scrollContainer ? (window.pageYOffset || scrollContainer.scrollTop) : this.element.scrollTop;
function getScroll() {
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
? scrollContainer : this.element;
return this.element === scrollContainer
? (window.pageYOffset || scrollContainer.scrollTop)
: this.element.scrollTop;
}
function prepareScroll(prop,value){
return parseInt(value);
function prepareScroll(prop, value) {
return parseInt(value, 10);
}
// All Component Functions
@ -19,20 +31,20 @@ const scrollFunctions = {
prepareStart: getScroll,
prepareProperty: prepareScroll,
onStart: onStartScroll,
onComplete: onCompleteScroll
}
onComplete: onCompleteScroll,
};
// Full Component
const scrollProperty = {
component: 'scrollProperty',
property: 'scroll',
defaultValue: 0,
Interpolate: {numbers},
Interpolate: { numbers },
functions: scrollFunctions,
// export stuff to global
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive }
}
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive,
},
};
export default scrollProperty
Components.ScrollProperty = scrollProperty
export default scrollProperty;

View file

@ -1,65 +1,68 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js'
import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents.js'
import supportTouch from 'shorter-js/src/boolean/supportTouch.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.js';
import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents.js';
import supportTouch from 'shorter-js/src/boolean/supportTouch.js';
import numbers from '../interpolation/numbers.js';
import KUTE from '../objects/kute.js';
// Component Util
// events preventing scroll
const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel'
const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel';
// true scroll container
// very important and specific to the component
export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent) ? document.body : document.documentElement
export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent)
? document.body
: document.documentElement;
// scroll event options
// it's important to stop propagating when animating scroll
const passiveHandler = supportPassive ? { passive: false } : false
const passiveHandler = supportPassive ? { passive: false } : false;
// prevent mousewheel or touch events while tweening scroll
export function preventScroll(e) {
this.scrolling && e.preventDefault()
if (this.scrolling) e.preventDefault();
}
export function getScrollTargets(){
let el = this.element
return el === scrollContainer ? { el: document, st: document.body } : { el: el, st: el}
export function getScrollTargets() {
const el = this.element;
return el === scrollContainer ? { el: document, st: document.body } : { el, st: el };
}
export function toggleScrollEvents(action,element){
element[action]( mouseHoverEvents[0], preventScroll, passiveHandler);
element[action]( touchOrWheel, preventScroll, passiveHandler);
export function toggleScrollEvents(action, element) {
element[action](mouseHoverEvents[0], preventScroll, passiveHandler);
element[action](touchOrWheel, preventScroll, passiveHandler);
}
export function scrollIn(){
let targets = getScrollTargets.call(this)
export function scrollIn() {
const targets = getScrollTargets.call(this);
if ( 'scroll' in this.valuesEnd && !targets.el.scrolling) {
if ('scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1;
toggleScrollEvents('addEventListener',targets.el)
targets.st.style.pointerEvents = 'none'
toggleScrollEvents('addEventListener', targets.el);
targets.st.style.pointerEvents = 'none';
}
}
export function scrollOut(){ //prevent scroll when tweening scroll
let targets = getScrollTargets.call(this)
export function scrollOut() { // prevent scroll when tweening scroll
const targets = getScrollTargets.call(this);
if ( 'scroll' in this.valuesEnd && targets.el.scrolling) {
if ('scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0;
toggleScrollEvents('removeEventListener',targets.el)
targets.st.style.pointerEvents = ''
toggleScrollEvents('removeEventListener', targets.el);
targets.st.style.pointerEvents = '';
}
}
// Component Functions
export function onStartScroll(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // checking 0 will NOT add the render function
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element;
export function onStartScroll(tweenProp) {
// checking 0 will NOT add the render function
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
? scrollContainer : this.element;
scrollIn.call(this);
KUTE[tweenProp] = (elem, a, b, v) => {
elem.scrollTop = (numbers(a,b,v))>>0;
elem.scrollTop = (numbers(a, b, v)) >> 0;
};
}
}
export function onCompleteScroll(tweenProp){
scrollOut.call(this)
export function onCompleteScroll(/* tweenProp */) {
scrollOut.call(this);
}
// Base Component
@ -67,13 +70,15 @@ const baseScroll = {
component: 'baseScroll',
property: 'scroll',
// defaultValue: 0,
Interpolate: {numbers},
Interpolate: { numbers },
functions: {
onStart: onStartScroll,
onComplete: onCompleteScroll
onComplete: onCompleteScroll,
},
// unfortunatelly scroll needs all them no matter the packaging
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive }
}
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive,
},
};
export default baseScroll
export default baseScroll;

View file

@ -1,13 +1,12 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueColor from '../util/trueColor.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import {onStartShadow} from './shadowPropertiesBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueColor from '../util/trueColor.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
import { onStartShadow } from './shadowPropertiesBase.js';
// Component Properties
const shadowProps = ['boxShadow','textShadow']
const shadowProps = ['boxShadow', 'textShadow'];
// Component Util
@ -15,79 +14,97 @@ const shadowProps = ['boxShadow','textShadow']
// text-shadow: none | offset-x offset-y blur-radius color |initial|inherit
// utility function to process values accordingly
// numbers must be floats and color must be rgb object
function processShadowArray (shadow,tweenProp){
let newShadow, i;
function processShadowArray(shadow, tweenProp) {
let newShadow;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
// [h-shadow, v-shadow, color]
if (shadow.length === 3) {
newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none'];
} else if (shadow.length === 4) { // [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color]
newShadow = /inset|none/.test(shadow[3]) ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]] : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none'];
} else if (shadow.length === 5) { // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color]
newShadow = /inset|none/.test(shadow[4]) ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]] : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none'];
} else if (shadow.length === 6) { // ideal [h-shadow, v-shadow, blur, spread, color, inset]
// [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color]
} else if (shadow.length === 4) {
newShadow = /inset|none/.test(shadow[3])
? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]]
: [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none'];
// [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color]
} else if (shadow.length === 5) {
newShadow = /inset|none/.test(shadow[4])
? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]]
: [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none'];
// ideal [h-shadow, v-shadow, blur, spread, color, inset]
} else if (shadow.length === 6) {
newShadow = shadow;
}
// make sure the values are ready to tween
for (i=0;i<4;i++){
for (let i = 0; i < 4; i += 1) {
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[4] = trueColor(newShadow[4]);
// return tweenProp === 'boxShadow' ? newShadow : [newShadow[0],newShadow[1],newShadow[2],newShadow[4]];
newShadow = tweenProp === 'boxShadow' ? newShadow : newShadow.filter((x,i)=>[0,1,2,4].indexOf(i)>-1);
newShadow = tweenProp === 'boxShadow'
? newShadow
: newShadow.filter((x, i) => [0, 1, 2, 4].includes(i));
return newShadow;
}
// Component Functions
export function getShadow(tweenProp,value){
let cssShadow = getStyleForProperty(this.element,tweenProp);
return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow) ? defaultValues[tweenProp] : cssShadow; // '0px 0px 0px 0px rgb(0,0,0)'
export function getShadow(tweenProp/* , value */) {
const cssShadow = getStyleForProperty(this.element, tweenProp);
// '0px 0px 0px 0px rgb(0,0,0)'
return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow)
? defaultValues[tweenProp]
: cssShadow;
}
export function prepareShadow(tweenProp,value) {
export function prepareShadow(tweenProp, propValue) {
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
// parseProperty for boxShadow, builds basic structure with ready to tween values
if (typeof value === 'string'){
let currentColor, inset = 'none';
let value = propValue;
if (typeof value === 'string') {
let inset = 'none';
// a full RegEx for color strings
const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi
const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi;
const currentColor = value.match(colRegEx);
// make sure to always have the inset last if possible
inset = /inset/.test(value) ? 'inset' : inset;
value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g,'') : value;
value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g, '') : value;
// also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset"
currentColor = value.match(colRegEx);
value = value.replace(currentColor[0],'').split(' ').concat([currentColor[0].replace(/\s/g,'')],[inset]);
value = value.replace(currentColor[0], '').split(' ').concat([currentColor[0].replace(/\s/g, '')], [inset]);
value = processShadowArray(value,tweenProp);
} else if (value instanceof Array){
value = processShadowArray(value,tweenProp);
value = processShadowArray(value, tweenProp);
} else if (value instanceof Array) {
value = processShadowArray(value, tweenProp);
}
return value;
}
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow)
const shadowPropOnStart = {};
shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// All Component Functions
const shadowFunctions = {
prepareStart: getShadow,
prepareProperty: prepareShadow,
onStart: shadowPropOnStart
}
onStart: shadowPropOnStart,
};
// Component Full
const shadowProperties = {
component: 'shadowProperties',
properties: shadowProps,
defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px rgb(0,0,0)'},
Interpolate: {numbers,colors},
defaultValues: {
boxShadow: '0px 0px 0px 0px rgb(0,0,0)',
textShadow: '0px 0px 0px rgb(0,0,0)',
},
Interpolate: { numbers, colors },
functions: shadowFunctions,
Util: { processShadowArray, trueColor }
}
Util: { processShadowArray, trueColor },
};
export default shadowProperties
Components.ShadowProperties = shadowProperties
export default shadowProperties;

View file

@ -1,38 +1,45 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import colors from '../interpolation/colors.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// Component Properties
const shadowProps = ['boxShadow','textShadow']
const shadowProps = ['boxShadow', 'textShadow'];
// Component Functions
export function onStartShadow(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
// let's start with the numbers | set unit | also determine inset
let params = [], unit = 'px', sl = tweenProp === 'textShadow' ? 3 : 4,
colA = sl === 3 ? a[3] : a[4], colB = sl === 3 ? b[3] : b[4],
inset = a[5] && a[5] !== 'none' || b[5] && b[5] !== 'none' ? ' inset' : false;
const params = [];
const unit = 'px';
const sl = tweenProp === 'textShadow' ? 3 : 4;
const colA = sl === 3 ? a[3] : a[4];
const colB = sl === 3 ? b[3] : b[4];
const inset = (a[5] && a[5] !== 'none') || (b[5] && b[5] !== 'none') ? ' inset' : false;
for (let i=0; i<sl; i++){
params.push( ((numbers( a[i], b[i], v ) * 1000 >> 0) / 1000) + unit );
for (let i = 0; i < sl; i += 1) {
params.push(((numbers(a[i], b[i], v) * 1000 >> 0) / 1000) + unit);
}
// the final piece of the puzzle, the DOM update
elem.style[tweenProp] = inset ? colors(colA,colB,v) + params.join(' ') + inset
: colors(colA,colB,v) + params.join(' ');
}
elem.style[tweenProp] = inset
? colors(colA, colB, v) + params.join(' ') + inset
: colors(colA, colB, v) + params.join(' ');
};
}
}
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow)
const shadowPropOnStart = {};
shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// Component Base
const baseShadow = {
component: 'baseShadow',
// properties: shadowProps,
// defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px 0px rgb(0,0,0)'},
Interpolate: {numbers,colors},
functions: {onStart: shadowPropOnStart}
}
// defaultValues: {
// boxShadow :'0px 0px 0px 0px rgb(0,0,0)',
// textShadow: '0px 0px 0px 0px rgb(0,0,0)'
// },
Interpolate: { numbers, colors },
functions: { onStart: shadowPropOnStart },
};
export default baseShadow
export default baseShadow;

View file

@ -1,131 +1,156 @@
import Components from '../objects/components.js'
import selector from '../util/selector.js'
import numbers from '../interpolation/numbers.js'
import parsePathString from 'svg-path-commander/src/process/parsePathString.js';
import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js';
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import reverseCurve from 'svg-path-commander/src/process/reverseCurve.js';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js';
import clonePath from 'svg-path-commander/src/process/clonePath.js';
import splitCubic from 'svg-path-commander/src/process/splitCubic.js';
import splitPath from 'svg-path-commander/src/process/splitPath.js';
import getSegCubicLength from 'svg-path-commander/src/util/getSegCubicLength.js';
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js';
import { onStartCubicMorph } from './svgCubicMorphBase.js';
import numbers from '../interpolation/numbers.js';
import selector from '../util/selector.js';
import {onStartCubicMorph} from './svgCubicMorphBase.js'
import parsePathString from 'svg-path-commander/src/process/parsePathString.js'
import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js'
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js'
import pathToString from 'svg-path-commander/src/convert/pathToString.js'
import reverseCurve from 'svg-path-commander/src/process/reverseCurve.js'
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js'
import clonePath from 'svg-path-commander/src/process/clonePath.js'
import splitCubic from 'svg-path-commander/src/process/splitCubic.js'
import splitPath from 'svg-path-commander/src/process/splitPath.js'
import getSegCubicLength from 'svg-path-commander/src/util/getSegCubicLength.js'
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Util
function getCurveArray(pathString){
return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map((segment,i,pathArray)=>{
let segmentData = i && pathArray[i-1].slice(-2).concat(segment.slice(1)),
curveLength = i ? getSegCubicLength.apply(0, segmentData ) : 0,
subsegs = i ? (curveLength ? splitCubic( segmentData ) : [segment,segment]) : [segment]; // must be [segment,segment]
return {
s: segment,
ss: subsegs,
l: curveLength
}
})
function getCurveArray(pathString) {
return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0])
.map((segment, i, pathArray) => {
const segmentData = i && pathArray[i - 1].slice(-2).concat(segment.slice(1));
const curveLength = i ? getSegCubicLength.apply(0, segmentData) : 0;
let subsegs;
if (i) {
// must be [segment,segment]
subsegs = curveLength ? splitCubic(segmentData) : [segment, segment];
} else {
subsegs = [segment];
}
return {
s: segment,
ss: subsegs,
l: curveLength,
};
});
}
function equalizeSegments(path1,path2,TL){
let c1 = getCurveArray(path1),
c2 = getCurveArray(path2),
L1 = c1.length,
L2 = c2.length,
l1 = c1.filter(x=>x.l).length,
l2 = c2.filter(x=>x.l).length,
m1 = c1.filter(x=>x.l).reduce((a,{l})=>a+l,0) / l1 || 0,
m2 = c2.filter(x=>x.l).reduce((a,{l})=>a+l,0) / l2 || 0,
tl = TL || Math.max(L1,L2),
mm = [m1,m2],
dif = [tl-L1,tl-L2],
canSplit = 0,
result = [c1,c2].map((x,i) => x.l === tl ? x.map(y=>y.s)
: x.map((y,j) => {
canSplit = j && dif[i] && y.l >= mm[i]
dif[i] -= canSplit ? 1 : 0
return canSplit ? y.ss : [y.s]
}).flat())
function equalizeSegments(path1, path2, TL) {
const c1 = getCurveArray(path1);
const c2 = getCurveArray(path2);
const L1 = c1.length;
const L2 = c2.length;
const l1 = c1.filter((x) => x.l).length;
const l2 = c2.filter((x) => x.l).length;
const m1 = c1.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l1 || 0;
const m2 = c2.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l2 || 0;
const tl = TL || Math.max(L1, L2);
const mm = [m1, m2];
const dif = [tl - L1, tl - L2];
let canSplit = 0;
const result = [c1, c2]
.map((x, i) => (x.l === tl
? x.map((y) => y.s)
: x.map((y, j) => {
canSplit = j && dif[i] && y.l >= mm[i];
dif[i] -= canSplit ? 1 : 0;
return canSplit ? y.ss : [y.s];
}).flat()));
return result[0].length === result[1].length ? result : equalizeSegments(result[0],result[1],tl)
return result[0].length === result[1].length
? result
: equalizeSegments(result[0], result[1], tl);
}
function getRotations(a) {
let segCount = a.length, pointCount = segCount - 1
const segCount = a.length;
const pointCount = segCount - 1;
return a.map((f,idx) => {
return a.map((p,i)=>{
let oldSegIdx = idx + i, seg;
if (i===0 || a[oldSegIdx] && a[oldSegIdx][0] === 'M') {
seg = a[oldSegIdx]
return ['M'].concat(seg.slice(-2))
} else {
if (oldSegIdx >= segCount) oldSegIdx -= pointCount;
return a[oldSegIdx]
}
})
})
return a.map((f, idx) => a.map((p, i) => {
let oldSegIdx = idx + i;
let seg;
if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) {
seg = a[oldSegIdx];
return ['M'].concat(seg.slice(-2));
}
if (oldSegIdx >= segCount) oldSegIdx -= pointCount;
return a[oldSegIdx];
}));
}
function getRotatedCurve(a,b) {
let segCount = a.length - 1,
lineLengths = [],
computedIndex = 0,
sumLensSqrd = 0,
rotations = getRotations(a);
function getRotatedCurve(a, b) {
const segCount = a.length - 1;
const lineLengths = [];
let computedIndex = 0;
let sumLensSqrd = 0;
const rotations = getRotations(a);
rotations.map((r,i)=>{
a.slice(1).map((s,j) => {
sumLensSqrd += distanceSquareRoot(a[(i+j) % segCount].slice(-2),b[j % segCount].slice(-2))
})
lineLengths[i] = sumLensSqrd
sumLensSqrd = 0
})
rotations.forEach((r, i) => {
a.slice(1).forEach((s, j) => {
sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2));
});
lineLengths[i] = sumLensSqrd;
sumLensSqrd = 0;
});
computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths))
computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths));
return rotations[computedIndex]
return rotations[computedIndex];
}
// Component Functions
function getCubicMorph(tweenProp){
function getCubicMorph(/* tweenProp, value */) {
return this.element.getAttribute('d');
}
function prepareCubicMorph(tweenProp,value){
function prepareCubicMorph(tweenProp, value) {
// get path d attribute or create a path from string value
let pathObject = {},
el = value instanceof SVGElement ? value : /^\.|^\#/.test(value) ? selector(value) : null,
pathReg = new RegExp('\\n','ig'); // remove newlines, they break some JSON strings
const pathObject = {};
// remove newlines, they break some JSON strings
const pathReg = new RegExp('\\n', 'ig');
let el = null;
if (value instanceof SVGElement) {
el = value;
} else if (/^\.|^#/.test(value)) {
el = selector(value);
}
// make sure to return pre-processed values
if ( typeof(value) === 'object' && value.curve ) {
if (typeof (value) === 'object' && value.curve) {
return value;
} else if ( el && /path|glyph/.test(el.tagName) ) {
pathObject.original = el.getAttribute('d').replace(pathReg,'');
} else if (!el && typeof(value) === 'string') { // maybe it's a string path already
pathObject.original = value.replace(pathReg,'');
} if (el && /path|glyph/.test(el.tagName)) {
pathObject.original = el.getAttribute('d').replace(pathReg, '');
// maybe it's a string path already
} else if (!el && typeof (value) === 'string') {
pathObject.original = value.replace(pathReg, '');
}
return pathObject;
}
function crossCheckCubicMorph(tweenProp){
function crossCheckCubicMorph(tweenProp) {
if (this.valuesEnd[tweenProp]) {
let pathCurve1 = this.valuesStart[tweenProp].curve,
pathCurve2 = this.valuesEnd[tweenProp].curve
const pathCurve1 = this.valuesStart[tweenProp].curve;
const pathCurve2 = this.valuesEnd[tweenProp].curve;
if ( !pathCurve1 || !pathCurve2 || ( pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length) ) {
let path1 = this.valuesStart[tweenProp].original,
path2 = this.valuesEnd[tweenProp].original,
curves = equalizeSegments(path1,path2),
curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) ? reverseCurve(curves[0]) : clonePath(curves[0])
if (!pathCurve1 || !pathCurve2
|| (pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length)) {
const path1 = this.valuesStart[tweenProp].original;
const path2 = this.valuesEnd[tweenProp].original;
const curves = equalizeSegments(path1, path2);
const curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1])
? reverseCurve(curves[0])
: clonePath(curves[0]);
this.valuesStart[tweenProp].curve = curve0;
this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1],curve0)
this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1], curve0);
}
}
}
@ -135,25 +160,31 @@ const svgCubicMorphFunctions = {
prepareStart: getCubicMorph,
prepareProperty: prepareCubicMorph,
onStart: onStartCubicMorph,
crossCheck: crossCheckCubicMorph
}
crossCheck: crossCheckCubicMorph,
};
// Component Full
const svgCubicMorph = {
component: 'svgCubicMorph',
property: 'path',
defaultValue: [],
Interpolate: {numbers,pathToString},
Interpolate: { numbers, pathToString },
functions: svgCubicMorphFunctions,
// export utils to global for faster execution
Util: {
pathToCurve, pathToAbsolute, pathToString, parsePathString,
getRotatedCurve, getRotations, equalizeSegments,
reverseCurve, clonePath, getDrawDirection,
splitCubic, getCurveArray
}
}
pathToCurve,
pathToAbsolute,
pathToString,
parsePathString,
getRotatedCurve,
getRotations,
equalizeSegments,
reverseCurve,
clonePath,
getDrawDirection,
splitCubic,
getCurveArray,
},
};
export default svgCubicMorph
Components.SVGCubicMorph = svgCubicMorph
export default svgCubicMorph;

View file

@ -1,23 +1,29 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers} },
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Functions
export function onStartCubicMorph(tweenProp){
export function onStartCubicMorph(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = function(elem,a,b,v){
let curve = [], path1 = a.curve, path2 = b.curve;
for(let i=0, l=path2.length; i<l; i++) { // each path command
KUTE[tweenProp] = function updateMorph(elem, a, b, v) {
const curve = [];
const path1 = a.curve;
const path2 = b.curve;
for (let i = 0, l = path2.length; i < l; i += 1) { // each path command
curve.push([path1[i][0]]);
for(var j=1,l2=path1[i].length;j<l2;j++) { // each command coordinate
curve[i].push( (numbers(path1[i][j], path2[i][j], v) * 1000 >>0)/1000 );
for (let j = 1, l2 = path1[i].length; j < l2; j += 1) { // each command coordinate
curve[i].push((numbers(path1[i][j], path2[i][j], v) * 1000 >> 0) / 1000);
}
}
elem.setAttribute("d", v === 1 ? b.original : pathToString(curve) )
}
elem.setAttribute('d', v === 1 ? b.original : pathToString(curve));
};
}
}
@ -26,8 +32,8 @@ const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
property: 'path',
// defaultValue: [],
Interpolate: {numbers,pathToString},
functions: {onStart:onStartCubicMorph}
}
Interpolate: { numbers, pathToString },
functions: { onStart: onStartCubicMorph },
};
export default baseSvgCubicMorph
export default baseSvgCubicMorph;

View file

@ -1,130 +1,151 @@
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import numbers from '../interpolation/numbers.js'
import {onStartDraw} from './svgDrawBase.js'
import getStyleForProperty from '../process/getStyleForProperty.js';
import numbers from '../interpolation/numbers.js';
import { onStartDraw } from './svgDrawBase.js';
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* svgDraw = {
property: 'draw',
defaultValue,
Interpolate: {numbers} },
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Util
function percent (v,l) {
return parseFloat(v) / 100 * l
function percent(v, l) {
return (parseFloat(v) / 100) * l;
}
// http://stackoverflow.com/a/30376660
function getRectLength(el) { // returns the length of a Rect
let w = el.getAttribute('width'),
h = el.getAttribute('height');
return (w*2)+(h*2);
// returns the length of a Rect
function getRectLength(el) {
const w = el.getAttribute('width');
const h = el.getAttribute('height');
return (w * 2) + (h * 2);
}
// getPolygonLength / getPolylineLength
// returns the length of the Polygon / Polyline
function getPolyLength(el) {
// getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline
const points = el.getAttribute('points').split(' ');
let len = 0;
if (points.length > 1) {
const coord = p => {
const coord = (p) => {
const c = p.split(',');
if (c.length != 2) { return; } // return undefined
if (isNaN(c[0]) || isNaN(c[1])) { return; }
if (c.length !== 2) { return 0; } // return undefined
if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; }
return [parseFloat(c[0]), parseFloat(c[1])];
};
const dist = (c1, c2) => {
if (c1 != undefined && c2 != undefined) {
if (c1 !== undefined && c2 !== undefined) {
return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2);
}
return 0;
};
if (points.length > 2) {
for (let i=0; i<points.length-1; i++) {
len += dist(coord(points[i]), coord(points[i+1]));
for (let i = 0; i < points.length - 1; i += 1) {
len += dist(coord(points[i]), coord(points[i + 1]));
}
}
len += el.tagName === 'polygon' ? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
len += el.tagName === 'polygon'
? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
}
return len;
}
function getLineLength(el) { // return the length of the line
// return the length of the line
function getLineLength(el) {
const x1 = el.getAttribute('x1');
const x2 = el.getAttribute('x2');
const y1 = el.getAttribute('y1');
const y2 = el.getAttribute('y2');
return Math.sqrt((x2 - x1) ** 2+(y2 - y1) ** 2);
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
function getCircleLength(el) { // return the length of the circle
// return the length of the circle
function getCircleLength(el) {
const r = el.getAttribute('r');
return 2 * Math.PI * r;
}
function getEllipseLength(el) { // returns the length of an ellipse
const rx = el.getAttribute('rx'), ry = el.getAttribute('ry'), len = 2*rx, wid = 2*ry;
return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
// returns the length of an ellipse
function getEllipseLength(el) {
const rx = el.getAttribute('rx');
const ry = el.getAttribute('ry');
const len = 2 * rx;
const wid = 2 * ry;
return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
}
function getTotalLength(el) { // returns the result of any of the below functions
if ('rect'===el.tagName) {
// returns the result of any of the below functions
function getTotalLength(el) {
if (el.tagName === 'rect') {
return getRectLength(el);
} else if ('circle'===el.tagName) {
} if (el.tagName === 'circle') {
return getCircleLength(el);
} else if ('ellipse'===el.tagName) {
} if (el.tagName === 'ellipse') {
return getEllipseLength(el);
} else if (['polygon','polyline'].indexOf(el.tagName)>-1) {
} if (['polygon', 'polyline'].includes(el.tagName)) {
return getPolyLength(el);
} else if ('line'===el.tagName) {
} if (el.tagName === 'line') {
return getLineLength(el);
}
// ESLint
return 0;
}
function getDraw(e,v) {
let length = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e),
start, end, d, o;
function getDraw(element, value) {
const length = /path|glyph/.test(element.tagName)
? element.getTotalLength()
: getTotalLength(element);
let start;
let end;
let dasharray;
let offset;
if ( v instanceof Object ) {
return v;
} else if (typeof v === 'string') {
v = v.split(/\,|\s/);
start = /%/.test(v[0]) ? percent(v[0].trim(),length) : parseFloat(v[0]);
end = /%/.test(v[1]) ? percent(v[1].trim(),length) : parseFloat(v[1]);
} else if (typeof v === 'undefined') {
o = parseFloat(getStyleForProperty(e,'stroke-dashoffset'));
d = getStyleForProperty(e,'stroke-dasharray').split(/\,/);
if (value instanceof Object) {
return value;
} if (typeof value === 'string') {
const v = value.split(/,|\s/);
start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]);
end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]);
} else if (typeof value === 'undefined') {
offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset'));
dasharray = getStyleForProperty(element, 'stroke-dasharray').split(',');
start = 0-o;
end = parseFloat(d[0]) + start || length;
start = 0 - offset;
end = parseFloat(dasharray[0]) + start || length;
}
return { s: start, e: end, l: length };
}
function resetDraw(elem) {
elem.style.strokeDashoffset = ``;
elem.style.strokeDasharray = ``;
elem.style.strokeDashoffset = '';
elem.style.strokeDasharray = '';
}
// Component Functions
function getDrawValue(){
function getDrawValue(/* prop, value */) {
return getDraw(this.element);
}
function prepareDraw(a,o){
return getDraw(this.element,o);
function prepareDraw(a, o) {
return getDraw(this.element, o);
}
// All Component Functions
const svgDrawFunctions = {
prepareStart: getDrawValue,
prepareProperty: prepareDraw,
onStart: onStartDraw
}
onStart: onStartDraw,
};
// Component Full
const svgDraw = {
component: 'svgDraw',
property: 'draw',
defaultValue: '0% 0%',
Interpolate: {numbers},
Interpolate: { numbers },
functions: svgDrawFunctions,
// Export to global for faster execution
Util: {
@ -136,10 +157,8 @@ const svgDraw = {
getTotalLength,
resetDraw,
getDraw,
percent
}
}
percent,
},
};
export default svgDraw
Components.SVGDraw = svgDraw
export default svgDraw;

View file

@ -1,21 +1,26 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* svgDraw = {
property: 'draw',
defaultValue,
Interpolate: {numbers} },
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
export function onStartDraw(tweenProp){
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem,a,b,v) => {
let pathLength = (a.l*100>>0)/100,
start = (numbers(a.s,b.s,v)*100>>0)/100,
end = (numbers(a.e,b.e,v)*100>>0)/100,
offset = 0 - start,
dashOne = end+offset;
export function onStartDraw(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
const pathLength = (a.l * 100 >> 0) / 100;
const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100;
const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100;
const offset = 0 - start;
const dashOne = end + offset;
elem.style.strokeDashoffset = `${offset}px`;
elem.style.strokeDasharray = `${((dashOne <1 ? 0 : dashOne)*100>>0)/100}px, ${pathLength}px`;
}
elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`;
};
}
}
@ -23,8 +28,8 @@ export function onStartDraw(tweenProp){
const baseSVGDraw = {
component: 'baseSVGDraw',
property: 'draw',
Interpolate: {numbers},
functions: {onStart:onStartDraw}
}
Interpolate: { numbers },
functions: { onStart: onStartDraw },
};
export default baseSVGDraw
export default baseSVGDraw;

View file

@ -1,23 +1,26 @@
import selector from '../util/selector.js'
import defaultOptions from '../objects/defaultOptions.js'
import Components from '../objects/components.js'
import coords from '../interpolation/coords.js'
import {onStartSVGMorph} from './svgMorphBase.js'
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import normalizePath from 'svg-path-commander/src/process/normalizePath.js';
import splitPath from 'svg-path-commander/src/process/splitPath.js';
import roundPath from 'svg-path-commander/src/process/roundPath.js';
import invalidPathValue from 'svg-path-commander/src/util/invalidPathValue.js';
import getPathLength from 'svg-path-commander/src/util/getPathLength.js';
import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength.js';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js';
import epsilon from 'svg-path-commander/src/math/epsilon.js';
import midPoint from 'svg-path-commander/src/math/midPoint.js';
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js';
import { onStartSVGMorph } from './svgMorphBase.js';
import coords from '../interpolation/coords.js';
import defaultOptions from '../objects/defaultOptions.js';
import selector from '../util/selector.js';
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js'
import pathToString from 'svg-path-commander/src/convert/pathToString.js'
import normalizePath from 'svg-path-commander/src/process/normalizePath.js'
import splitPath from 'svg-path-commander/src/process/splitPath.js'
import roundPath from 'svg-path-commander/src/process/roundPath.js'
import invalidPathValue from 'svg-path-commander/src/util/invalidPathValue.js'
import getPathLength from 'svg-path-commander/src/util/getPathLength.js'
import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength.js'
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js'
import epsilon from 'svg-path-commander/src/math/epsilon.js'
import midPoint from 'svg-path-commander/src/math/midPoint.js'
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers,coords},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Interpolation
// function function(array1, array2, length, progress)
@ -26,55 +29,55 @@ import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.j
// original script flubber
// https://github.com/veltman/flubber
function polygonLength(ring){
return ring.reduce((length, point, i) =>
i ? length + distanceSquareRoot(ring[i-1],point) : 0, 0 )
function polygonLength(ring) {
return ring.reduce((length, point, i) => (i
? length + distanceSquareRoot(ring[i - 1], point)
: 0), 0);
}
function pathStringToRing(str, maxSegmentLength) {
let parsed = normalizePath(str,0)
return exactRing(parsed) || approximateRing(parsed, maxSegmentLength);
}
function exactRing(pathArray) {
let ring = [],
segment = [], pathCommand = '',
pathlen = pathArray.length,
pathLength = 0;
const ring = [];
const pathlen = pathArray.length;
let segment = [];
let pathCommand = '';
let pathLength = 0;
if (!pathArray.length || pathArray[0][0] !== "M") {
if (!pathArray.length || pathArray[0][0] !== 'M') {
return false;
}
for (let i = 0; i < pathlen; i++) {
segment = pathArray[i]
pathCommand = segment[0]
for (let i = 0; i < pathlen; i += 1) {
segment = pathArray[i];
[pathCommand] = segment;
if (pathCommand === "M" && i || pathCommand === "Z") {
if ((pathCommand === 'M' && i) || pathCommand === 'Z') {
break; // !!
} else if ('ML'.indexOf( pathCommand) > -1) {
} else if ('ML'.indexOf(pathCommand) > -1) {
ring.push([segment[1], segment[2]]);
} else {
return false;
}
}
pathLength = polygonLength(ring)
pathLength = polygonLength(ring);
return pathlen ? { ring, pathLength } : false;
}
function approximateRing(parsed, maxSegmentLength) {
let ringPath = splitPath(pathToString(parsed))[0],
curvePath = pathToCurve(ringPath,4),
pathLength = getPathLength(curvePath),
ring = [], numPoints = 3, point;
const ringPath = splitPath(pathToString(parsed))[0];
const curvePath = pathToCurve(ringPath, 4);
const pathLength = getPathLength(curvePath);
const ring = [];
let numPoints = 3;
let point;
if ( maxSegmentLength && !isNaN(maxSegmentLength) && +maxSegmentLength > 0 ) {
if (maxSegmentLength && !Number.isNaN(maxSegmentLength) && +maxSegmentLength > 0) {
numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength));
}
for (let i = 0; i < numPoints; i++) {
point = getPointAtLength(curvePath,pathLength * i / numPoints)
for (let i = 0; i < numPoints; i += 1) {
point = getPointAtLength(curvePath, (pathLength * i) / numPoints);
ring.push([point.x, point.y]);
}
@ -86,19 +89,36 @@ function approximateRing(parsed, maxSegmentLength) {
return {
pathLength,
ring,
skipBisect: true
skipBisect: true,
};
}
function rotateRing(ring, vs) {
let len = ring.length, min = Infinity, bestOffset, sumOfSquares, spliced;
for (let offset = 0; offset < len; offset++) {
function pathStringToRing(str, maxSegmentLength) {
const parsed = normalizePath(str, 0);
return exactRing(parsed) || approximateRing(parsed, maxSegmentLength);
}
function rotateRing(ring, vs) {
const len = ring.length;
let min = Infinity;
let bestOffset;
let sumOfSquares = 0;
let spliced;
let d;
let p;
for (let offset = 0; offset < len; offset += 1) {
sumOfSquares = 0;
vs.forEach(function(p, i) {
let d = distanceSquareRoot(ring[(offset + i) % len], p);
// vs.forEach((p, i) => {
// const d = distanceSquareRoot(ring[(offset + i) % len], p);
// sumOfSquares += d * d;
// });
for (let i = 0; i < vs.length; i += 1) {
p = vs[i];
d = distanceSquareRoot(ring[(offset + i) % len], p);
sumOfSquares += d * d;
});
}
if (sumOfSquares < min) {
min = sumOfSquares;
@ -111,33 +131,44 @@ function rotateRing(ring, vs) {
ring.splice(ring.length, 0, ...spliced);
}
}
function addPoints(ring, numPoints) {
let desiredLength = ring.length + numPoints,
// step = ring.pathLength / numPoints;
step = polygonLength(ring) / numPoints;
let i = 0, cursor = 0, insertAt = step / 2, a, b, segment;
function addPoints(ring, numPoints) {
const desiredLength = ring.length + numPoints;
// const step = ring.pathLength / numPoints;
const step = polygonLength(ring) / numPoints;
let i = 0;
let cursor = 0;
let insertAt = step / 2;
let a;
let b;
let segment;
while (ring.length < desiredLength) {
a = ring[i]
b = ring[(i + 1) % ring.length]
// console.log(step,a,b)
segment = distanceSquareRoot(a, b)
a = ring[i];
b = ring[(i + 1) % ring.length];
segment = distanceSquareRoot(a, b);
if (insertAt <= cursor + segment) {
ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) );
ring.splice(i + 1, 0, segment
? midPoint(a, b, (insertAt - cursor) / segment)
: a.slice(0));
insertAt += step;
continue;
} else {
cursor += segment;
i += 1;
}
cursor += segment;
i++;
}
}
function bisect(ring, maxSegmentLength = Infinity) {
let a = [], b = []
for (let i = 0; i < ring.length; i++) {
a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1];
let a = [];
let b = [];
for (let i = 0; i < ring.length; i += 1) {
a = ring[i];
b = i === ring.length - 1 ? ring[0] : ring[i + 1];
// Could splice the whole set for a segment instead, but a bit messy
while (distanceSquareRoot(a, b) > maxSegmentLength) {
@ -147,89 +178,110 @@ function bisect(ring, maxSegmentLength = Infinity) {
}
}
function normalizeRing(ring, maxSegmentLength) {
let points, skipBisect, pathLength;
function validRing(ring) {
return Array.isArray(ring)
&& ring.every((point) => Array.isArray(point)
&& point.length === 2
&& !Number.isNaN(point[0])
&& !Number.isNaN(point[1]));
}
if (typeof ring === "string") {
let converted = pathStringToRing(ring, maxSegmentLength)
ring = converted.ring
skipBisect = converted.skipBisect
pathLength = converted.pathLength
function normalizeRing(input, maxSegmentLength) {
let skipBisect;
let pathLength;
let ring = input;
if (typeof (ring) === 'string') {
const converted = pathStringToRing(ring, maxSegmentLength);
ring = converted.ring;
skipBisect = converted.skipBisect;
pathLength = converted.pathLength;
} else if (!Array.isArray(ring)) {
throw (invalidPathValue)
throw Error(`${invalidPathValue}: ${ring}`);
}
points = ring.slice(0)
points.pathLength = pathLength
const points = ring.slice(0);
points.pathLength = pathLength;
if (!validRing(points)) {
throw (invalidPathValue)
throw Error(`${invalidPathValue}: ${points}`);
}
// TODO skip this test to avoid scale issues?
// Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9
if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) {
points.pop()
points.pop();
}
if ( !skipBisect && maxSegmentLength && !isNaN(maxSegmentLength) && (+maxSegmentLength) > 0 ) {
bisect(points, maxSegmentLength)
if (!skipBisect && maxSegmentLength
&& !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) {
bisect(points, maxSegmentLength);
}
return points
}
function validRing(ring) {
return Array.isArray(ring) && ring.every( point =>
Array.isArray(point) && point.length === 2 && !isNaN(point[0]) && !isNaN(point[1]))
return points;
}
function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) {
morphPrecision = morphPrecision || defaultOptions.morphPrecision
let fromRing = normalizeRing(pathArray1, morphPrecision),
toRing = normalizeRing(pathArray2, morphPrecision),
diff = fromRing.length - toRing.length;
function getInterpolationPoints(pathArray1, pathArray2, precision) {
const morphPrecision = precision || defaultOptions.morphPrecision;
const fromRing = normalizeRing(pathArray1, morphPrecision);
const toRing = normalizeRing(pathArray2, morphPrecision);
const diff = fromRing.length - toRing.length;
addPoints(fromRing, diff < 0 ? diff * -1 : 0);
addPoints(toRing, diff > 0 ? diff : 0);
rotateRing(fromRing,toRing);
rotateRing(fromRing, toRing);
return [roundPath(fromRing),roundPath(toRing)]
return [roundPath(fromRing), roundPath(toRing)];
}
// Component functions
function getSVGMorph(tweenProp){
function getSVGMorph(/* tweenProp */) {
return this.element.getAttribute('d');
}
function prepareSVGMorph(tweenProp,value){
let pathObject = {}, elem = value instanceof SVGElement ? value : /^\.|^\#/.test(value) ? selector(value) : null,
pathReg = new RegExp('\\n','ig'); // remove newlines, they brake JSON strings sometimes
function prepareSVGMorph(tweenProp, value) {
const pathObject = {};
// remove newlines, they brake JSON strings sometimes
const pathReg = new RegExp('\\n', 'ig');
let elem = null;
if (value instanceof SVGElement) {
elem = value;
} else if (/^\.|^#/.test(value)) {
elem = selector(value);
}
// first make sure we return pre-processed values
if ( typeof(value) === 'object' && value.pathArray ) {
if (typeof (value) === 'object' && value.pathArray) {
return value;
} else if ( elem && /path|glyph/.test(elem.tagName) ) {
pathObject.original = elem.getAttribute('d').replace(pathReg,'');
} else if ( !elem && typeof(value) === 'string' ) { // maybe it's a string path already
pathObject.original = value.replace(pathReg,'');
} if (elem && ['path', 'glyph'].includes(elem.tagName)) {
pathObject.original = elem.getAttribute('d').replace(pathReg, '');
// maybe it's a string path already
} else if (!elem && typeof (value) === 'string') {
pathObject.original = value.replace(pathReg, '');
}
return pathObject;
}
function crossCheckSVGMorph(prop){
if ( this.valuesEnd[prop]){
let pathArray1 = this.valuesStart[prop].pathArray,
pathArray2 = this.valuesEnd[prop].pathArray
function crossCheckSVGMorph(prop) {
if (this.valuesEnd[prop]) {
const pathArray1 = this.valuesStart[prop].pathArray;
const pathArray2 = this.valuesEnd[prop].pathArray;
// skip already processed paths
// allow the component to work with pre-processed values
if ( !pathArray1 || !pathArray2 || pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length ) {
let p1 = this.valuesStart[prop].original,
p2 = this.valuesEnd[prop].original,
// process morphPrecision
morphPrecision = this._morphPrecision ? parseInt(this._morphPrecision) : defaultOptions.morphPrecision,
paths = getInterpolationPoints(p1,p2,morphPrecision);
this.valuesStart[prop].pathArray = paths[0];
this.valuesEnd[prop].pathArray = paths[1];
if (!pathArray1 || !pathArray2
|| (pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length)) {
const p1 = this.valuesStart[prop].original;
const p2 = this.valuesEnd[prop].original;
// process morphPrecision
const morphPrecision = this._morphPrecision
? parseInt(this._morphPrecision, 10)
: defaultOptions.morphPrecision;
const [path1, path2] = getInterpolationPoints(p1, p2, morphPrecision);
this.valuesStart[prop].pathArray = path1;
this.valuesEnd[prop].pathArray = path2;
}
}
}
@ -239,9 +291,8 @@ const svgMorphFunctions = {
prepareStart: getSVGMorph,
prepareProperty: prepareSVGMorph,
onStart: onStartSVGMorph,
crossCheck: crossCheckSVGMorph
}
crossCheck: crossCheckSVGMorph,
};
// Component Full
const svgMorph = {
@ -249,19 +300,27 @@ const svgMorph = {
property: 'path',
defaultValue: [],
Interpolate: coords,
defaultOptions: {morphPrecision : 10, morphIndex:0},
defaultOptions: { morphPrecision: 10, morphIndex: 0 },
functions: svgMorphFunctions,
// Export utils to global for faster execution
Util: {
addPoints,bisect,normalizeRing,validRing, // component
getInterpolationPoints,pathStringToRing,
distanceSquareRoot,midPoint,
approximateRing,rotateRing,
pathToString,pathToCurve,// svg-path-commander
getPathLength,getPointAtLength,getDrawDirection,roundPath
}
}
addPoints,
bisect,
normalizeRing,
validRing, // component
getInterpolationPoints,
pathStringToRing,
distanceSquareRoot,
midPoint,
approximateRing,
rotateRing,
pathToString,
pathToCurve, // svg-path-commander
getPathLength,
getPointAtLength,
getDrawDirection,
roundPath,
},
};
export default svgMorph
Components.SVGMorph = svgMorph
export default svgMorph;

View file

@ -1,15 +1,21 @@
import KUTE from '../objects/kute.js'
import coords from '../interpolation/coords.js'
import KUTE from '../objects/kute.js';
import coords from '../interpolation/coords.js';
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers,coords} },
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component functions
export function onStartSVGMorph(tweenProp){
export function onStartSVGMorph(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let path1 = a.pathArray, path2 = b.pathArray, len = path2.length;
elem.setAttribute("d", (v === 1 ? b.original : `M${coords( path1, path2, len, v ).join('L')}Z`) );
}
const path1 = a.pathArray; const path2 = b.pathArray; const
len = path2.length;
elem.setAttribute('d', (v === 1 ? b.original : `M${coords(path1, path2, len, v).join('L')}Z`));
};
}
}
@ -18,7 +24,7 @@ const baseSVGMorph = {
component: 'baseSVGMorph',
property: 'path',
Interpolate: coords,
functions: {onStart:onStartSVGMorph}
}
functions: { onStart: onStartSVGMorph },
};
export default baseSVGMorph
export default baseSVGMorph;

View file

@ -1,104 +1,150 @@
import numbers from '../interpolation/numbers.js'
import Components from '../objects/components.js'
import {svgTransformOnStart} from './svgTransformBase.js'
import numbers from '../interpolation/numbers.js';
import { svgTransformOnStart } from './svgTransformBase.js';
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions }
/* const svgTransform = {
property: 'svgTransform',
subProperties,
defaultValue,
Interpolate: {numbers},
functions
} */
// Component Util
function parseStringOrigin (origin, {x, width}) {
return /[a-z]/i.test(origin) && !/px/.test(origin)
? origin.replace(/top|left/,0).replace(/right|bottom/,100).replace(/center|middle/,50)
: /%/.test(origin) ? (x + parseFloat(origin) * width / 100) : parseFloat(origin);
function parseStringOrigin(origin, { x, width }) {
let result;
if (/[a-z]/i.test(origin) && !/px/.test(origin)) {
result = origin.replace(/top|left/, 0)
.replace(/right|bottom/, 100)
.replace(/center|middle/, 50);
} else {
result = /%/.test(origin) ? (x + (parseFloat(origin) * width) / 100) : parseFloat(origin);
}
return result;
}
// helper function that turns transform value from string to object
function parseTransformString (a) {
let d = a && /\)/.test(a) ? a.substring(0, a.length-1).split(/\)\s|\)/) : 'none', c = {};
function parseTransformString(a) {
const c = {};
const d = a && /\)/.test(a)
? a.substring(0, a.length - 1).split(/\)\s|\)/)
: 'none';
if (d instanceof Array) {
for (let j=0, jl = d.length; j<jl; j++){
let p = d[j].trim().split('(');
c[p[0]] = p[1];
for (let j = 0, jl = d.length; j < jl; j += 1) {
const [prop, val] = d[j].trim().split('(');
c[prop] = val;
}
}
return c;
}
function parseTransformSVG (p,v){
let svgTransformObject = {};
function parseTransformSVG(p, v) {
const svgTransformObject = {};
// by default the transformOrigin is "50% 50%" of the shape box
let bb = this.element.getBBox();
let cx = bb.x + bb.width/2;
let cy = bb.y + bb.height/2;
const bb = this.element.getBBox();
const cx = bb.x + bb.width / 2;
const cy = bb.y + bb.height / 2;
let origin = this._transformOrigin;
let translation;
origin = typeof (origin) !== 'undefined' ? (origin.constructor === Array ? origin : origin.split(/\s/)) : [cx,cy];
if (typeof (origin) !== 'undefined') {
origin = origin instanceof Array ? origin : origin.split(/\s/);
} else {
origin = [cx, cy];
}
origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0],bb);
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1],bb);
origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0], bb);
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1], bb);
svgTransformObject.origin = origin;
for ( let i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
svgTransformObject[i] = typeof v[i] === 'number' ? v[i] : v[i] instanceof Array ? v[i][0] : v[i].split(/\s/)[0]*1;
} else if (i === 'translate'){
translation = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(',') : [v[i],0];
svgTransformObject[i] = [translation[0]*1||0, translation[1]*1||0];
// populate the valuesStart and / or valuesEnd
Object.keys(v).forEach((i) => {
if (i === 'rotate') {
if (typeof v[i] === 'number') {
svgTransformObject[i] = v[i];
} else if (v[i] instanceof Array) {
[svgTransformObject[i]] = v[i];
} else {
svgTransformObject[i] = v[i].split(/\s/)[0] * 1;
}
} else if (i === 'translate') {
if (v[i] instanceof Array) {
translation = v[i];
} else if (/,|\s/.test(v[i])) {
translation = v[i].split(',');
} else {
translation = [v[i], 0];
}
svgTransformObject[i] = [translation[0] * 1 || 0, translation[1] * 1 || 0];
} else if (/skew/.test(i)) {
svgTransformObject[i] = v[i]*1||0;
} else if (i === 'scale'){
svgTransformObject[i] = parseFloat(v[i])||1;
svgTransformObject[i] = v[i] * 1 || 0;
} else if (i === 'scale') {
svgTransformObject[i] = parseFloat(v[i]) || 1;
}
}
});
return svgTransformObject;
}
// Component Functions
function prepareSvgTransform(p,v){
return parseTransformSVG.call(this,p,v);
function prepareSvgTransform(p, v) {
return parseTransformSVG.call(this, p, v);
}
// returns an obect with current transform attribute value
function getStartSvgTransform (tweenProp,value) {
function getStartSvgTransform(tweenProp, value) {
const transformObject = {};
const currentTransform = parseTransformString(this.element.getAttribute('transform'));
for (let j in value) {
// find a value in current attribute value or add a default value
transformObject[j] = j in currentTransform ? currentTransform[j] : (j==='scale'?1:0);
}
// find a value in current attribute value or add a default value
Object.keys(value).forEach((j) => {
const scaleValue = j === 'scale' ? 1 : 0;
transformObject[j] = j in currentTransform ? currentTransform[j] : scaleValue;
});
return transformObject;
}
function svgTransformCrossCheck(prop) {
if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method
if ( this.valuesEnd[prop] ) {
let valuesStart = this.valuesStart[prop];
let valuesEnd = this.valuesEnd[prop];
let currentTransform = parseTransformSVG.call(this, prop, parseTransformString(this.element.getAttribute('transform')) );
if (this.valuesEnd[prop]) {
const valuesStart = this.valuesStart[prop];
const valuesEnd = this.valuesEnd[prop];
const currentTransform = parseTransformSVG.call(this, prop,
parseTransformString(this.element.getAttribute('transform')));
// populate the valuesStart first
for ( let tp in currentTransform ) {
Object.keys(currentTransform).forEach((tp) => {
valuesStart[tp] = currentTransform[tp];
}
});
// now try to determine the REAL translation
const parentSVG = this.element.ownerSVGElement;
const startMatrix = parentSVG.createSVGTransformFromMatrix(
parentSVG.createSVGMatrix()
.translate(-valuesStart.origin[0],-valuesStart.origin[1]) // - origin
.translate('translate' in valuesStart ? valuesStart.translate[0] : 0,'translate' in valuesStart ? valuesStart.translate[1] : 0) // the current translate
.rotate(valuesStart.rotate||0).skewX(valuesStart.skewX||0).skewY(valuesStart.skewY||0).scale(valuesStart.scale||1)// the other functions
.translate(+valuesStart.origin[0],+valuesStart.origin[1]) // + origin
.translate(-valuesStart.origin[0], -valuesStart.origin[1]) // - origin
.translate('translate' in valuesStart // the current translate
? valuesStart.translate[0] : 0, 'translate' in valuesStart ? valuesStart.translate[1]
: 0)
.rotate(valuesStart.rotate || 0)
.skewX(valuesStart.skewX || 0)
.skewY(valuesStart.skewY || 0)
.scale(valuesStart.scale || 1)// the other functions
.translate(+valuesStart.origin[0], +valuesStart.origin[1]), // + origin
);
valuesStart.translate = [startMatrix.matrix.e,startMatrix.matrix.f]; // finally the translate we're looking for
// finally the translate we're looking for
valuesStart.translate = [startMatrix.matrix.e, startMatrix.matrix.f];
// copy existing and unused properties to the valuesEnd
for ( let s in valuesStart) {
if ( !(s in valuesEnd) || s==='origin') {
Object.keys(valuesStart).forEach((s) => {
if (!(s in valuesEnd) || s === 'origin') {
valuesEnd[s] = valuesStart[s];
}
}
});
}
}
@ -107,24 +153,23 @@ export const svgTransformFunctions = {
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform,
onStart: svgTransformOnStart,
crossCheck: svgTransformCrossCheck
}
crossCheck: svgTransformCrossCheck,
};
// Component Full
export const svgTransform = {
component: 'svgTransformProperty',
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
defaultOptions: {transformOrigin:'50% 50%'},
defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1},
Interpolate: {numbers},
defaultOptions: { transformOrigin: '50% 50%' },
defaultValue: {
translate: 0, rotate: 0, skewX: 0, skewY: 0, scale: 1,
},
Interpolate: { numbers },
functions: svgTransformFunctions,
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG }
}
Util: { parseStringOrigin, parseTransformString, parseTransformSVG },
};
export default svgTransform
Components.SVGTransformProperty = svgTransform
export default svgTransform;

View file

@ -1,42 +1,54 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions }
/* svgTransform = {
property: 'svgTransform',
subProperties,
defaultValue,
Interpolate: {numbers},
functions
} */
// Component Functions
export function svgTransformOnStart (tweenProp){
export function svgTransformOnStart(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (l, a, b, v) => {
let x = 0;
let y = 0;
let tmp;
const deg = Math.PI/180;
const scale = 'scale' in b ? numbers(a.scale,b.scale,v) : 1;
const rotate = 'rotate' in b ? numbers(a.rotate,b.rotate,v) : 0;
const sin = Math.sin(rotate*deg);
const cos = Math.cos(rotate*deg);
const skewX = 'skewX' in b ? numbers(a.skewX,b.skewX,v) : 0;
const skewY = 'skewY' in b ? numbers(a.skewY,b.skewY,v) : 0;
const complex = rotate||skewX||skewY||scale!==1 || 0;
const deg = Math.PI / 180;
const scale = 'scale' in b ? numbers(a.scale, b.scale, v) : 1;
const rotate = 'rotate' in b ? numbers(a.rotate, b.rotate, v) : 0;
const sin = Math.sin(rotate * deg);
const cos = Math.cos(rotate * deg);
const skewX = 'skewX' in b ? numbers(a.skewX, b.skewX, v) : 0;
const skewY = 'skewY' in b ? numbers(a.skewY, b.skewY, v) : 0;
const complex = rotate || skewX || skewY || scale !== 1 || 0;
// start normalizing the translation, we start from last to first (from last chained translation)
// the normalized translation will handle the transformOrigin tween option and makes sure to have a consistent transformation
x -= complex ? b.origin[0] : 0;y -= complex ? b.origin[1] : 0; // we start with removing transformOrigin from translation
x *= scale;y *= scale; // we now apply the scale
y += skewY ? x*Math.tan(skewY*deg) : 0;x += skewX ? y*Math.tan(skewX*deg) : 0; // now we apply skews
tmp = cos*x - sin*y; // apply rotation as well
y = rotate ? sin*x + cos*y : y;x = rotate ? tmp : x;
x += 'translate' in b ? numbers(a.translate[0],b.translate[0],v) : 0; // now we apply the actual translation
y += 'translate' in b ? numbers(a.translate[1],b.translate[1],v) : 0;
x += complex ? b.origin[0] : 0;y += complex ? b.origin[1] : 0; // normalizing ends with the addition of the transformOrigin to the translation
// start normalizing the translation, we start from last to first
// (from last chained translation)
// the normalized translation will handle the transformOrigin tween option
// and makes sure to have a consistent transformation
// we start with removing transformOrigin from translation
x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0;
x *= scale; y *= scale; // we now apply the scale
// now we apply skews
y += skewY ? x * Math.tan(skewY * deg) : 0; x += skewX ? y * Math.tan(skewX * deg) : 0;
const cxsy = cos * x - sin * y; // apply rotation as well
y = rotate ? sin * x + cos * y : y; x = rotate ? cxsy : x;
// now we apply the actual translation
x += 'translate' in b ? numbers(a.translate[0], b.translate[0], v) : 0;
y += 'translate' in b ? numbers(a.translate[1], b.translate[1], v) : 0;
// normalizing ends with the addition of the transformOrigin to the translation
x += complex ? b.origin[0] : 0; y += complex ? b.origin[1] : 0;
// finally we apply the transform attribute value
l.setAttribute('transform', ( x||y ? (`translate(${(x*1000>>0)/1000}${y ? (`,${(y*1000>>0)/1000}`) : ''})`) : '' )
+( rotate ? `rotate(${(rotate*1000>>0)/1000})` : '' )
+( skewX ? `skewX(${(skewX*1000>>0)/1000})` : '' )
+( skewY ? `skewY(${(skewY*1000>>0)/1000})` : '' )
+( scale !== 1 ? `scale(${(scale*1000>>0)/1000})` : '' ) );
}
l.setAttribute('transform', (x || y ? (`translate(${(x * 1000 >> 0) / 1000}${y ? (`,${(y * 1000 >> 0) / 1000}`) : ''})`) : '')
+ (rotate ? `rotate(${(rotate * 1000 >> 0) / 1000})` : '')
+ (skewX ? `skewX(${(skewX * 1000 >> 0) / 1000})` : '')
+ (skewY ? `skewY(${(skewY * 1000 >> 0) / 1000})` : '')
+ (scale !== 1 ? `scale(${(scale * 1000 >> 0) / 1000})` : ''));
};
}
}
@ -46,9 +58,9 @@ const baseSVGTransform = {
property: 'svgTransform',
// subProperties: ['translate','rotate','skewX','skewY','scale'],
// defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1},
defaultOptions: {transformOrigin:'50% 50%'},
Interpolate: {numbers},
functions: {onStart:svgTransformOnStart}
}
defaultOptions: { transformOrigin: '50% 50%' },
Interpolate: { numbers },
functions: { onStart: svgTransformOnStart },
};
export default baseSVGTransform
export default baseSVGTransform;

View file

@ -1,24 +1,30 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getStyleForProperty from '../process/getStyleForProperty.js'
import trueDimension from '../util/trueDimension.js'
import units from '../interpolation/units.js'
import {textPropOnStart} from './textPropertiesBase.js'
import defaultValues from '../objects/defaultValues.js';
import getStyleForProperty from '../process/getStyleForProperty.js';
import trueDimension from '../util/trueDimension.js';
import units from '../interpolation/units.js';
import { textPropOnStart } from './textPropertiesBase.js';
// const textProperties = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
/* textProperties = {
category: 'textProperties',
defaultValues: [],
interpolators: {units}
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Properties
const textProps = ['fontSize','lineHeight','letterSpacing','wordSpacing']
const textOnStart = {}
const textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
// Component Functions
textProps.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart
})
export function getTextProp(prop) {
return getStyleForProperty(this.element,prop) || defaultValues[prop];
textProps.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
export function getTextProp(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
export function prepareTextProp(prop,value) {
export function prepareTextProp(prop, value) {
return trueDimension(value);
}
@ -26,20 +32,20 @@ export function prepareTextProp(prop,value) {
const textPropFunctions = {
prepareStart: getTextProp,
prepareProperty: prepareTextProp,
onStart: textOnStart
}
onStart: textOnStart,
};
// Component Full
const textProperties = {
component: 'textProperties',
category: 'textProperties',
properties: textProps,
defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
defaultValues: {
fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0,
},
Interpolate: { units },
functions: textPropFunctions,
Util: {trueDimension}
}
Util: { trueDimension },
};
export default textProperties
Components.TextProperties = textProperties
export default textProperties;

View file

@ -1,22 +1,28 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js';
// const opacity = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
/* textProperties = {
category: 'textProperties',
defaultValues: [],
interpolators: {units},
functions = { prepareStart, prepareProperty, onStart:{}
} */
// Component Properties
const textProperties = ['fontSize','lineHeight','letterSpacing','wordSpacing']
const textOnStart = {}
const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
export function textPropOnStart(tweenProp){
export function textPropOnStart(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem,a,b,v) => {
elem.style[tweenProp] = units(a.v,b.v,b.u,v);
}
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = units(a.v, b.v, b.u, v);
};
}
}
textProperties.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart
})
textProperties.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
// Component Base
const baseTextProperties = {
@ -24,8 +30,8 @@ const baseTextProperties = {
category: 'textProps',
// properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
functions: {onStart:textOnStart}
}
Interpolate: { units },
functions: { onStart: textOnStart },
};
export default baseTextProperties
export default baseTextProperties;

View file

@ -1,159 +1,178 @@
import connect from '../objects/connect.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import connect from '../objects/connect.js';
import numbers from '../interpolation/numbers.js';
import {onStartWrite,charSet} from './textWriteBase.js'
import { onStartWrite, charSet } from './textWriteBase.js';
// Component Util
// utility for multi-child targets
// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class
function wrapContentsSpan(el,classNAME){
function wrapContentsSpan(el, classNAME) {
let textWriteWrapper;
let newElem;
if ( typeof(el) === 'string' ) {
newElem = document.createElement('SPAN')
newElem.innerHTML = el
newElem.className = classNAME
return newElem
} else if (!el.children.length || el.children.length && el.children[0].className !== classNAME ) {
let elementInnerHTML = el.innerHTML
textWriteWrapper = document.createElement('SPAN')
textWriteWrapper.className = classNAME
textWriteWrapper.innerHTML = elementInnerHTML
el.appendChild(textWriteWrapper)
el.innerHTML = textWriteWrapper.outerHTML
} else if (el.children.length && el.children[0].className === classNAME){
textWriteWrapper = el.children[0]
if (typeof (el) === 'string') {
newElem = document.createElement('SPAN');
newElem.innerHTML = el;
newElem.className = classNAME;
return newElem;
}
return textWriteWrapper
if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) {
const elementInnerHTML = el.innerHTML;
textWriteWrapper = document.createElement('SPAN');
textWriteWrapper.className = classNAME;
textWriteWrapper.innerHTML = elementInnerHTML;
el.appendChild(textWriteWrapper);
el.innerHTML = textWriteWrapper.outerHTML;
} else if (el.children.length && el.children[0].className === classNAME) {
[textWriteWrapper] = el.children;
}
return textWriteWrapper;
}
function getTextPartsArray(el,classNAME){
let elementsArray = []
if (el.children.length) {
let textParts = [];
function getTextPartsArray(el, classNAME) {
let elementsArray = [];
const len = el.children.length;
if (len) {
const textParts = [];
let remainingMarkup = el.innerHTML;
let wrapperParts;
for ( let i=0, l = el.children.length, currentChild, childOuter, unTaggedContent; i<l; i++) {
currentChild = el.children[i]
childOuter = currentChild.outerHTML
wrapperParts = remainingMarkup.split(childOuter)
for (let i = 0, currentChild, childOuter, unTaggedContent; i < len; i += 1) {
currentChild = el.children[i];
childOuter = currentChild.outerHTML;
wrapperParts = remainingMarkup.split(childOuter);
if (wrapperParts[0] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[0],classNAME)
textParts.push( unTaggedContent )
remainingMarkup = remainingMarkup.replace(wrapperParts[0],'')
unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME);
textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0], '');
} else if (wrapperParts[1] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0],classNAME)
textParts.push( unTaggedContent )
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0],'')
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME);
textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], '');
}
!currentChild.classList.contains(classNAME) && currentChild.classList.add(classNAME)
textParts.push( currentChild )
remainingMarkup = remainingMarkup.replace(childOuter,'')
if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME);
textParts.push(currentChild);
remainingMarkup = remainingMarkup.replace(childOuter, '');
}
if (remainingMarkup!==''){
let unTaggedRemaining = wrapContentsSpan(remainingMarkup,classNAME)
textParts.push( unTaggedRemaining )
if (remainingMarkup !== '') {
const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME);
textParts.push(unTaggedRemaining);
}
elementsArray = elementsArray.concat(textParts)
elementsArray = elementsArray.concat(textParts);
} else {
elementsArray = elementsArray.concat([wrapContentsSpan(el,classNAME)])
elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]);
}
return elementsArray
return elementsArray;
}
function setSegments(target,newText){
const oldTargetSegs = getTextPartsArray( target,'text-part');
const newTargetSegs = getTextPartsArray( wrapContentsSpan( newText ), 'text-part' );
function setSegments(target, newText) {
const oldTargetSegs = getTextPartsArray(target, 'text-part');
const newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part');
target.innerHTML = ''
target.innerHTML += oldTargetSegs.map(s=>{ s.className += ' oldText'; return s.outerHTML }).join('')
target.innerHTML += newTargetSegs.map(s=>{ s.className += ' newText'; return s.outerHTML.replace(s.innerHTML,'') }).join('')
target.innerHTML = '';
target.innerHTML += oldTargetSegs.map((s) => { s.className += ' oldText'; return s.outerHTML; }).join('');
target.innerHTML += newTargetSegs.map((s) => { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join('');
return [oldTargetSegs,newTargetSegs]
return [oldTargetSegs, newTargetSegs];
}
export function createTextTweens(target,newText,options){
if (target.playing) return;
export function createTextTweens(target, newText, ops) {
if (target.playing) return false;
options = options || {}
options.duration = options.duration === 'auto' ? 'auto' : isFinite(options.duration*1) ? options.duration*1 : 1000;
const options = ops || {};
options.duration = 1000;
const segs = setSegments(target,newText);
if (ops.duration === 'auto') {
options.duration = 'auto';
} else if (Number.isFinite(ops.duration * 1)) {
options.duration = ops.duration * 1;
}
const TweenContructor = connect.tween;
const segs = setSegments(target, newText);
const oldTargetSegs = segs[0];
const newTargetSegs = segs[1];
let oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
let newTargets = [].slice.call(target.getElementsByClassName('newText'));
const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
const newTargets = [].slice.call(target.getElementsByClassName('newText'));
let textTween = [], totalDelay = 0
let textTween = [];
let totalDelay = 0;
textTween = textTween.concat(oldTargets.map((el,i) => {
options.duration = options.duration === 'auto' ? oldTargetSegs[i].innerHTML.length * 75 : options.duration;
textTween = textTween.concat(oldTargets.map((el, i) => {
options.duration = options.duration === 'auto'
? oldTargetSegs[i].innerHTML.length * 75
: options.duration;
options.delay = totalDelay;
options.onComplete = null
options.onComplete = null;
totalDelay += options.duration
return new connect.tween(el, {text:el.innerHTML}, {text:''}, options );
totalDelay += options.duration;
return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options);
}));
textTween = textTween.concat(newTargets.map((el,i)=> {
const onComplete = () => {target.innerHTML = newText, target.playing = false};
textTween = textTween.concat(newTargets.map((el, i) => {
function onComplete() {
target.innerHTML = newText;
target.playing = false;
}
options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay;
options.onComplete = i === newTargetSegs.length-1 ? onComplete : null
totalDelay += options.duration
options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null;
totalDelay += options.duration;
return new connect.tween(el, {text:''}, {text:newTargetSegs[i].innerHTML}, options );
return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options);
}));
textTween.start = function(){
!target.playing && textTween.map(tw=>tw.start()) && (target.playing = true)
}
textTween.start = function startTweens() {
if (!target.playing) {
textTween.forEach((tw) => tw.start());
target.playing = true;
}
};
return textTween
return textTween;
}
// Component Functions
function getWrite(tweenProp,value){
function getWrite(/* tweenProp, value */) {
return this.element.innerHTML;
}
function prepareText(tweenProp,value) {
if( tweenProp === 'number' ) {
return parseFloat(value)
} else {
// empty strings crash the update function
return value === '' ? ' ' : value
function prepareText(tweenProp, value) {
if (tweenProp === 'number') {
return parseFloat(value);
}
// empty strings crash the update function
return value === '' ? ' ' : value;
}
// All Component Functions
export const textWriteFunctions = {
prepareStart: getWrite,
prepareProperty: prepareText,
onStart: onStartWrite
}
onStart: onStartWrite,
};
// const textWrite = { category : 'textWrite', defaultValues: {}, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
/* textWrite = {
category: 'textWrite',
defaultValues: {},
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Full Component
export const textWrite = {
component: 'textWriteProperties',
category: 'textWrite',
properties: ['text','number'],
defaultValues: {text: ' ',numbers:'0'},
properties: ['text', 'number'],
defaultValues: { text: ' ', numbers: '0' },
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
Interpolate: { numbers },
functions: textWriteFunctions,
// export to global for faster execution
Util: { charSet, createTextTweens }
}
Util: { charSet, createTextTweens },
};
export default textWrite
Components.TextWriteProperties = textWrite
export default textWrite;

View file

@ -1,66 +1,74 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import defaultOptions from '../objects/defaultOptions.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import defaultOptions from '../objects/defaultOptions.js';
// Component Values
const lowerCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase
upperCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""), // uppercase
nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols
numeric = String("0123456789").split(""), // numeric
alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha,numeric), // alpha numeric
allTypes = alphaNumeric.concat(nonAlpha); // all caracters
const lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase
const upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase
const nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols
const numeric = String('0123456789').split(''); // numeric
const alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric
const allTypes = alphaNumeric.concat(nonAlpha); // all caracters
const charSet = {
alpha: lowerCaseAlpha, // lowercase
upper: upperCaseAlpha, // uppercase
symbols: nonAlpha, // symbols
numeric: numeric,
numeric,
alphanumeric: alphaNumeric,
all: allTypes,
}
};
export {charSet}
export { charSet };
// Component Functions
export const onStartWrite = {
text: function(tweenProp){
if ( !KUTE[tweenProp] && this.valuesEnd[tweenProp] ) {
text(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
const chars = this._textChars;
let charsets = charSet[defaultOptions.textChars];
let chars = this._textChars,
charsets = chars in charSet ? charSet[chars]
: chars && chars.length ? chars
: charSet[defaultOptions.textChars]
if (chars in charSet) {
charsets = charSet[chars];
} else if (chars && chars.length) {
charsets = chars;
}
KUTE[tweenProp] = function(elem,a,b,v) {
let initialText = '',
endText = '',
firstLetterA = a.substring(0),
firstLetterB = b.substring(0),
pointer = charsets[(Math.random() * charsets.length)>>0];
KUTE[tweenProp] = (elem, a, b, v) => {
let initialText = '';
let endText = '';
const finalText = b === '' ? ' ' : b;
const firstLetterA = a.substring(0);
const firstLetterB = b.substring(0);
const pointer = charsets[(Math.random() * charsets.length) >> 0];
if (a === ' ') {
endText = firstLetterB.substring(Math.min(v * firstLetterB.length, firstLetterB.length)>>0, 0 );
elem.innerHTML = v < 1 ? ( ( endText + pointer ) ) : (b === '' ? ' ' : b);
endText = firstLetterB
.substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0);
elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText;
} else if (b === ' ') {
initialText = firstLetterA.substring(0, Math.min((1-v) * firstLetterA.length, firstLetterA.length)>>0 );
elem.innerHTML = v < 1 ? ( ( initialText + pointer ) ) : (b === '' ? ' ' : b);
initialText = firstLetterA
.substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0);
elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText;
} else {
initialText = firstLetterA.substring(firstLetterA.length, Math.min(v * firstLetterA.length, firstLetterA.length)>>0 );
endText = firstLetterB.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length)>>0 );
elem.innerHTML = v < 1 ? ( (endText + pointer + initialText) ) : (b === '' ? ' ' : b);
initialText = firstLetterA
.substring(firstLetterA.length,
Math.min(v * firstLetterA.length, firstLetterA.length) >> 0);
endText = firstLetterB
.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0);
elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText;
}
}
};
}
},
number: function(tweenProp) {
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0
number(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0
KUTE[tweenProp] = (elem, a, b, v) => {
elem.innerHTML = numbers(a, b, v)>>0;
}
elem.innerHTML = numbers(a, b, v) >> 0;
};
}
}
}
},
};
// Base Component
export const baseTextWrite = {
@ -69,10 +77,10 @@ export const baseTextWrite = {
// properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
functions: {onStart:onStartWrite},
Interpolate: { numbers },
functions: { onStart: onStartWrite },
// export to global for faster execution
Util: { charSet }
}
Util: { charSet },
};
export default baseTextWrite
export default baseTextWrite;

View file

@ -1,65 +1,89 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getInlineStyle from '../process/getInlineStyle.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import {onStartTransform} from './transformFunctionsBase.js'
import defaultValues from '../objects/defaultValues.js';
import getInlineStyle from '../process/getInlineStyle.js';
import perspective from '../interpolation/perspective.js';
import translate3d from '../interpolation/translate3d.js';
import rotate3d from '../interpolation/rotate3d.js';
import translate from '../interpolation/translate.js';
import rotate from '../interpolation/rotate.js';
import scale from '../interpolation/scale.js';
import skew from '../interpolation/skew.js';
import { onStartTransform } from './transformFunctionsBase.js';
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
/* transformFunctions = {
property: 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// same to svg transform, attr
// the component developed for modern browsers supporting non-prefixed transform
// Component Functions
function getTransform(tweenProperty,value){
let currentStyle = getInlineStyle(this.element);
function getTransform(tweenProperty/* , value */) {
const currentStyle = getInlineStyle(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
function prepareTransform(prop,obj){
let prepAxis = ['X', 'Y', 'Z'], // coordinates
transformObject = {},
translateArray = [], rotateArray = [], skewArray = [],
arrayFunctions = ['translate3d','translate','rotate3d','skew']
for (let x in obj) {
let pv = typeof obj[x] === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x]);
function prepareTransform(prop, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
const transformObject = {};
const translateArray = []; const rotateArray = []; const skewArray = [];
const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew'];
Object.keys(obj).forEach((x) => {
const pv = typeof obj[x] === 'object' && obj[x].length
? obj[x].map((v) => parseInt(v, 10))
: parseInt(obj[x], 10);
if (arrayFunctions.includes(x)) {
let propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
transformObject[propId] = x === 'skew' ? (pv.length ? [pv[0]||0, pv[1]||0] : [pv||0,0] )
: x === 'translate' ? (pv.length ? [pv[0]||0, pv[1]||0, pv[2]||0] : [pv||0,0,0] )
: [pv[0]||0, pv[1]||0,pv[2]||0] // translate3d | rotate3d
if (x === 'skew') {
transformObject[propId] = pv.length
? [pv[0] || 0, pv[1] || 0]
: [pv || 0, 0];
} else if (x === 'translate') {
transformObject[propId] = pv.length
? [pv[0] || 0, pv[1] || 0, pv[2] || 0]
: [pv || 0, 0, 0];
} else { // translate3d | rotate3d
transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0];
}
} else if (/[XYZ]/.test(x)) {
const fn = x.replace(/[XYZ]/, '');
const fnId = fn === 'skew' ? fn : `${fn}3d`;
const fnLen = fn === 'skew' ? 2 : 3;
let fnArray = [];
} else if ( /[XYZ]/.test(x) ) {
let fn = x.replace(/[XYZ]/,''),
fnId = fn === 'skew' ? fn : `${fn}3d`,
fnLen = fn === 'skew' ? 2 : 3,
fnArray = fn === 'translate' ? translateArray
: fn === 'rotate' ? rotateArray
: fn === 'skew' ? skewArray : {}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex++) {
let fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`]) : 0;
if (fn === 'translate') {
fnArray = translateArray;
} else if (fn === 'rotate') {
fnArray = rotateArray;
} else if (fn === 'skew') {
fnArray = skewArray;
}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) {
const fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0;
}
transformObject[fnId] = fnArray;
} else if (x==='rotate') { // rotate
transformObject['rotate3d'] = [0,0,pv]
} else if (x === 'rotate') { // rotate
transformObject.rotate3d = [0, 0, pv];
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
}
}
});
return transformObject;
}
function crossCheckTransform(tweenProp){
function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if ( this.valuesEnd[tweenProp] ) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
@ -70,24 +94,34 @@ const transformFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
crossCheck: crossCheckTransform
}
crossCheck: crossCheckTransform,
};
const supportedTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale'
]
'scale',
];
const defaultTransformValues = {
perspective: 400,
translate3d : [0,0,0], translateX : 0, translateY : 0, translateZ : 0, translate : [0,0],
rotate3d: [0,0,0], rotateX : 0, rotateY : 0, rotateZ : 0, rotate : 0,
skewX : 0, skewY : 0, skew: [0,0],
scale : 1
}
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
translate: [0, 0],
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
rotate: 0,
skewX: 0,
skewY: 0,
skew: [0, 0],
scale: 1,
};
// Full Component
const transformFunctionsComponent = {
@ -97,13 +131,14 @@ const transformFunctionsComponent = {
defaultValues: defaultTransformValues,
functions: transformFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default transformFunctionsComponent
Components.TransformFunctions = transformFunctionsComponent
export default transformFunctionsComponent;

View file

@ -1,25 +1,31 @@
import KUTE from '../objects/kute.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import KUTE from '../objects/kute.js';
import perspective from '../interpolation/perspective.js';
import translate3d from '../interpolation/translate3d.js';
import rotate3d from '../interpolation/rotate3d.js';
import translate from '../interpolation/translate.js';
import rotate from '../interpolation/rotate.js';
import scale from '../interpolation/scale.js';
import skew from '../interpolation/skew.js';
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
/* transformFunctions = {
property: 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// same to svg transform, attr
// Component Functions
export function onStartTransform(tweenProp){
export function onStartTransform(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] =
(a.perspective||b.perspective ? perspective(a.perspective,b.perspective,'px',v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d,b.translate3d,'px',v):'') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d,b.rotate3d,'deg',v):'') // array [x,y,z]
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z]
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
}
}
@ -27,13 +33,16 @@ export function onStartTransform(tweenProp){
const BaseTransform = {
component: 'baseTransform',
property: 'transform',
functions: {onStart: onStartTransform},
functions: { onStart: onStartTransform },
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default BaseTransform
export default BaseTransform;

View file

@ -1,89 +1,107 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import getInlineStyleLegacy from '../process/getInlineStyleLegacy.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js';
import defaultValues from '../objects/defaultValues.js';
import getInlineStyleLegacy from '../process/getInlineStyleLegacy.js';
import perspective from '../interpolation/perspective.js';
import translate3d from '../interpolation/translate3d.js';
import rotate3d from '../interpolation/rotate3d.js';
import translate from '../interpolation/translate.js';
import rotate from '../interpolation/rotate.js';
import scale from '../interpolation/scale.js';
import skew from '../interpolation/skew.js';
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js'
import {onStartLegacyTransform} from './transformLegacyBase.js'
import transformProperty from '../util/transformProperty.js'
import supportTransform from '../util/supportLegacyTransform.js'
import { onStartLegacyTransform } from './transformLegacyBase.js';
import transformProperty from '../util/transformProperty.js';
import supportTransform from '../util/supportLegacyTransform.js';
/* transformFunctions = {
property : 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// same to svg transform, attr
// the component to handle all kinds of input values and process according to browser supported API,
// the component that handles all browsers IE9+
// Component Functions
function getLegacyTransform(tweenProperty,value){
function getLegacyTransform(tweenProperty/* , value */) {
const currentStyle = getInlineStyleLegacy(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
function prepareLegacyTransform(prop,obj){
let prepAxis = ['X', 'Y', 'Z'], // coordinates
translateArray = [], rotateArray = [], skewArray = [],
transformObject = {},
arrayFunctions = ['translate3d','translate','rotate3d','skew']
function prepareLegacyTransform(prop, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
const translateArray = []; const rotateArray = []; const skewArray = [];
const transformObject = {};
const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew'];
for (let x in obj) {
let pv = typeof(obj[x]) === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x])
Object.keys(obj).forEach((x) => {
const pv = typeof (obj[x]) === 'object' && obj[x].length
? obj[x].map((v) => parseInt(v, 10))
: parseInt(obj[x], 10);
if (arrayFunctions.includes(x)) {
if (support3DTransform){
if (x==='translate3d' || x==='rotate3d') {
transformObject[x] = pv
} else if (x==='translate'){
transformObject['translate3d'] = pv.length ? pv.concat(0) : [pv||0,0,0]
} else if (x==='rotate'){
transformObject['rotate3d'] = [0,0,pv||0]
} else if (x==='skew'){
transformObject[x] = pv.length ? pv : [pv||0,0]
if (support3DTransform) {
if (x === 'translate3d' || x === 'rotate3d') {
transformObject[x] = pv;
} else if (x === 'translate') {
transformObject.translate3d = pv.length ? pv.concat(0) : [pv || 0, 0, 0];
} else if (x === 'rotate') {
transformObject.rotate3d = [0, 0, pv || 0];
} else if (x === 'skew') {
transformObject[x] = pv.length ? pv : [pv || 0, 0];
}
} else if (supportTransform) {
if (x==='translate3d') {
transformObject['translate'] = [pv[0]||0,pv[1]||0]
} else if (x==='translate' || x==='skew'){
transformObject[x] = pv.length ? pv : [pv||0,0]
} else if (x==='rotate3d'){
transformObject['rotate'] = pv[2]||pv[1]||pv[0]
} else if (x==='rotate'){
transformObject[x] = pv
if (x === 'translate3d') {
transformObject.translate = [pv[0] || 0, pv[1] || 0];
} else if (x === 'translate' || x === 'skew') {
transformObject[x] = pv.length ? pv : [pv || 0, 0];
} else if (x === 'rotate3d') {
transformObject.rotate = pv[2] || pv[1] || pv[0];
} else if (x === 'rotate') {
transformObject[x] = pv;
}
}
} else if (/[XYZ]/.test(x)) {
const fn = x.replace(/[XYZ]/, '');
const fnId = fn === 'skew' || !support3DTransform ? fn : `${fn}3d`;
const fnLen = fn === 'skew' || (!support3DTransform && fn === 'translate') ? 2 : 3;
let fnArray = [];
} else if ( /[XYZ]/.test(x) ) {
let fn = x.replace(/[XYZ]/,''),
fnId = fn === 'skew' || !support3DTransform ? fn : `${fn}3d`,
fnLen = fn === 'skew' || (!support3DTransform && fn === 'translate') ? 2 : 3,
fnArray = fn === 'translate' ? translateArray
: fn === 'rotate' && support3DTransform ? rotateArray
: fn === 'skew' ? skewArray : {}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex++) {
let fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`]) : 0;
if (fn === 'translate') {
fnArray = translateArray;
} else if (fn === 'rotate') {
fnArray = rotateArray;
} else if (fn === 'skew') {
fnArray = skewArray;
}
transformObject[fnId] = support3DTransform ? fnArray : fn === 'rotate' ? fnArray[2]||fnArray[1]||fnArray[0] : fnArray;
} else if (x==='rotate') { // 2d rotate
let pType = support3DTransform ? 'rotate3d' : 'rotate';
transformObject[pType] = support3DTransform ? [0,0,pv] : pv
for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) {
const fnAxis = prepAxis[fnIndex];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0;
}
if (support3DTransform) {
transformObject[fnId] = fnArray;
} else {
transformObject[fnId] = fn === 'rotate' ? (fnArray[2] || fnArray[1] || fnArray[0]) : fnArray;
}
} else if (x === 'rotate') { // 2d rotate
const pType = support3DTransform ? 'rotate3d' : 'rotate';
transformObject[pType] = support3DTransform ? [0, 0, pv] : pv;
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
}
}
});
return transformObject;
}
function crossCheckLegacyTransform(tweenProp){
function crossCheckLegacyTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if ( this.valuesEnd[tweenProp] && support3DTransform) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
if (this.valuesEnd[tweenProp] && support3DTransform) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
@ -94,24 +112,34 @@ const transformLegacyFunctions = {
prepareStart: getLegacyTransform,
prepareProperty: prepareLegacyTransform,
onStart: onStartLegacyTransform,
crossCheck: crossCheckLegacyTransform
}
crossCheck: crossCheckLegacyTransform,
};
const legacyTransformValues = {
perspective: 400,
translate3d: [0,0,0], translateX: 0, translateY: 0, translateZ: 0, translate: [0,0],
rotate3d: [0,0,0], rotateX: 0, rotateY: 0, rotateZ: 0, rotate: 0,
skewX: 0, skewY: 0, skew: [0,0],
scale: 1
}
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
translate: [0, 0],
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
rotate: 0,
skewX: 0,
skewY: 0,
skew: [0, 0],
scale: 1,
};
const legacyTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale'
]
'scale',
];
// Full Component
const transformLegacyComponent = {
@ -121,14 +149,15 @@ const transformLegacyComponent = {
defaultValues: legacyTransformValues,
functions: transformLegacyFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: [transformProperty]
}
Util: [transformProperty],
};
export default transformLegacyComponent
Components.TransformLegacy = transformLegacyComponent
export default transformLegacyComponent;

View file

@ -1,40 +1,44 @@
import KUTE from '../objects/kute.js'
import perspective from '../interpolation/perspective.js'
import translate3d from '../interpolation/translate3d.js'
import rotate3d from '../interpolation/rotate3d.js'
import translate from '../interpolation/translate.js'
import rotate from '../interpolation/rotate.js'
import scale from '../interpolation/scale.js'
import skew from '../interpolation/skew.js'
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js';
import KUTE from '../objects/kute.js';
import perspective from '../interpolation/perspective.js';
import translate3d from '../interpolation/translate3d.js';
import rotate3d from '../interpolation/rotate3d.js';
import translate from '../interpolation/translate.js';
import rotate from '../interpolation/rotate.js';
import scale from '../interpolation/scale.js';
import skew from '../interpolation/skew.js';
import support3DTransform from 'shorter-js/src/boolean/support3DTransform.js'
import supportTransform from '../util/supportLegacyTransform.js'
import transformProperty from '../util/transformProperty.js'
import supportTransform from '../util/supportLegacyTransform.js';
import transformProperty from '../util/transformProperty.js';
/* baseLegacyTransform = {
property: 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// const baseLegacyTransform = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// same to svg transform, attr
// the component that handles all browsers IE9+
// Component Functions
export function onStartLegacyTransform(tweenProp){
export function onStartLegacyTransform(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
if (support3DTransform){
if (support3DTransform) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] =
(a.perspective||b.perspective ? perspective(a.perspective,b.perspective,'px',v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d,b.translate3d,'px',v):'') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d,b.rotate3d,'deg',v):'') // array [x,y,z]
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
elem.style[transformProperty] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0
+ (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z]
+ (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z]
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
} else if (supportTransform) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[transformProperty] =
(a.translate ? translate(a.translate,b.translate,'px',v):'') // array [x,y]
+ ((a.rotate||b.rotate) ? rotate(a.rotate,b.rotate,'deg',v):'') // one side might be 0
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y]
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0
}
elem.style[transformProperty] = (a.translate ? translate(a.translate, b.translate, 'px', v) : '') // array [x,y]
+ ((a.rotate || b.rotate) ? rotate(a.rotate, b.rotate, 'deg', v) : '') // one side might be 0
+ (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
+ (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
};
}
}
}
@ -43,14 +47,17 @@ export function onStartLegacyTransform(tweenProp){
const BaseLegacyTransform = {
component: 'baseLegacyTransform',
property: 'transform',
functions: {onStart: onStartLegacyTransform},
functions: { onStart: onStartLegacyTransform },
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: {transformProperty}
}
Util: { transformProperty },
};
export default BaseLegacyTransform
export default BaseLegacyTransform;

View file

@ -1,88 +1,106 @@
import defaultValues from '../objects/defaultValues.js'
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import arrays from '../interpolation/arrays.js'
import {onStartTransform} from './transformMatrixBase.js'
import defaultValues from '../objects/defaultValues.js';
import numbers from '../interpolation/numbers.js';
import arrays from '../interpolation/arrays.js';
import { onStartTransform } from './transformMatrixBase.js';
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* transformMatrix = {
property : 'transform',
defaultValue: {},
interpolators: {}
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component name
const matrixComponent = 'transformMatrix'
const matrixComponent = 'transformMatrix';
// Component Functions
function getTransform(tweenProp, value){
let transformObject = {}
function getTransform(tweenProp, value) {
const transformObject = {};
const currentValue = this.element[matrixComponent];
if (this.element[matrixComponent]) {
const currentValue = this.element[matrixComponent]
for (const vS in currentValue) {
transformObject[vS] = currentValue[vS]
}
if (currentValue) {
Object.keys(currentValue).forEach((vS) => {
transformObject[vS] = currentValue[vS];
});
} else {
for (const vE in value){
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE]
}
Object.keys(value).forEach((vE) => {
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE];
});
}
return transformObject
return transformObject;
}
function prepareTransform(tweenProp,value){
if ( typeof(value) === 'object' && !value.length) {
let pv,
transformObject = {},
translate3dObj = {},
rotate3dObj = {},
scale3dObj = {},
skewObj = {},
axis = [{translate3d:translate3dObj},{rotate3d:rotate3dObj},{skew:skewObj},{scale3d:scale3dObj}];
for (const prop in value) {
if ( /3d/.test(prop) && typeof(value[prop]) === 'object' && value[prop].length ){
pv = value[prop].map( (v) => prop === 'scale3d' ? parseFloat(v) : parseInt(v) )
transformObject[prop] = prop === 'scale3d' ? [pv[0]||1, pv[1]||1, pv[2]||1] : [pv[0]||0, pv[1]||0, pv[2]||0]
} else if ( /[XYZ]/.test(prop) ) {
let obj = /translate/.test(prop) ? translate3dObj
: /rotate/.test(prop) ? rotate3dObj
: /scale/.test(prop) ? scale3dObj
: /skew/.test(prop) ? skewObj : {};
let idx = prop.replace(/translate|rotate|scale|skew/,'').toLowerCase()
obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop])
} else if ('skew' === prop ) {
pv = value[prop].map(v => parseInt(v)||0)
transformObject[prop] = [pv[0]||0, pv[1]||0]
function prepareTransform(tweenProp, value) {
if (typeof (value) === 'object' && !value.length) {
let pv;
const transformObject = {};
const translate3dObj = {};
const rotate3dObj = {};
const scale3dObj = {};
const skewObj = {};
const axis = [{ translate3d: translate3dObj },
{ rotate3d: rotate3dObj },
{ skew: skewObj },
{ scale3d: scale3dObj }];
Object.keys(value).forEach((prop) => {
if (/3d/.test(prop) && typeof (value[prop]) === 'object' && value[prop].length) {
pv = value[prop].map((v) => (prop === 'scale3d' ? parseFloat(v) : parseInt(v, 10)));
transformObject[prop] = prop === 'scale3d' ? [pv[0] || 1, pv[1] || 1, pv[2] || 1] : [pv[0] || 0, pv[1] || 0, pv[2] || 0];
} else if (/[XYZ]/.test(prop)) {
let obj = {};
if (/translate/.test(prop)) {
obj = translate3dObj;
} else if (/rotate/.test(prop)) {
obj = rotate3dObj;
} else if (/scale/.test(prop)) {
obj = scale3dObj;
} else if (/skew/.test(prop)) {
obj = skewObj;
}
const idx = prop.replace(/translate|rotate|scale|skew/, '').toLowerCase();
obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop], 10);
} else if (prop === 'skew') {
pv = value[prop].map((v) => parseInt(v, 10) || 0);
transformObject[prop] = [pv[0] || 0, pv[1] || 0];
} else { // perspective
transformObject[prop] = parseInt(value[prop]);
transformObject[prop] = parseInt(value[prop], 10);
}
}
});
axis.map((o) => {
let tp = Object.keys(o)[0], tv = o[tp]
if ( Object.keys(tv).length && !transformObject[tp]) {
transformObject[tp] = tp === 'scale3d' ? [tv.x || 1, tv.y || 1, tv.z || 1]
: tp === 'skew' ? [tv.x || 0, tv.y || 0]
: [tv.x || 0, tv.y || 0, tv.z || 0]; // translate|rotate
axis.forEach((o) => {
const tp = Object.keys(o)[0];
const tv = o[tp];
if (Object.keys(tv).length && !transformObject[tp]) {
if (tp === 'scale3d') {
transformObject[tp] = [tv.x || 1, tv.y || 1, tv.z || 1];
} else if (tp === 'skew') {
transformObject[tp] = [tv.x || 0, tv.y || 0];
} else { // translate | rotate
transformObject[tp] = [tv.x || 0, tv.y || 0, tv.z || 0];
}
}
})
});
return transformObject;
} else { // string | array
} // string | array
// if ( typeof (value) === 'object' && value.length ) {
// } else if ( typeof (value) === string && value.includes('matrix')) {
// decompose matrix to object
console.error(`KUTE.js - "${value}" is not valid/supported transform function`)
}
// decompose matrix to object
throw Error(`KUTE.js - "${value}" is not valid/supported transform function`);
}
function onCompleteTransform(tweenProp){
function onCompleteTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
this.element[matrixComponent] = {}
for (const tf in this.valuesEnd[tweenProp]){
this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf]
}
this.element[matrixComponent] = {};
Object.keys(this.valuesEnd[tweenProp]).forEach((tf) => {
this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf];
});
}
}
function crossCheckTransform(tweenProp){
function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
@ -93,25 +111,44 @@ const matrixFunctions = {
prepareProperty: prepareTransform,
onStart: onStartTransform,
onComplete: onCompleteTransform,
crossCheck: crossCheckTransform
}
crossCheck: crossCheckTransform,
};
// Component Full Object
const matrixTransform = {
component: matrixComponent,
property: 'transform',
// subProperties: ['perspective','translate3d','translateX','translateY','translateZ','rotate3d','rotateX','rotateY','rotateZ','skew','skewX','skewY','scale3d','scaleX','scaleY','scaleZ'],
defaultValue: {perspective:400,translate3d:[0,0,0],translateX:0,translateY:0,translateZ:0,rotate3d:[0,0,0],rotateX:0,rotateY:0,rotateZ:0,skew:[0,0],skewX:0,skewY:0,scale3d:[1,1,1],scaleX:1,scaleY:1,scaleZ:1},
/* subProperties: [
'perspective', 'translate3d', 'translateX', 'translateY', 'translateZ',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ',
'skew','skewX','skewY',
'scale3d', 'scaleX', 'scaleY', 'scaleZ'], */
defaultValue: {
perspective: 400,
translate3d: [0, 0, 0],
translateX: 0,
translateY: 0,
translateZ: 0,
rotate3d: [0, 0, 0],
rotateX: 0,
rotateY: 0,
rotateZ: 0,
skew: [0, 0],
skewX: 0,
skewY: 0,
scale3d: [1, 1, 1],
scaleX: 1,
scaleY: 1,
scaleZ: 1,
},
functions: matrixFunctions,
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
scale3d: arrays,
},
};
export default matrixTransform
Components.TransformMatrix = matrixTransform
export default matrixTransform;

View file

@ -1,62 +1,81 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
import arrays from '../interpolation/arrays.js'
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import arrays from '../interpolation/arrays.js';
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
/* transformMatrix = {
property : 'transform',
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component name
const matrixComponent = 'transformMatrixBase'
const matrixComponent = 'transformMatrixBase';
// Component special
const CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix
: null
// this component is restricted to modern browsers only
const CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
// Component Functions
export const onStartTransform = {
transform : function(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
transform(tweenProp) {
if (CSS3Matrix && this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix(), transformObject = {}
let matrix = new CSS3Matrix();
const tObject = {};
for ( const p in b ) {
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v)
Object.keys(b).forEach((p) => {
tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v);
});
// set perspective
if (tObject.perspective) matrix.m34 = -1 / tObject.perspective;
// set translate
matrix = tObject.translate3d
? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2])
: matrix;
// set rotation
matrix = tObject.rotate3d
? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2])
: matrix;
// set skew
if (tObject.skew) {
matrix = tObject.skew[0] ? matrix.skewX(tObject.skew[0]) : matrix;
matrix = tObject.skew[1] ? matrix.skewY(tObject.skew[1]) : matrix;
}
transformObject.perspective && (matrix.m34 = -1/transformObject.perspective)// set perspective
matrix = transformObject.translate3d ? (matrix.translate(transformObject.translate3d[0],transformObject.translate3d[1],transformObject.translate3d[2])) : matrix // set translate
matrix = transformObject.rotate3d ? (matrix.rotate(transformObject.rotate3d[0],transformObject.rotate3d[1],transformObject.rotate3d[2])) : matrix // set rotation
if (transformObject.skew) { // set skew
matrix = transformObject.skew[0] ? matrix.skewX(transformObject.skew[0]) : matrix;
matrix = transformObject.skew[1] ? matrix.skewY(transformObject.skew[1]) : matrix;
}
matrix = transformObject.scale3d ? (matrix.scale(transformObject.scale3d[0],transformObject.scale3d[1],transformObject.scale3d[2])): matrix // set scale
elem.style[tweenProp] = matrix.toString() // set element style
}
// set scale
matrix = tObject.scale3d
? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2])
: matrix;
// set element style
elem.style[tweenProp] = matrix.toString();
};
}
},
CSS3Matrix: function(prop) {
if (this.valuesEnd.transform){
!KUTE[prop] && (KUTE[prop] = CSS3Matrix)
CSS3Matrix(prop) {
if (CSS3Matrix && this.valuesEnd.transform) {
if (!KUTE[prop]) KUTE[prop] = CSS3Matrix;
}
},
}
};
// Component Base Object
export const baseMatrixTransform = {
component: matrixComponent,
property: 'transform',
functions: {onStart: onStartTransform},
functions: { onStart: onStartTransform },
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
scale3d: arrays,
},
};
export default baseMatrixTransform
export default baseMatrixTransform;

View file

@ -1,2 +1,3 @@
import Tweens from '../objects/tweens.js'
export default (tw) => Tweens.push(tw)
import Tweens from '../objects/tweens.js';
export default (tw) => Tweens.push(tw);

View file

@ -1,2 +1,3 @@
import Tweens from '../objects/tweens.js'
export default () => Tweens
import Tweens from '../objects/tweens.js';
export default () => Tweens;

View file

@ -1,9 +1,9 @@
import add from './add.js'
import remove from './remove.js'
import getAll from './getAll.js'
import removeAll from './removeAll.js'
import {stop} from './render.js'
import linkInterpolation from './linkInterpolation.js'
import add from './add.js';
import remove from './remove.js';
import getAll from './getAll.js';
import removeAll from './removeAll.js';
import { stop } from './render.js';
import linkInterpolation from './linkInterpolation.js';
export default {
add,
@ -11,5 +11,5 @@ export default {
getAll,
removeAll,
stop,
linkInterpolation
}
linkInterpolation,
};

View file

@ -1,34 +1,32 @@
import KUTE from '../objects/kute.js'
import linkProperty from '../objects/linkProperty.js'
import supportedProperties from '../objects/supportedProperties.js'
import KUTE from '../objects/kute.js';
import linkProperty from '../objects/linkProperty.js';
import supportedProperties from '../objects/supportedProperties.js';
export default function() { // DON'T change
for (const component in linkProperty){
const componentLink = linkProperty[component]
const componentProps = supportedProperties[component]
export default function linkInterpolation() { // DON'T change
Object.keys(linkProperty).forEach((component) => {
const componentLink = linkProperty[component];
const componentProps = supportedProperties[component];
for ( const fnObj in componentLink ) {
if ( typeof(componentLink[fnObj]) === 'function'
&& Object.keys(this.valuesEnd).some(i => componentProps && componentProps.includes(i)
|| i=== 'attr' && Object.keys(this.valuesEnd[i]).some(j => componentProps && componentProps.includes(j)) ) )
{ // ATTR, colors, scroll, boxModel, borderRadius
!KUTE[fnObj] && (KUTE[fnObj] = componentLink[fnObj])
Object.keys(componentLink).forEach((fnObj) => {
if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius
&& Object.keys(this.valuesEnd).some((i) => (componentProps && componentProps.includes(i))
|| (i === 'attr' && Object.keys(this.valuesEnd[i]).some((j) => componentProps && componentProps.includes(j))))) {
if (!KUTE[fnObj]) KUTE[fnObj] = componentLink[fnObj];
} else {
for ( const prop in this.valuesEnd ) {
for ( const i in this.valuesEnd[prop] ) {
if ( typeof(componentLink[i]) === 'function' ) { // transformCSS3
!KUTE[i] && (KUTE[i] = componentLink[i])
Object.keys(this.valuesEnd).forEach((prop) => {
Object.keys(this.valuesEnd[prop]).forEach((i) => {
if (typeof (componentLink[i]) === 'function') { // transformCSS3
if (!KUTE[i]) KUTE[i] = componentLink[i];
} else {
for (const j in componentLink[fnObj]){
if (componentLink[i] && typeof(componentLink[i][j]) === 'function' ) { // transformMatrix
!KUTE[j] && (KUTE[j] = componentLink[i][j])
Object.keys(componentLink[fnObj]).forEach((j) => {
if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix
if (!KUTE[j]) KUTE[j] = componentLink[i][j];
}
}
});
}
}
}
});
});
}
}
}
});
});
}

View file

@ -1,17 +1,18 @@
import onStart from '../objects/onStart.js'
import linkInterpolation from './linkInterpolation.js'
import onStart from '../objects/onStart.js';
import linkInterpolation from './linkInterpolation.js';
export default function(){
export default function queueStart() {
// fire onStart actions
for (let obj in onStart) {
Object.keys(onStart).forEach((obj) => {
if (typeof (onStart[obj]) === 'function') {
onStart[obj].call(this,obj) // easing functions
onStart[obj].call(this, obj); // easing functions
} else {
for (let prop in onStart[obj]) {
onStart[obj][prop].call(this,prop);
}
Object.keys(onStart[obj]).forEach((prop) => {
onStart[obj][prop].call(this, prop);
});
}
}
});
// add interpolations
linkInterpolation.call(this)
linkInterpolation.call(this);
}

View file

@ -1,5 +1,6 @@
import Tweens from '../objects/tweens.js'
import Tweens from '../objects/tweens.js';
export default (tw) => {
let i = Tweens.indexOf(tw)
i !== -1 && Tweens.splice(i, 1)
}
const i = Tweens.indexOf(tw);
if (i !== -1) Tweens.splice(i, 1);
};

View file

@ -1,2 +1,3 @@
import Tweens from '../objects/tweens.js'
export default () => { Tweens.length = 0 }
import Tweens from '../objects/tweens.js';
export default () => { Tweens.length = 0; };

View file

@ -1,31 +1,28 @@
import KUTE from '../objects/kute.js'
import Tweens from '../objects/tweens.js'
import globalObject from '../objects/globalObject.js'
import Interpolate from '../objects/interpolate.js'
import onStart from '../objects/onStart.js'
import KUTE from '../objects/kute.js';
import Tweens from '../objects/tweens.js';
import globalObject from '../objects/globalObject.js';
import Interpolate from '../objects/interpolate.js';
import onStart from '../objects/onStart.js';
// const Time = window.performance
const Time = {};
const that = window.self || window || {};
Time.now = that.performance.now.bind(that.performance);
const Time = {}
Time.now = self.performance.now.bind(self.performance)
// export {Time}
let Tick = 0;
export { Tick };
let Tick = 0
export {Tick}
let Ticker = (time) => {
const Ticker = (time) => {
let i = 0;
while ( i < Tweens.length ) {
if ( Tweens[i].update(time) ) {
i++;
while (i < Tweens.length) {
if (Tweens[i].update(time)) {
i += 1;
} else {
Tweens.splice(i, 1);
}
}
Tick = requestAnimationFrame(Ticker);
}
export {Ticker}
};
export { Ticker };
// stop requesting animation frame
export function stop() {
@ -33,29 +30,33 @@ export function stop() {
if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick);
Tick = null;
for (let obj in onStart) {
Object.keys(onStart).forEach((obj) => {
if (typeof (onStart[obj]) === 'function') {
KUTE[obj] && (delete KUTE[obj])
if (KUTE[obj]) delete KUTE[obj];
} else {
for (let prop in onStart[obj]) {
KUTE[prop] && (delete KUTE[prop])
}
Object.keys(onStart[obj]).forEach((prop) => {
if (KUTE[prop]) delete KUTE[prop];
});
}
}
for (let i in Interpolate) {
KUTE[i] && (delete KUTE[i])
}
});
Object.keys(Interpolate).forEach((i) => {
if (KUTE[i]) delete KUTE[i];
});
}
},64)
}, 64);
}
// KUTE.js render update functions
// ===============================
const Render = {Tick,Ticker,Tweens,Time}
for ( const blob in Render ) {
const Render = {
Tick, Ticker, Tweens, Time,
};
Object.keys(Render).forEach((blob) => {
if (!KUTE[blob]) {
KUTE[blob] = blob === 'Time' ? Time.now : Render[blob];
}
}
export default Render
globalObject[`_KUTE`] = KUTE
});
export default Render;
globalObject._KUTE = KUTE;

View file

@ -1,36 +1,45 @@
import connect from '../objects/connect.js'
import connect from '../objects/connect.js';
// Select Robert Penner's Easing Functions
// updated for ESLint
const Easing = {
linear : (t) => t,
easingQuadraticIn : (t) => t*t,
easingQuadraticOut : (t) => t*(2-t),
easingQuadraticInOut : (t) => t<.5 ? 2*t*t : -1+(4-2*t)*t,
easingCubicIn : (t) => t*t*t,
easingCubicOut : (t) => (--t)*t*t+1,
easingCubicInOut : (t) => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,
easingCircularIn : (t) => -(Math.sqrt(1 - (t * t)) - 1),
easingCircularOut : (t) => Math.sqrt(1 - (t = t - 1) * t),
easingCircularInOut : (t) => ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
easingBackIn : (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s) },
easingBackOut : (t) => { const s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 },
easingBackInOut : (t) => {
linear: (t) => t,
easingQuadraticIn: (t) => t * t,
easingQuadraticOut: (t) => t * (2 - t),
easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
easingCubicIn: (t) => t * t * t,
easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; },
easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1),
easingCircularOut: (t0) => { const t = t0 - 1; Math.sqrt(1 - t * t); },
easingCircularInOut: (t0) => {
let t = t0 * 2;
if (t < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1);
t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1);
},
easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); },
easingBackOut: (t0) => {
const s = 1.70158;
const t = t0 - 1;
return t * t * ((s + 1) * t + s) + 1;
},
easingBackInOut: (t0) => {
const s = 1.70158 * 1.525;
if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s))
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2)
}
}
let t = t0 * 2;
if (t < 1) return 0.5 * (t * t * ((s + 1) * t - s));
t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2);
},
};
function processEasing(fn) {
if ( typeof fn === 'function') {
if (typeof fn === 'function') {
return fn;
} else if ( typeof Easing[fn] === 'function' ) {
} if (typeof Easing[fn] === 'function') {
return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
}
return Easing.linear;
}
connect.processEasing = processEasing
connect.processEasing = processEasing;
export default Easing
export default Easing;

View file

@ -1,57 +1,56 @@
import connect from '../objects/connect.js'
import CubicBezier from 'cubic-bezier-easing'
import CubicBezier from 'cubic-bezier-easing';
import connect from '../objects/connect.js';
const Easing = {
linear : new CubicBezier(0, 0, 1, 1,'linear'),
easingSinusoidalIn : new CubicBezier(0.47, 0, 0.745, 0.715,'easingSinusoidalIn'),
easingSinusoidalOut : new CubicBezier(0.39, 0.575, 0.565, 1,'easingSinusoidalOut'),
easingSinusoidalInOut : new CubicBezier(0.445, 0.05, 0.55, 0.95,'easingSinusoidalInOut'),
linear: new CubicBezier(0, 0, 1, 1, 'linear'),
easingSinusoidalIn: new CubicBezier(0.47, 0, 0.745, 0.715, 'easingSinusoidalIn'),
easingSinusoidalOut: new CubicBezier(0.39, 0.575, 0.565, 1, 'easingSinusoidalOut'),
easingSinusoidalInOut: new CubicBezier(0.445, 0.05, 0.55, 0.95, 'easingSinusoidalInOut'),
easingQuadraticIn : new CubicBezier(0.550, 0.085, 0.680, 0.530,'easingQuadraticIn'),
easingQuadraticOut : new CubicBezier(0.250, 0.460, 0.450, 0.940,'easingQuadraticOut'),
easingQuadraticInOut : new CubicBezier(0.455, 0.030, 0.515, 0.955,'easingQuadraticInOut'),
easingQuadraticIn: new CubicBezier(0.550, 0.085, 0.680, 0.530, 'easingQuadraticIn'),
easingQuadraticOut: new CubicBezier(0.250, 0.460, 0.450, 0.940, 'easingQuadraticOut'),
easingQuadraticInOut: new CubicBezier(0.455, 0.030, 0.515, 0.955, 'easingQuadraticInOut'),
easingCubicIn : new CubicBezier(0.55, 0.055, 0.675, 0.19,'easingCubicIn'),
easingCubicOut : new CubicBezier(0.215, 0.61, 0.355, 1,'easingCubicOut'),
easingCubicInOut : new CubicBezier(0.645, 0.045, 0.355, 1,'easingCubicInOut'),
easingCubicIn: new CubicBezier(0.55, 0.055, 0.675, 0.19, 'easingCubicIn'),
easingCubicOut: new CubicBezier(0.215, 0.61, 0.355, 1, 'easingCubicOut'),
easingCubicInOut: new CubicBezier(0.645, 0.045, 0.355, 1, 'easingCubicInOut'),
easingQuarticIn : new CubicBezier(0.895, 0.03, 0.685, 0.22,'easingQuarticIn'),
easingQuarticOut : new CubicBezier(0.165, 0.84, 0.44, 1,'easingQuarticOut'),
easingQuarticInOut : new CubicBezier(0.77, 0, 0.175, 1,'easingQuarticInOut'),
easingQuarticIn: new CubicBezier(0.895, 0.03, 0.685, 0.22, 'easingQuarticIn'),
easingQuarticOut: new CubicBezier(0.165, 0.84, 0.44, 1, 'easingQuarticOut'),
easingQuarticInOut: new CubicBezier(0.77, 0, 0.175, 1, 'easingQuarticInOut'),
easingQuinticIn : new CubicBezier(0.755, 0.05, 0.855, 0.06,'easingQuinticIn'),
easingQuinticOut : new CubicBezier(0.23, 1, 0.32, 1,'easingQuinticOut'),
easingQuinticInOut : new CubicBezier(0.86, 0, 0.07, 1,'easingQuinticInOut'),
easingQuinticIn: new CubicBezier(0.755, 0.05, 0.855, 0.06, 'easingQuinticIn'),
easingQuinticOut: new CubicBezier(0.23, 1, 0.32, 1, 'easingQuinticOut'),
easingQuinticInOut: new CubicBezier(0.86, 0, 0.07, 1, 'easingQuinticInOut'),
easingExponentialIn : new CubicBezier(0.95, 0.05, 0.795, 0.035,'easingExponentialIn'),
easingExponentialOut : new CubicBezier(0.19, 1, 0.22, 1,'easingExponentialOut'),
easingExponentialInOut : new CubicBezier(1, 0, 0, 1,'easingExponentialInOut'),
easingExponentialIn: new CubicBezier(0.95, 0.05, 0.795, 0.035, 'easingExponentialIn'),
easingExponentialOut: new CubicBezier(0.19, 1, 0.22, 1, 'easingExponentialOut'),
easingExponentialInOut: new CubicBezier(1, 0, 0, 1, 'easingExponentialInOut'),
easingCircularIn : new CubicBezier(0.6, 0.04, 0.98, 0.335,'easingCircularIn'),
easingCircularOut : new CubicBezier(0.075, 0.82, 0.165, 1,'easingCircularOut'),
easingCircularInOut : new CubicBezier(0.785, 0.135, 0.15, 0.86,'easingCircularInOut'),
easingCircularIn: new CubicBezier(0.6, 0.04, 0.98, 0.335, 'easingCircularIn'),
easingCircularOut: new CubicBezier(0.075, 0.82, 0.165, 1, 'easingCircularOut'),
easingCircularInOut: new CubicBezier(0.785, 0.135, 0.15, 0.86, 'easingCircularInOut'),
easingBackIn : new CubicBezier(0.6, -0.28, 0.735, 0.045,'easingBackIn'),
easingBackOut : new CubicBezier(0.175, 0.885, 0.32, 1.275,'easingBackOut'),
easingBackInOut : new CubicBezier(0.68, -0.55, 0.265, 1.55,'easingBackInOut')
}
easingBackIn: new CubicBezier(0.6, -0.28, 0.735, 0.045, 'easingBackIn'),
easingBackOut: new CubicBezier(0.175, 0.885, 0.32, 1.275, 'easingBackOut'),
easingBackInOut: new CubicBezier(0.68, -0.55, 0.265, 1.55, 'easingBackInOut'),
};
function processBezierEasing(fn) {
if ( typeof fn === 'function') {
if (typeof fn === 'function') {
return fn;
} else if (typeof(Easing[fn]) === 'function') {
} if (typeof (Easing[fn]) === 'function') {
return Easing[fn];
} else if ( /bezier/.test(fn) ) {
var bz = fn.replace(/bezier|\s|\(|\)/g,'').split(',');
return new CubicBezier( bz[0]*1,bz[1]*1,bz[2]*1,bz[3]*1 ); //bezier easing
} else {
if ( /elastic|bounce/i.test(fn) ) {
console.warn(`KUTE.js - CubicBezier doesn't support ${fn} easing.`)
}
return Easing.linear
} if (/bezier/.test(fn)) {
const bz = fn.replace(/bezier|\s|\(|\)/g, '').split(',');
return new CubicBezier(bz[0] * 1, bz[1] * 1, bz[2] * 1, bz[3] * 1); // bezier easing
}
// if (/elastic|bounce/i.test(fn)) {
// throw TypeError(`KUTE.js - CubicBezier doesn't support ${fn} easing.`);
// }
return Easing.linear;
}
connect.processEasing = processBezierEasing
connect.processEasing = processBezierEasing;
export default Easing
export default Easing;

View file

@ -1,79 +1,132 @@
import connect from '../objects/connect.js'
import connect from '../objects/connect.js';
// Robert Penner's Easing Functions
// updated for ESLint
const Easing = {
linear : (t) => t,
easingSinusoidalIn : (t) => -Math.cos(t * Math.PI / 2) + 1,
easingSinusoidalOut : (t) => Math.sin(t * Math.PI / 2),
easingSinusoidalInOut : (t) => -0.5 * (Math.cos(Math.PI * t) - 1),
easingQuadraticIn : (t) => t*t,
easingQuadraticOut : (t) => t*(2-t),
easingQuadraticInOut : (t) => t<.5 ? 2*t*t : -1+(4-2*t)*t,
easingCubicIn : (t) => t*t*t,
easingCubicOut : (t) => (--t)*t*t+1,
easingCubicInOut : (t) => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,
easingQuarticIn : (t) => t*t*t*t,
easingQuarticOut : (t) => 1-(--t)*t*t*t,
easingQuarticInOut : (t) => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t,
easingQuinticIn : (t) => t*t*t*t*t,
easingQuinticOut : (t) => 1+(--t)*t*t*t*t,
easingQuinticInOut : (t) => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t,
easingCircularIn : (t) => -(Math.sqrt(1 - (t * t)) - 1),
easingCircularOut : (t) => Math.sqrt(1 - (t = t - 1) * t),
easingCircularInOut : (t) => ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
easingExponentialIn : (t) => 2 ** (10 * (t - 1)) - 0.001,
easingExponentialOut : (t) => 1 - 2 ** (-10 * t),
easingExponentialInOut : (t) => (t *= 2) < 1 ? 0.5 * (2 ** (10 * (t - 1))) : 0.5 * (2 - 2 ** (-10 * (t - 1))),
easingBackIn : (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s) },
easingBackOut : (t) => { const s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 },
easingBackInOut : (t) => {
linear: (t) => t,
easingSinusoidalIn: (t) => -Math.cos((t * Math.PI) / 2) + 1,
easingSinusoidalOut: (t) => Math.sin((t * Math.PI) / 2),
easingSinusoidalInOut: (t) => -0.5 * (Math.cos(Math.PI * t) - 1),
easingQuadraticIn: (t) => t * t,
easingQuadraticOut: (t) => t * (2 - t),
easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
easingCubicIn: (t) => t * t * t,
easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; },
easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
easingQuarticIn: (t) => t * t * t * t,
easingQuarticOut: (t0) => { const t = t0 - 1; return 1 - t * t * t * t; },
easingQuarticInOut: (t0) => {
let t = t0;
if (t < 0.5) return 8 * t * t * t * t;
t -= 1; return 1 - 8 * t * t * t * t;
},
easingQuinticIn: (t) => t * t * t * t * t,
easingQuinticOut: (t0) => { const t = t0 - 1; return 1 + t * t * t * t * t; },
easingQuinticInOut: (t0) => {
let t = t0;
if (t < 0.5) return 16 * t * t * t * t * t;
t -= 1; return 1 + 16 * t * t * t * t * t;
},
easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1),
easingCircularOut: (t0) => { const t = t0 - 1; return Math.sqrt(1 - t * t); },
easingCircularInOut: (t0) => {
let t = t0 * 2;
if (t < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1);
t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1);
},
easingExponentialIn: (t) => 2 ** (10 * (t - 1)) - 0.001,
easingExponentialOut: (t) => 1 - 2 ** (-10 * t),
easingExponentialInOut: (t0) => {
const t = t0 * 2;
if (t < 1) return 0.5 * (2 ** (10 * (t - 1)));
return 0.5 * (2 - 2 ** (-10 * (t - 1)));
},
easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); },
easingBackOut: (t0) => {
const s = 1.70158;
const t = t0 - 1;
return t * t * ((s + 1) * t + s) + 1;
},
easingBackInOut: (t0) => {
const s = 1.70158 * 1.525;
if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s))
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2)
let t = t0 * 2;
if (t < 1) return 0.5 * (t * t * ((s + 1) * t - s));
t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2);
},
easingElasticIn : (t) => {
let s, _kea = 0.1, _kep = 0.4
if ( t === 0 ) return 0;if ( t === 1 ) return 1
if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2
return - ( _kea * (2 ** (10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) )
easingElasticIn: (t0) => {
let s;
let k1 = 0.1;
const k2 = 0.4;
let t = t0;
if (t === 0) return 0;
if (t === 1) return 1;
if (!k1 || k1 < 1) {
k1 = 1; s = k2 / 4;
} else {
s = ((k2 * Math.asin(1 / k1)) / Math.PI) * 2;
}
t -= 1;
return -(k1 * (2 ** (10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2));
},
easingElasticOut : (t) => {
let s, _kea = 0.1, _kep = 0.4
if ( t === 0 ) return 0;if ( t === 1 ) return 1
if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2
return _kea * (2 ** (- 10 * t)) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) + 1
easingElasticOut: (t) => {
let s;
let k1 = 0.1;
const k2 = 0.4;
if (t === 0) return 0;
if (t === 1) return 1;
if (!k1 || k1 < 1) {
k1 = 1;
s = k2 / 4;
} else {
s = ((k2 * Math.asin(1 / k1)) / Math.PI) * 2;
}
return k1 * (2 ** (-10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2) + 1;
},
easingElasticInOut : (t) => {
let s, _kea = 0.1, _kep = 0.4
if ( t === 0 ) return 0;if ( t === 1 ) return 1
if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2
if ( ( t *= 2 ) < 1 ) return - 0.5 * ( _kea * (2 ** (10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) )
return _kea * (2 ** (-10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) * 0.5 + 1
easingElasticInOut: (t0) => {
let t = t0;
let s;
let k1 = 0.1;
const k2 = 0.4;
if (t === 0) return 0;
if (t === 1) return 1;
if (!k1 || k1 < 1) {
k1 = 1; s = k2 / 4;
} else {
s = k2 * (Math.asin(1 / k1) / Math.PI) * 2;
}
t *= 2;
if (t < 1) {
return -0.5 * (k1 * (2 ** (10 * (t - 1)))
* Math.sin(((t - 1 - s) * Math.PI * 2) / k2));
}
t -= 1;
return k1 * (2 ** (-10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2) * 0.5 + 1;
},
easingBounceIn : (t) => { return 1 - Easing.easingBounceOut( 1 - t ) },
easingBounceOut : (t) => {
if ( t < ( 1 / 2.75 ) ) { return 7.5625 * t * t; }
else if ( t < ( 2 / 2.75 ) ) { return 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + 0.75; }
else if ( t < ( 2.5 / 2.75 ) ) { return 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + 0.9375; }
else {return 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + 0.984375; }
easingBounceIn: (t) => 1 - Easing.easingBounceOut(1 - t),
easingBounceOut: (t0) => {
let t = t0;
if (t < (1 / 2.75)) { return 7.5625 * t * t; }
if (t < (2 / 2.75)) { t -= (1.5 / 2.75); return 7.5625 * t * t + 0.75; }
if (t < (2.5 / 2.75)) { t -= (2.25 / 2.75); return 7.5625 * t * t + 0.9375; }
t -= (2.625 / 2.75);
return 7.5625 * t * t + 0.984375;
},
easingBounceInOut : (t) => {
if ( t < 0.5 ) return Easing.easingBounceIn( t * 2 ) * 0.5;
return Easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5
}
}
easingBounceInOut: (t) => {
if (t < 0.5) return Easing.easingBounceIn(t * 2) * 0.5;
return Easing.easingBounceOut(t * 2 - 1) * 0.5 + 0.5;
},
};
function processEasing(fn) {
if ( typeof fn === 'function') {
if (typeof fn === 'function') {
return fn;
} else if ( typeof Easing[fn] === 'function' ) {
} if (typeof Easing[fn] === 'function') {
return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
}
return Easing.linear;
}
// Tween constructor needs to know who will process easing functions
connect.processEasing = processEasing
connect.processEasing = processEasing;
export default Easing
export default Easing;

View file

@ -1,29 +1,29 @@
import {version as Version} from './../package.json'
import Render from './core/render.js'
import Interpolate from './objects/interpolate.js'
import Objects from './objects/objectsBase.js'
import Util from './objects/util.js'
import Easing from './easing/easing-base.js'
import Internals from './core/internals.js'
import Selector from './util/selector.js'
import { version as Version } from '../package.json';
import Render from './core/render.js';
import Interpolate from './objects/interpolate.js';
import Objects from './objects/objectsBase.js';
import Util from './objects/util.js';
import Easing from './easing/easing-base.js';
import Internals from './core/internals.js';
import Selector from './util/selector.js';
import Animation from './animation/animationBase.js'
import Animation from './animation/animationBase.js';
// TweenConstructor
import Tween from './tween/tweenBase.js'
import Tween from './tween/tweenBase.js';
// Interface only fromTo
import fromTo from './interface/fromTo.js'
import fromTo from './interface/fromTo.js';
// import baseTransform from './components/transformFunctionsBase.js'
import baseTransformMatrix from './components/transformMatrixBase.js'
import baseBoxModel from './components/boxModelBase.js'
import baseOpacity from './components/opacityPropertyBase.js'
import baseTransformMatrix from './components/transformMatrixBase.js';
import baseBoxModel from './components/boxModelBase.js';
import baseOpacity from './components/opacityPropertyBase.js';
// import {baseCrossBrowserMove} from './components/crossBrowserMove.js'
// const Transform = new Animation(baseTransform)
const Transform = new Animation(baseTransformMatrix)
const BoxModel = new Animation(baseBoxModel)
const Opacity = new Animation(baseOpacity)
const Transform = new Animation(baseTransformMatrix);
const BoxModel = new Animation(baseBoxModel);
const Opacity = new Animation(baseOpacity);
// const Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here
@ -46,5 +46,5 @@ export default {
Interpolate,
Internals,
Selector,
Version
}
Version,
};

View file

@ -1,49 +1,67 @@
import {version as Version} from './../package.json'
import Render from './core/render.js'
import Interpolate from './objects/interpolate.js'
import Objects from './objects/objects.js'
import Util from './objects/util.js'
import Components from './objects/components.js'
import Internals from './core/internals.js'
import Process from './process/process.js'
import CubicBezier from 'cubic-bezier-easing'
import Easing from './easing/easing-bezier.js'
import Selector from './util/selector.js'
import CubicBezier from 'cubic-bezier-easing';
import { version as Version } from '../package.json';
import Render from './core/render.js';
import Interpolate from './objects/interpolate.js';
import Objects from './objects/objects.js';
import Util from './objects/util.js';
import Internals from './core/internals.js';
import Process from './process/process.js';
import Easing from './easing/easing-bezier.js';
import Selector from './util/selector.js';
// TweenConstructor
import Tween from './tween/tweenExtra.js'
import TweenCollection from './tween/tweenCollection.js'
import ProgressBar from './util/progressBar.js'
import Tween from './tween/tweenExtra.js';
import TweenCollection from './tween/tweenCollection.js';
import ProgressBar from './util/progressBar.js';
// interface
import to from './interface/to.js'
import fromTo from './interface/fromTo.js'
import allTo from './interface/allTo.js'
import allFromTo from './interface/allFromTo.js'
import to from './interface/to.js';
import fromTo from './interface/fromTo.js';
import allTo from './interface/allTo.js';
import allFromTo from './interface/allFromTo.js';
import Animation from './animation/animationDevelopment.js'
import Animation from './animation/animationDevelopment.js';
// components
import BackgroundPosition from './components/backgroundPosition.js'
import BorderRadius from './components/borderRadius.js'
import BoxModel from './components/boxModel.js'
import ClipProperty from './components/clipProperty.js'
import ColorProperties from './components/colorProperties.js'
import FilterEffects from './components/filterEffects'
import HTMLAttributes from './components/htmlAttributes.js'
import OpacityProperty from './components/opacityProperty.js'
import SVGDraw from './components/svgDraw.js'
import SVGCubicMorph from './components/svgCubicMorph.js'
import SVGTransform from './components/svgTransform.js'
import ScrollProperty from './components/scrollProperty.js'
import ShadowProperties from './components/shadowProperties.js'
import TextProperties from './components/textProperties.js'
import TextWriteProperties from './components/textWrite.js'
import MatrixTransform from './components/transformMatrix.js'
import BackgroundPosition from './components/backgroundPosition.js';
import BorderRadius from './components/borderRadius.js';
import BoxModel from './components/boxModel.js';
import ClipProperty from './components/clipProperty.js';
import ColorProperties from './components/colorProperties.js';
import FilterEffects from './components/filterEffects';
import HTMLAttributes from './components/htmlAttributes.js';
import OpacityProperty from './components/opacityProperty.js';
import SVGDraw from './components/svgDraw.js';
import SVGCubicMorph from './components/svgCubicMorph.js';
import SVGTransform from './components/svgTransform.js';
import ScrollProperty from './components/scrollProperty.js';
import ShadowProperties from './components/shadowProperties.js';
import TextProperties from './components/textProperties.js';
import TextWriteProperties from './components/textWrite.js';
import MatrixTransform from './components/transformMatrix.js';
for (let component in Components) {
let compOps = Components[component]
Components[component] = new Animation(compOps)
}
const Components = {
BackgroundPosition,
BorderRadius,
BoxModel,
ClipProperty,
ColorProperties,
FilterEffects,
HTMLAttributes,
OpacityProperty,
SVGDraw,
SVGCubicMorph,
SVGTransform,
ScrollProperty,
ShadowProperties,
TextProperties,
TextWriteProperties,
MatrixTransform,
};
Object.keys(Components).forEach((component) => {
const compOps = Components[component];
Components[component] = new Animation(compOps);
});
export default {
Animation,
@ -69,5 +87,5 @@ export default {
Process,
Internals,
Selector,
Version
}
Version,
};

71
src/index-legacy.js Normal file
View file

@ -0,0 +1,71 @@
import { version as Version } from '../package.json';
import Render from './core/render.js';
import Interpolate from './objects/interpolate.js';
import Objects from './objects/objects.js';
import Util from './objects/util.js';
import Internals from './core/internals.js';
import Process from './process/process.js';
import Easing from './easing/easing.js';
import Selector from './util/selector.js';
// TweenConstructor
import Tween from './tween/tween.js';
import TweenCollection from './tween/tweenCollection.js';
// interface
import to from './interface/to.js';
import fromTo from './interface/fromTo.js';
import allTo from './interface/allTo.js';
import allFromTo from './interface/allFromTo.js';
import Animation from './animation/animation.js';
// components
import BoxModel from './components/boxModelEssential.js';
import ColorProperties from './components/colorProperties.js';
import HTMLAttributes from './components/htmlAttributes.js';
import OpacityProperty from './components/opacityProperty.js';
import TextWrite from './components/textWrite.js';
import TransformLegacy from './components/transformLegacy.js';
import SVGDraw from './components/svgDraw.js';
import SVGMorph from './components/svgMorph.js';
const Components = {
BoxModel,
ColorProperties,
HTMLAttributes,
OpacityProperty,
TextWrite,
TransformLegacy,
SVGDraw,
SVGMorph,
};
// init components
Object.keys(Components).forEach((component) => {
const compOps = Components[component];
Components[component] = new Animation(compOps);
});
export default {
Animation,
Components,
// Tween Interface
Tween,
fromTo,
to,
// Tween Collection
TweenCollection,
allFromTo,
allTo,
// Tween Interface
Objects,
Util,
Easing,
Render,
Interpolate,
Process,
Internals,
Selector,
Version,
};

View file

@ -1,52 +1,51 @@
import {version as Version} from './../package.json'
import Render from './core/render.js'
import Interpolate from './objects/interpolate.js'
import Objects from './objects/objects.js'
import Util from './objects/util.js'
import Components from './objects/components.js'
import Internals from './core/internals.js'
import Process from './process/process.js'
import CubicBezier from 'cubic-bezier-easing'
import Easing from './easing/easing-bezier.js'
import Selector from './util/selector.js'
import CubicBezier from 'cubic-bezier-easing';
import { version as Version } from '../package.json';
import Render from './core/render.js';
import Interpolate from './objects/interpolate.js';
import Objects from './objects/objects.js';
import Util from './objects/util.js';
import Internals from './core/internals.js';
import Process from './process/process.js';
import Easing from './easing/easing-bezier.js';
import Selector from './util/selector.js';
// TweenConstructor
import Tween from './tween/tween.js'
import TweenCollection from './tween/tweenCollection.js'
import Tween from './tween/tween.js';
import TweenCollection from './tween/tweenCollection.js';
// interface
import to from './interface/to.js'
import fromTo from './interface/fromTo.js'
import allTo from './interface/allTo.js'
import allFromTo from './interface/allFromTo.js'
import to from './interface/to.js';
import fromTo from './interface/fromTo.js';
import allTo from './interface/allTo.js';
import allFromTo from './interface/allFromTo.js';
// import {default as Animation} from './animation/animationDevelopment.js'
import Animation from './animation/animation.js'
import Animation from './animation/animation.js';
// components
// import EssentialBoxModel from './components/boxModelEssential.js'
// import ColorsProperties from './components/colorProperties.js'
// import HTMLAttributes from './components/htmlAttributes.js'
// import OpacityProperty from './components/opacityProperty.js'
// import TextWrite from './components/textWrite.js'
// import TransformFunctions from './components/transformFunctions.js'
// // import TransformFunctions from './components/transformLegacy.js'
// import SVGDraw from './components/svgDraw.js'
// import SVGMorph from './components/svgMorph.js'
import './components/boxModelEssential.js'
import './components/colorProperties.js'
import './components/htmlAttributes.js'
import './components/opacityProperty.js'
import './components/textWrite.js'
import './components/transformFunctions.js'
// import './components/transformLegacy.js'
import './components/svgDraw.js'
import './components/svgMorph.js'
import EssentialBoxModel from './components/boxModelEssential.js';
import ColorsProperties from './components/colorProperties.js';
import HTMLAttributes from './components/htmlAttributes.js';
import OpacityProperty from './components/opacityProperty.js';
import TextWrite from './components/textWrite.js';
import TransformFunctions from './components/transformFunctions.js';
import SVGDraw from './components/svgDraw.js';
import SVGMorph from './components/svgMorph.js';
const Components = {
EssentialBoxModel,
ColorsProperties,
HTMLAttributes,
OpacityProperty,
TextWrite,
TransformFunctions,
SVGDraw,
SVGMorph,
};
// init components
for (let component in Components) {
let compOps = Components[component]
Components[component] = new Animation(compOps)
}
Object.keys(Components).forEach((component) => {
const compOps = Components[component];
Components[component] = new Animation(compOps);
});
export default {
Animation,
@ -71,5 +70,5 @@ export default {
Process,
Internals,
Selector,
Version
}
Version,
};

View file

@ -1,7 +1,7 @@
import selector from '../util/selector.js'
import TweenCollection from '../tween/tweenCollection.js'
import selector from '../util/selector.js';
import TweenCollection from '../tween/tweenCollection.js';
export default function allFromTo(elements, startObject, endObject, optionsObj) {
optionsObj = optionsObj || {}
return new TweenCollection(selector(elements,true), startObject, endObject, optionsObj)
const options = optionsObj || {};
return new TweenCollection(selector(elements, true), startObject, endObject, options);
}

View file

@ -1,9 +1,9 @@
import selector from '../util/selector.js'
import TweenCollection from '../tween/tweenCollection.js'
import selector from '../util/selector.js';
import TweenCollection from '../tween/tweenCollection.js';
// multiple elements tween objects
export default function allTo(elements, endObject, optionsObj) {
optionsObj = optionsObj || {}
optionsObj.resetStart = endObject
return new TweenCollection(selector(elements,true), endObject, endObject, optionsObj)
const options = optionsObj || {};
optionsObj.resetStart = endObject;
return new TweenCollection(selector(elements, true), endObject, endObject, options);
}

View file

@ -1,7 +1,8 @@
import selector from '../util/selector.js'
import connect from '../objects/connect.js'
import selector from '../util/selector.js';
import connect from '../objects/connect.js';
export default function fromTo(element, startObject, endObject, optionsObj) {
optionsObj = optionsObj || {}
return new connect.tween(selector(element), startObject, endObject, optionsObj)
const options = optionsObj || {};
const TweenConstructor = connect.tween;
return new TweenConstructor(selector(element), startObject, endObject, options);
}

View file

@ -1,8 +1,9 @@
import selector from '../util/selector.js'
import connect from '../objects/connect.js'
import selector from '../util/selector.js';
import connect from '../objects/connect.js';
export default function to(element, endObject, optionsObj) {
optionsObj = optionsObj || {}
optionsObj.resetStart = endObject
return new connect.tween(selector(element), endObject, endObject, optionsObj)
const options = optionsObj || {};
const TweenConstructor = connect.tween;
options.resetStart = endObject;
return new TweenConstructor(selector(element), endObject, endObject, options);
}

View file

@ -1,7 +1,7 @@
export default function(a,b,v){
const result = []
for ( let i=0, l=b.length; i<l; i++ ) {
result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0 ) / 1000
export default function arrays(a, b, v) {
const result = [];
for (let i = 0, l = b.length; i < l; i += 1) {
result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0) / 1000;
}
return result
return result;
}

View file

@ -1,13 +1,23 @@
import numbers from './numbers.js'
import numbers from './numbers.js';
export default function(a, b, v) {
let _c = {},
c,
ep = ')',
cm =',',
rgb = 'rgb(',
rgba = 'rgba(';
export default function colors(a, b, v) {
const _c = {};
const ep = ')';
const cm = ',';
const rgb = 'rgb(';
const rgba = 'rgba(';
for (c in b) { _c[c] = c !== 'a' ? (numbers(a[c],b[c],v)>>0 || 0) : (a[c] && b[c]) ? (numbers(a[c],b[c],v) * 100 >> 0 )/100 : null; }
return !_c.a ? rgb + _c.r + cm + _c.g + cm + _c.b + ep : rgba + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep;
Object.keys(b).forEach((c) => {
// _c[c] = c !== 'a' ? (numbers(a[c], b[c], v) >> 0 || 0) : (a[c] && b[c])
// ? (numbers(a[c], b[c], v) * 100 >> 0) / 100 : null;
if (c !== 'a') {
_c[c] = numbers(a[c], b[c], v) >> 0 || 0;
} else if (a[c] && b[c]) {
_c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100;
}
});
return !_c.a
? rgb + _c.r + cm + _c.g + cm + _c.b + ep
: rgba + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep;
}

View file

@ -1,9 +1,9 @@
export default function(a, b, l, v) {
export default function coords(a, b, l, v) {
const points = [];
for(let i=0;i<l;i++) { // for each point
for (let i = 0; i < l; i += 1) { // for each point
points[i] = [];
for(let j=0;j<2;j++) { // each point coordinate
points[i].push( ((a[i][j]+(b[i][j]-a[i][j])*v) * 1000 >> 0)/1000 );
for (let j = 0; j < 2; j += 1) { // each point coordinate
points[i].push(((a[i][j] + (b[i][j] - a[i][j]) * v) * 1000 >> 0) / 1000);
}
}
return points;

View file

@ -1,3 +1,6 @@
export default function(a, b, v) { // number1, number2, progress
a = +a; b -= a; return a + b * v;
export default function numbers(a, b, v) { // number1, number2, progress
const A = +a;
const B = b - a;
// a = +a; b -= a;
return A + B * v;
}

View file

@ -1,3 +1,3 @@
export default function(a, b, u, v) {
return `perspective(${((a + (b - a) * v) * 1000 >> 0 ) / 1000}${u})`
export default function perspective(a, b, u, v) {
return `perspective(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`;
}

View file

@ -1,3 +1,3 @@
export default function(a, b, u, v) {
return `rotate(${((a + (b - a) * v) * 1000 >> 0 ) / 1000}${u})`
export default function rotate(a, b, u, v) {
return `rotate(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`;
}

View file

@ -1,7 +1,7 @@
export default function(a, b, u, v) {
let rotateStr = ''
rotateStr += a[0]||b[0] ? `rotateX(${((a[0] + (b[0] - a[0]) * v) * 1000 >> 0 ) / 1000}${u})` : ''
rotateStr += a[1]||b[1] ? `rotateY(${((a[1] + (b[1] - a[1]) * v) * 1000 >> 0 ) / 1000}${u})` : ''
rotateStr += a[2]||b[2] ? `rotateZ(${((a[2] + (b[2] - a[2]) * v) * 1000 >> 0 ) / 1000}${u})` : ''
return rotateStr
export default function rotate3d(a, b, u, v) {
let rotateStr = '';
rotateStr += a[0] || b[0] ? `rotateX(${((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000}${u})` : '';
rotateStr += a[1] || b[1] ? `rotateY(${((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000}${u})` : '';
rotateStr += a[2] || b[2] ? `rotateZ(${((a[2] + (b[2] - a[2]) * v) * 1000 >> 0) / 1000}${u})` : '';
return rotateStr;
}

View file

@ -1,3 +1,3 @@
export default function(a, b, v) {
return `scale(${((a + (b - a) * v) * 1000 >> 0 ) / 1000})`;
export default function scale(a, b, v) {
return `scale(${((a + (b - a) * v) * 1000 >> 0) / 1000})`;
}

View file

@ -1,6 +1,6 @@
export default function(a, b, u, v) {
let skewArray = [];
skewArray[0] = ( a[0]===b[0] ? b[0] : ( (a[0] + ( b[0] - a[0] ) * v ) * 1000 >> 0 ) / 1000 ) + u
skewArray[1] = a[1]||b[1] ? (( a[1]===b[1] ? b[1] : ( (a[1] + ( b[1] - a[1] ) * v ) * 1000 >> 0 ) / 1000 ) + u) : '0'
export default function skew(a, b, u, v) {
const skewArray = [];
skewArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u;
skewArray[1] = a[1] || b[1] ? ((a[1] === b[1] ? b[1] : ((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000) + u) : '0';
return `skew(${skewArray.join(',')})`;
}

View file

@ -1,3 +1,3 @@
export default function(a, b, u, v) {
return `skewX(${((a + (b - a) * v) * 1000 >> 0 ) / 1000}${u})`
export default function skewX(a, b, u, v) {
return `skewX(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`;
}

View file

@ -1,3 +1,3 @@
export default function(a, b, u, v) {
return `skewY(${((a + (b - a) * v) * 1000 >> 0 ) / 1000}${u})`
export default function skewY(a, b, u, v) {
return `skewY(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`;
}

View file

@ -1,6 +1,6 @@
export default function(a, b, u, v) {
let translateArray = [];
translateArray[0] = ( a[0]===b[0] ? b[0] : ( (a[0] + ( b[0] - a[0] ) * v ) * 1000 >> 0 ) / 1000 ) + u
translateArray[1] = a[1]||b[1] ? (( a[1]===b[1] ? b[1] : ( (a[1] + ( b[1] - a[1] ) * v ) * 1000 >> 0 ) / 1000 ) + u) : '0'
export default function translate(a, b, u, v) {
const translateArray = [];
translateArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u;
translateArray[1] = a[1] || b[1] ? ((a[1] === b[1] ? b[1] : ((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000) + u) : '0';
return `translate(${translateArray.join(',')})`;
}

View file

@ -1,7 +1,8 @@
export default function(a, b, u, v) {
let translateArray = [];
for (let ax=0; ax<3; ax++){
translateArray[ax] = ( a[ax]||b[ax] ? ( (a[ax] + ( b[ax] - a[ax] ) * v ) * 1000 >> 0 ) / 1000 : 0 ) + u;
export default function translate3d(a, b, u, v) {
const translateArray = [];
for (let ax = 0; ax < 3; ax += 1) {
translateArray[ax] = (a[ax] || b[ax]
? ((a[ax] + (b[ax] - a[ax]) * v) * 1000 >> 0) / 1000 : 0) + u;
}
return `translate3d(${translateArray.join(',')})`;
}

View file

@ -1,3 +1,6 @@
export default function(a, b, u, v) { // number1, number2, unit, progress
a = +a; b -= a; return ( a + b * v ) + u;
export default function units(a, b, u, v) { // number1, number2, unit, progress
const A = +a;
const B = b - a;
// a = +a; b -= a;
return (A + B * v) + u;
}

View file

@ -1 +0,0 @@
export default {}

View file

@ -1 +1 @@
export default {}
export default {};

View file

@ -2,4 +2,4 @@
// can be set to make sure start unit and end unit are same,
// stack transforms, process SVG paths,
// any type of post processing the component needs
export default {}
export default {};

Some files were not shown because too many files have changed in this diff Show more