* 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

215
dist/polyfill.js vendored
View file

@ -1,93 +1,140 @@
/*!
* 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";
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
return function from(arrayLike) {
var C = this, items = Object(arrayLike);
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
}
var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T;
if (typeof mapFn !== 'undefined') {
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) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
A.length = len;
return A;
}
}());
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
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');
}
var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T;
if (typeof mapFn !== 'undefined') {
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) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
A.length = len;
return A;
}
}());
}
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement ) {
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
// 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 (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
return this.indexOf(search, start) !== -1;
};
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
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,116 +1,135 @@
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
// * populate KUTE objects
// * 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){
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`);
} else {
this.setComponent(Component)
}
} catch(e){
console.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
// set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
// set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate
defaultValues[ Property ] = Component.defaultValue
// minimal info
propertyInfo.supports = `${Property} property`
} else if (Component.defaultValues) {
for (const dv in Component.defaultValues) {
defaultValues[dv] = Component.defaultValues[dv]
}
// minimal info
propertyInfo.supports = `${Length||Property} ${Property||Category} properties`
}
// set additional options
if (Component.defaultOptions) {
for (const op in Component.defaultOptions) {
defaultOptions[op] = Component.defaultOptions[op]
}
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
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])
}
}
}
}
}
// set component interpolate
if (Component.Interpolate) {
for (const fni in Component.Interpolate) {
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] ) {
Interpolate[fni] = compIntObj[sfn];
}
}
}
}
linkProperty[ComponentName] = Component.Interpolate
}
// set component util
if (Component.Util) {
for (const fnu in Component.Util){
!Util[fnu] && (Util[fnu] = Component.Util[fnu])
}
}
return propertyInfo
}
}
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
// * populate KUTE objects
// * 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) {
try {
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);
}
} 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);
// 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;
// set defaultValues
if ('defaultValue' in Component) { // value 0 will invalidate
defaultValues[Property] = Component.defaultValue;
// minimal info
propertyInfo.supports = `${Property} property`;
} else if (Component.defaultValues) {
Object.keys(Component.defaultValues).forEach((dv) => {
defaultValues[dv] = Component.defaultValues[dv];
});
// minimal info
propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
}
// set additional options
if (Component.defaultOptions) {
Object.keys(Component.defaultOptions).forEach((op) => {
defaultOptions[op] = Component.defaultOptions[op];
});
}
// set functions
if (Component.functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
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) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
});
}
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
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'
// Animation class
export default class AnimationBase {
constructor(Component){
return this.setComponent(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
// set supported category/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]
}
}
// set functions
if (Component.functions) {
for (const fn in Functions) {
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])
}
}
}
}
}
// set interpolate
if (Component.Interpolate) {
for (const fni in Component.Interpolate) {
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] ) {
Interpolate[fni] = compIntObj[sfn];
}
}
}
}
linkProperty[ComponentName] = Component.Interpolate
}
// set component util
if (Component.Util) {
for (const fnu in Component.Util){
!Util[fnu] && (Util[fnu] = Component.Util[fnu])
}
}
return {name:ComponentName}
}
}
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);
}
setComponent(Component) {
const ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
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;
// set additional options
if (Component.defaultOptions) {
Object.keys(Component.defaultOptions).forEach((op) => {
defaultOptions[op] = Component.defaultOptions[op];
});
}
// set functions
if (Component.functions) {
Object.keys(Functions).forEach((fn) => {
if (fn in Component.functions) {
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) {
Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni];
if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn];
}
});
}
});
linkProperty[ComponentName] = Component.Interpolate;
}
// set component util
if (Component.Util) {
Object.keys(Component.Util).forEach((fnu) => {
if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
});
}
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 Animation from './animation.js'
// AnimationDevelopment class
export default class AnimationDevelopment extends Animation {
constructor(...args){
super(...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
// set defaultValues
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`
}
// set additional options
if (Component.defaultOptions) {
propertyInfo.extends = []
for (const op in Component.defaultOptions) {
propertyInfo.extends.push(op)
}
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) {
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
} 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
}
}
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 = []
for (let fni in Component.Interpolate) {
let compIntObj = Component.Interpolate[fni]
// register new Interpolation functions
if ( typeof(compIntObj) === 'function' ) {
if ( !Interpolate[fni] ) {
propertyInfo.adds.push(`${fni}`)
}
propertyInfo.uses.push(`${fni}`)
} else {
for ( let sfn in compIntObj ) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) {
propertyInfo.adds.push(`${sfn}`)
}
propertyInfo.uses.push(`${sfn}`)
}
}
}
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
} else {
propertyInfo.critical = `For ${Property||Category} no interpolation function[s] is set`
}
// set component util
if (Component.Util) {
propertyInfo.hasUtil = Object.keys(Component.Util).join(',')
}
return propertyInfo
}
}
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';
// AnimationDevelopment class
export default class AnimationDevelopment extends Animation {
constructor(...args) {
super(...args);
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);
// set defaultValues
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';
}
// set additional options
if (Component.defaultOptions) {
propertyInfo.extends = [];
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;
}
}
// set functions
if (Component.functions) {
propertyInfo.interface = [];
propertyInfo.render = [];
propertyInfo.warning = [];
Object.keys(Functions).forEach((fnf) => {
if (fnf in Component.functions) {
if (fnf === 'prepareProperty') propertyInfo.interface.push('fromTo()');
if (fnf === 'prepareStart') propertyInfo.interface.push('to()');
if (fnf === 'onStart') propertyInfo.render = 'can render update';
} else {
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;
}
}
// register Interpolation functions
if (Component.Interpolate) {
propertyInfo.uses = [];
propertyInfo.adds = [];
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}`);
}
propertyInfo.uses.push(`${fni}`);
} else {
Object.keys(compIntObj).forEach((sfn) => {
if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
propertyInfo.adds.push(`${sfn}`);
}
propertyInfo.uses.push(`${sfn}`);
});
}
});
if (propertyInfo.uses.length) {
propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)`;
} else {
delete propertyInfo.uses;
}
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`;
}
// set component util
if (Component.Util) {
propertyInfo.hasUtil = Object.keys(Component.Util).join(',');
}
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'
// const 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 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 ];
}
}
// All Component Functions
const bgPositionFunctions = {
prepareStart: getBgPos,
prepareProperty: prepareBgPos,
onStart: onStartBgPos
}
// Component Full Object
const BackgroundPosition = {
component: 'backgroundPositionProp',
property: 'backgroundPosition',
defaultValue: [50,50],
Interpolate: {numbers},
functions: bgPositionFunctions,
Util: {trueDimension}
}
export default BackgroundPosition
Components.BackgroundPosition = BackgroundPosition
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';
/* bgPosProp = {
property: 'backgroundPosition',
defaultValue: [0,0],
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
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;
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,
};
// Component Full Object
const BackgroundPosition = {
component: 'backgroundPositionProp',
property: 'backgroundPosition',
defaultValue: [50, 50],
Interpolate: { numbers },
functions: bgPositionFunctions,
Util: { trueDimension },
};
export default BackgroundPosition;

View file

@ -1,22 +1,27 @@
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 }
// Component Functions
export function onStartBgPos(prop){
if ( this.valuesEnd[prop] && !KUTE[prop]) { // opacity could be 0
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)}%`;
}
}
}
// Component Base Object
const baseBgPosOps = {
component: 'baseBackgroundPosition',
property: 'backgroundPosition',
Interpolate: {numbers},
functions: {onStart: onStartBgPos}
}
export default baseBgPosOps
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
/* bgPosProp = {
property: 'backgroundPosition',
defaultValue: [0,0],
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
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)}%`;
};
}
}
// Component Base Object
const baseBgPosOps = {
component: 'baseBackgroundPosition',
property: 'backgroundPosition',
Interpolate: { numbers },
functions: { onStart: onStartBgPos },
};
export default baseBgPosOps;

View file

@ -1,48 +1,53 @@
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'
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
const radiusValues = {}
radiusProps.map(x => radiusValues[x] = 0);
// Component Functions
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
});
export function getRadius(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp];
}
export function prepareRadius(tweenProp,value){
return trueDimension(value);
}
// All Component Functions
export const radiusFunctions = {
prepareStart: getRadius,
prepareProperty: prepareRadius,
onStart: radiusOnStart
}
// Full Component
const BorderRadius = {
component: 'borderRadiusProperties',
category: 'borderRadius',
properties: radiusProps,
defaultValues: radiusValues,
Interpolate: {units},
functions: radiusFunctions,
Util: {trueDimension}
}
export default BorderRadius
Components.BorderRadiusProperties = BorderRadius
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';
/* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties
const radiusProps = ['borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
const radiusValues = {};
radiusProps.forEach((x) => { radiusValues[x] = 0; });
// Component Functions
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
export function getRadius(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
export function prepareRadius(tweenProp, value) {
return trueDimension(value);
}
// All Component Functions
export const radiusFunctions = {
prepareStart: getRadius,
prepareProperty: prepareRadius,
onStart: radiusOnStart,
};
// Full Component
const BorderRadius = {
component: 'borderRadiusProperties',
category: 'borderRadius',
properties: radiusProps,
defaultValues: radiusValues,
Interpolate: { units },
functions: radiusFunctions,
Util: { trueDimension },
};
export default BorderRadius;

View file

@ -1,29 +1,35 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} }
// Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius']
// Component Functions
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);
}
}
}
const radiusOnStart = {}
radiusProps.forEach(tweenProp => {
radiusOnStart[tweenProp] = radiusOnStartFn
});
// Base Component
const baseBorderRadius = {
component: 'baseBorderRadius',
category: 'borderRadius',
Interpolate: {units},
functions: {onStart: radiusOnStart}
}
export default baseBorderRadius
import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js';
/* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties
const radiusProps = ['borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
// Component Functions
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);
};
}
}
const radiusOnStart = {};
radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn;
});
// Base Component
const baseBorderRadius = {
component: 'baseBorderRadius',
category: 'borderRadius',
Interpolate: { units },
functions: { onStart: radiusOnStart },
};
export default baseBorderRadius;

View file

@ -1,46 +1,45 @@
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'
// 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);
// Component Functions
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;
}
const boxPropsOnStart = {}
boxModelProperties.map(x => boxPropsOnStart[x] = boxModelOnStart );
// All Component Functions
const boxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart
}
// Component Full Component
const boxModel = {
component: 'boxModelProperties',
category: 'boxModel',
properties: boxModelProperties,
defaultValues: boxModelValues,
Interpolate: {numbers},
functions: boxModelFunctions
}
export default boxModel
Components.BoxModelProperties = boxModel
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.forEach((x) => { boxModelValues[x] = 0; });
// Component Functions
function getBoxModel(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
}
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.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; });
// All Component Functions
const boxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart,
};
// Component Full Component
const boxModel = {
component: 'boxModelProperties',
category: 'boxModel',
properties: boxModelProperties,
defaultValues: boxModelValues,
Interpolate: { numbers },
functions: boxModelFunctions,
};
export default boxModel;

View file

@ -1,28 +1,29 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// Component Functions
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`;
}
}
}
// Component Base Props
const baseBoxProps = ['top','left','width','height']
const baseBoxOnStart = {}
baseBoxProps.map(x=>baseBoxOnStart[x] = boxModelOnStart)
// Component Base
const baseBoxModel = {
component: 'baseBoxModel',
category: 'boxModel',
properties: baseBoxProps,
Interpolate: {numbers},
functions: {onStart: baseBoxOnStart}
}
export default baseBoxModel
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// Component Functions
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`;
};
}
}
// Component Base Props
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 },
};
export default baseBoxModel;

View file

@ -1,44 +1,44 @@
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'
// Component Functions
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;
}
// 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)
// All Component Functions
const essentialBoxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart
}
// Component Essential
const essentialBoxModel = {
component: 'essentialBoxModel',
category: 'boxModel',
properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues,
Interpolate: {numbers},
functions: essentialBoxModelFunctions,
Util:{trueDimension}
}
export default essentialBoxModel
Components.BoxModelEssential = essentialBoxModel
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 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.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; });
// All Component Functions
const essentialBoxModelFunctions = {
prepareStart: getBoxModel,
prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart,
};
// Component Essential
const essentialBoxModel = {
component: 'essentialBoxModel',
category: 'boxModel',
properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues,
Interpolate: { numbers },
functions: essentialBoxModelFunctions,
Util: { trueDimension },
};
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'
// Component Functions
function getClip(tweenProp,v){
const currentClip = getStyleForProperty(this.element,tweenProp),
width = getStyleForProperty(this.element,'width'),
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]) ];
}
}
// All Component Functions
const clipFunctions = {
prepareStart: getClip,
prepareProperty: prepareClip,
onStart: onStartClip
}
// Component Full
const clipProperty = {
component: 'clipProperty',
property: 'clip',
defaultValue: [0,0,0,0],
Interpolate: {numbers},
functions: clipFunctions,
Util: {trueDimension}
}
export default clipProperty
Components.ClipProperty = clipProperty
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/* , 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 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,
};
// Component Full
const clipProperty = {
component: 'clipProperty',
property: 'clip',
defaultValue: [0, 0, 0, 0],
Interpolate: { numbers },
functions: clipFunctions,
Util: { trueDimension },
};
export default clipProperty;

View file

@ -1,27 +1,29 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// Component Functions
export function onStartClip(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;
}
elem.style.clip = `rect(${cl})`;
}
}
}
// Component Base
const baseClip = {
component: 'baseClip',
property: 'clip',
// defaultValue: [0,0,0,0],
Interpolate: {numbers},
functions: {onStart:onStartClip}
}
export default baseClip
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
// Component Functions
export function onStartClip(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
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})`;
};
}
}
// Component Base
const baseClip = {
component: 'baseClip',
property: 'clip',
// defaultValue: [0,0,0,0],
Interpolate: { numbers },
functions: { onStart: onStartClip },
};
export default baseClip;

View file

@ -1,51 +1,50 @@
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'
// 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 = {}
supportedColors.map(tweenProp => {
defaultColors[tweenProp] = '#000'
});
// Component Functions
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
function getColor(prop,value) {
return getStyleForProperty(this.element,prop) || defaultValues[prop];
}
function prepareColor(prop,value) {
return trueColor(value);
}
// All Component Functions
const colorFunctions = {
prepareStart: getColor,
prepareProperty: prepareColor,
onStart: colorsOnStart
}
// Component Full
const colorProperties = {
component: 'colorProperties',
category: 'colors',
properties: supportedColors,
defaultValues: defaultColors,
Interpolate: {numbers,colors},
functions: colorFunctions,
Util: {trueColor}
}
export default colorProperties
Components.ColorProperties = colorProperties
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 = {};
supportedColors.forEach((tweenProp) => {
defaultColors[tweenProp] = '#000';
});
// Component Functions
const colorsOnStart = {};
supportedColors.forEach((x) => {
colorsOnStart[x] = onStartColors;
});
function getColor(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
function prepareColor(prop, value) {
return trueColor(value);
}
// All Component Functions
const colorFunctions = {
prepareStart: getColor,
prepareProperty: prepareColor,
onStart: colorsOnStart,
};
// Component Full
const colorProperties = {
component: 'colorProperties',
category: 'colors',
properties: supportedColors,
defaultValues: defaultColors,
Interpolate: { numbers, colors },
functions: colorFunctions,
Util: { trueColor },
};
export default colorProperties;

View file

@ -1,35 +1,36 @@
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']
// Component Functions
export function onStartColors(tweenProp){
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = colors(a,b,v);
}
}
}
const colorsOnStart = {}
supportedColors.map(x => colorsOnStart[x] = onStartColors)
// Component Base
export const baseColors = {
component: 'baseColors',
category: 'colors',
// properties: supportedColors,
// defaultValues: defaultColors,
Interpolate: {numbers,colors},
functions: {onStart:colorsOnStart}
}
export default baseColors
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'];
// Component Functions
export function onStartColors(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = colors(a, b, v);
};
}
}
const colorsOnStart = {};
supportedColors.forEach((x) => { colorsOnStart[x] = onStartColors; });
// Component Base
export const baseColors = {
component: 'baseColors',
category: 'colors',
// properties: supportedColors,
// defaultValues: defaultColors,
Interpolate: { numbers, colors },
functions: { onStart: colorsOnStart },
};
export default baseColors;

View file

@ -1,79 +1,79 @@
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'
// 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;
return [ x, y ]
}
export function onStartComponent(tweenProp,value){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
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)';
}
} else {
KUTE[tweenProp] = (elem, a, b, v) => {
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';
}
}
}
}
}
// All Component Functions
const componentFunctions = {
prepareStart: getComponentCurrentValue,
prepareProperty: prepareComponentValue,
onStart: onStartComponent
}
// Base Component
export const baseCrossBrowserMove = {
component: 'baseCrossBrowserMove',
property: 'move',
Interpolate: {numbers},
functions: {onStart:onStartComponent}
}
// Full Component
const crossBrowserMove = {
component: 'crossBrowserMove',
property: 'move',
defaultValue: [0,0],
Interpolate: {numbers},
functions: componentFunctions,
Util: {trueProperty}
}
export default crossBrowserMove
Components.CrossBrowserMove = crossBrowserMove
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 */) {
const currentTransform = getInlineStyle(this.element);
const { left } = this.element.style;
const { top } = this.element.style;
let x = 0;
let y = 0;
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 */) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
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)`;
};
} else {
KUTE[tweenProp] = (elem, a, b, v) => {
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`;
}
};
}
}
}
// All Component Functions
const componentFunctions = {
prepareStart: getComponentCurrentValue,
prepareProperty: prepareComponentValue,
onStart: onStartComponent,
};
// Base Component
export const baseCrossBrowserMove = {
component: 'baseCrossBrowserMove',
property: 'move',
Interpolate: { numbers },
functions: { onStart: onStartComponent },
};
// Full Component
const crossBrowserMove = {
component: 'crossBrowserMove',
property: 'move',
defaultValue: [0, 0],
Interpolate: { numbers },
functions: componentFunctions,
Util: { trueProperty },
};
export default crossBrowserMove;

View file

@ -1,134 +1,169 @@
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'
// const 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 parseDropShadow (shadow){
let newShadow
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
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++){
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[3] = trueColor(newShadow[3]);
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'
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);
} else {
result[pp] = p[1].replace(/\'|\"|\)/g,'');
}
}
}
return result
}
// Component Functions
function getFilter(tweenProp,value) {
let currentStyle = getStyleForProperty(this.element,tweenProp),
filterObject = parseFilterString(currentStyle), fnp
for (let fn in value){
fnp = replaceDashNamespace(fn)
if ( !filterObject[fnp] ){
filterObject[fnp] = defaultValues[tweenProp][fn]
}
}
return filterObject;
}
function prepareFilter(tweenProp,value) {
let filterObject = {}, 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:''},
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]
// } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) {
} else {
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]
}
}
}
}
// All Component Functions
const filterFunctions = {
prepareStart: getFilter,
prepareProperty: prepareFilter,
onStart: onStartFilter,
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:''},
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
},
functions: filterFunctions,
Util: {parseDropShadow,parseFilterString,replaceDashNamespace,trueColor}
}
export default filterEffects
Components.FilterEffects = filterEffects
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';
/* 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 parseDropShadow(shadow) {
let newShadow;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
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 += 1) {
newShadow[i] = parseFloat(newShadow[i]);
}
// also the color must be a rgb object
newShadow[3] = trueColor(newShadow[3]);
return newShadow;
}
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 += 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, '');
}
}
}
return result;
}
// Component Functions
function getFilter(tweenProp, value) {
const currentStyle = getStyleForProperty(this.element, tweenProp);
const filterObject = parseFilterString(currentStyle);
let fnp;
Object.keys(value).forEach((fn) => {
fnp = replaceDashNamespace(fn);
if (!filterObject[fnp]) {
filterObject[fnp] = defaultValues[tweenProp][fn];
}
});
return filterObject;
}
function prepareFilter(tweenProp, value) {
const filterObject = {};
let fnp;
// 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: '' | ''
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]);
}
});
return filterObject;
}
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];
}
});
}
}
// All Component Functions
const filterFunctions = {
prepareStart: getFilter,
prepareProperty: prepareFilter,
onStart: onStartFilter,
crossCheck: crossCheckFilter,
};
// Full Component
const filterEffects = {
component: 'filterEffects',
property: 'filter',
// 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,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: { numbers, colors, dropShadow },
},
functions: filterFunctions,
Util: {
parseDropShadow, parseFilterString, replaceDashNamespace, trueColor,
},
};
export default filterEffects;

View file

@ -1,57 +1,69 @@
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 }
// Component Interpolation
export function dropShadow(a,b,v){
let params = [], unit = 'px'
for (let i=0; i<3; i++){
params[i] = ((numbers(a[i],b[i],v) * 100 >>0) /100) + unit
}
return `drop-shadow(${params.concat( colors(a[3],b[3],v) ).join(' ') })`
}
// Component Functions
export function onStartFilter(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) : '')
}
}
}
// 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:''},
Interpolate: {
opacity: numbers,
blur: numbers,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: {numbers,colors,dropShadow}
},
functions: {onStart:onStartFilter}
}
export default baseFilter
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
/* filterEffects = {
property: 'filter',
subProperties: {},
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Interpolation
export function dropShadow(a, b, v) {
const params = [];
const unit = 'px';
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(' ')})`;
}
// Component Functions
export function onStartFilter(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) : '');
};
}
}
// Base Component
const baseFilter = {
component: 'baseFilter',
property: 'filter',
// 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,
saturate: numbers,
grayscale: numbers,
brightness: numbers,
contrast: numbers,
sepia: numbers,
invert: numbers,
hueRotate: numbers,
dropShadow: { numbers, colors, dropShadow },
},
functions: { onStart: onStartFilter },
};
export default baseFilter;

View file

@ -1,93 +1,112 @@
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'
// Component Name
let ComponentName = 'htmlAttributes'
// Component Properties
const svgColors = ['fill','stroke','stop-color'];
// Component Util
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));
}
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) ) {
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) ) {
attributes[tp] = (elem, oneAttr, a, b, v) => {
elem.setAttribute(oneAttr, colors(a,b,v));
}
}
}
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
}
}
return attributesObject;
}
// All Component Functions
const attrFunctions = {
prepareStart: getAttr,
prepareProperty: prepareAttr,
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 },
functions: attrFunctions,
// export to global for faster execution
Util: { replaceUppercase, trueColor, trueDimension }
}
export default htmlAttributes
Components.HTMLAttributes = htmlAttributes
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
const ComponentName = 'htmlAttributes';
// Component Properties
const svgColors = ['fill', 'stroke', 'stop-color'];
// Component Util
function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); }
// Component Functions
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)
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) => {
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
// 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));
};
}
};
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
}
});
return attributesObject;
}
// All Component Functions
const attrFunctions = {
prepareStart: getAttr,
prepareProperty: prepareAttr,
onStart: onStartAttr,
};
// Component Full
const htmlAttributes = {
component: ComponentName,
property: 'attr',
// 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 },
};
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'
// Component Name
let ComponentName = 'baseHTMLAttributes'
// Component Special
let attributes = {};
export {attributes}
export const onStartAttr = {
attr : function(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);
}
}
}
},
attributes : function(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd.attr) {
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}
}
export default baseAttributes
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// Component Name
const ComponentName = 'baseHTMLAttributes';
// Component Special
const attributes = {};
export { attributes };
export const onStartAttr = {
attr(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, vS, vE, v) => {
Object.keys(vE).forEach((oneAttr) => {
KUTE.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v);
});
};
}
},
attributes(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd.attr) {
KUTE[tweenProp] = attributes;
}
},
};
// Component Base
const baseAttributes = {
component: ComponentName,
property: 'attr',
// 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;

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

View file

@ -1,24 +1,30 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const 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
KUTE[tweenProp] = (elem, a, b, v) => {
elem.style[tweenProp] = ((numbers(a,b,v) * 1000)>>0)/1000;
}
}
}
// Base Component
const baseOpacity = {
component: 'baseOpacity',
property: 'opacity',
// defaultValue: 1,
Interpolate: {numbers},
functions: {onStart: onStartOpacity}
}
export default baseOpacity
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
/* opacityProperty = {
property: 'opacity',
defaultValue: 1,
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions
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;
};
}
}
// Base Component
const baseOpacity = {
component: 'baseOpacity',
property: 'opacity',
// defaultValue: 1,
Interpolate: { numbers },
functions: { onStart: onStartOpacity },
};
export default baseOpacity;

View file

@ -1,38 +1,50 @@
import Components from '../objects/components.js'
import numbers from '../interpolation/numbers.js'
import supportPassive from 'shorter-js/src/boolean/supportPassive.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 prepareScroll(prop,value){
return parseInt(value);
}
// All Component Functions
const scrollFunctions = {
prepareStart: getScroll,
prepareProperty: prepareScroll,
onStart: onStartScroll,
onComplete: onCompleteScroll
}
// Full Component
const scrollProperty = {
component: 'scrollProperty',
property: 'scroll',
defaultValue: 0,
Interpolate: {numbers},
functions: scrollFunctions,
// export stuff to global
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive }
}
export default scrollProperty
Components.ScrollProperty = scrollProperty
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';
// 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 prepareScroll(prop, value) {
return parseInt(value, 10);
}
// All Component Functions
const scrollFunctions = {
prepareStart: getScroll,
prepareProperty: prepareScroll,
onStart: onStartScroll,
onComplete: onCompleteScroll,
};
// Full Component
const scrollProperty = {
component: 'scrollProperty',
property: 'scroll',
defaultValue: 0,
Interpolate: { numbers },
functions: scrollFunctions,
// export stuff to global
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive,
},
};
export default scrollProperty;

View file

@ -1,79 +1,84 @@
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'
// Component Util
// events preventing scroll
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
// scroll event options
// it's important to stop propagating when animating scroll
const passiveHandler = supportPassive ? { passive: false } : false
// prevent mousewheel or touch events while tweening scroll
export function preventScroll(e) {
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 toggleScrollEvents(action,element){
element[action]( mouseHoverEvents[0], preventScroll, passiveHandler);
element[action]( touchOrWheel, preventScroll, passiveHandler);
}
export function scrollIn(){
let targets = getScrollTargets.call(this)
if ( 'scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1;
toggleScrollEvents('addEventListener',targets.el)
targets.st.style.pointerEvents = 'none'
}
}
export function scrollOut(){ //prevent scroll when tweening scroll
let targets = getScrollTargets.call(this)
if ( 'scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0;
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;
scrollIn.call(this);
KUTE[tweenProp] = (elem, a, b, v) => {
elem.scrollTop = (numbers(a,b,v))>>0;
};
}
}
export function onCompleteScroll(tweenProp){
scrollOut.call(this)
}
// Base Component
const baseScroll = {
component: 'baseScroll',
property: 'scroll',
// defaultValue: 0,
Interpolate: {numbers},
functions: {
onStart: onStartScroll,
onComplete: onCompleteScroll
},
// unfortunatelly scroll needs all them no matter the packaging
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive }
}
export default baseScroll
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';
// true scroll container
// very important and specific to the component
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;
// prevent mousewheel or touch events while tweening scroll
export function preventScroll(e) {
if (this.scrolling) e.preventDefault();
}
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 scrollIn() {
const targets = getScrollTargets.call(this);
if ('scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1;
toggleScrollEvents('addEventListener', targets.el);
targets.st.style.pointerEvents = 'none';
}
}
export function scrollOut() { // prevent scroll when tweening scroll
const targets = getScrollTargets.call(this);
if ('scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0;
toggleScrollEvents('removeEventListener', targets.el);
targets.st.style.pointerEvents = '';
}
}
// Component Functions
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;
};
}
}
export function onCompleteScroll(/* tweenProp */) {
scrollOut.call(this);
}
// Base Component
const baseScroll = {
component: 'baseScroll',
property: 'scroll',
// defaultValue: 0,
Interpolate: { numbers },
functions: {
onStart: onStartScroll,
onComplete: onCompleteScroll,
},
// unfortunatelly scroll needs all them no matter the packaging
Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive,
},
};
export default baseScroll;

View file

@ -1,93 +1,110 @@
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'
// Component Properties
const shadowProps = ['boxShadow','textShadow']
// Component Util
// box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit
// 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;
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
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]
newShadow = shadow;
}
// make sure the values are ready to tween
for (i=0;i<4;i++){
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);
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 prepareShadow(tweenProp,value) {
// [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';
// 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
// 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;
// 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 = processShadowArray(value,tweenProp);
} else if (value instanceof Array){
value = processShadowArray(value,tweenProp);
}
return value;
}
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow)
// All Component Functions
const shadowFunctions = {
prepareStart: getShadow,
prepareProperty: prepareShadow,
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},
functions: shadowFunctions,
Util: { processShadowArray, trueColor }
}
export default shadowProperties
Components.ShadowProperties = shadowProperties
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'];
// Component Util
// box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit
// 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;
// [h-shadow, v-shadow, color]
if (shadow.length === 3) {
newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none'];
// [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 (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]);
newShadow = tweenProp === 'boxShadow'
? newShadow
: newShadow.filter((x, i) => [0, 1, 2, 4].includes(i));
return newShadow;
}
// Component Functions
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, propValue) {
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
// parseProperty for boxShadow, builds basic structure with ready to tween values
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 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;
// also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px 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);
}
return value;
}
const shadowPropOnStart = {};
shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// All Component Functions
const shadowFunctions = {
prepareStart: getShadow,
prepareProperty: prepareShadow,
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 },
functions: shadowFunctions,
Util: { processShadowArray, trueColor },
};
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'
// Component Properties
const shadowProps = ['boxShadow','textShadow']
// Component Functions
export function onStartShadow(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;
for (let i=0; i<sl; i++){
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(' ');
}
}
}
const shadowPropOnStart = {}
shadowProps.map(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}
}
export default baseShadow
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js';
// Component Properties
const shadowProps = ['boxShadow', 'textShadow'];
// Component Functions
export function onStartShadow(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
// let's start with the numbers | set unit | also determine inset
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 += 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(' ');
};
}
}
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 },
};
export default baseShadow;

View file

@ -1,159 +1,190 @@
import Components from '../objects/components.js'
import selector from '../util/selector.js'
import numbers from '../interpolation/numbers.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 }
// 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 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())
return result[0].length === result[1].length ? result : equalizeSegments(result[0],result[1],tl)
}
function getRotations(a) {
let segCount = a.length, 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]
}
})
})
}
function getRotatedCurve(a,b) {
let segCount = a.length - 1,
lineLengths = [],
computedIndex = 0,
sumLensSqrd = 0,
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
})
computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths))
return rotations[computedIndex]
}
// Component Functions
function getCubicMorph(tweenProp){
return this.element.getAttribute('d');
}
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
// make sure to return pre-processed values
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,'');
}
return pathObject;
}
function crossCheckCubicMorph(tweenProp){
if (this.valuesEnd[tweenProp]) {
let pathCurve1 = this.valuesStart[tweenProp].curve,
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])
this.valuesStart[tweenProp].curve = curve0;
this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1],curve0)
}
}
}
// All Component Functions
const svgCubicMorphFunctions = {
prepareStart: getCubicMorph,
prepareProperty: prepareCubicMorph,
onStart: onStartCubicMorph,
crossCheck: crossCheckCubicMorph
}
// Component Full
const svgCubicMorph = {
component: 'svgCubicMorph',
property: 'path',
defaultValue: [],
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
}
}
export default svgCubicMorph
Components.SVGCubicMorph = svgCubicMorph
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';
/* 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) => {
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) {
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);
}
function getRotations(a) {
const segCount = a.length;
const pointCount = segCount - 1;
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) {
const segCount = a.length - 1;
const lineLengths = [];
let computedIndex = 0;
let sumLensSqrd = 0;
const rotations = getRotations(a);
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));
return rotations[computedIndex];
}
// Component Functions
function getCubicMorph(/* tweenProp, value */) {
return this.element.getAttribute('d');
}
function prepareCubicMorph(tweenProp, value) {
// get path d attribute or create a path from string value
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) {
return value;
} 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) {
if (this.valuesEnd[tweenProp]) {
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)) {
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);
}
}
}
// All Component Functions
const svgCubicMorphFunctions = {
prepareStart: getCubicMorph,
prepareProperty: prepareCubicMorph,
onStart: onStartCubicMorph,
crossCheck: crossCheckCubicMorph,
};
// Component Full
const svgCubicMorph = {
component: 'svgCubicMorph',
property: 'path',
defaultValue: [],
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,
},
};
export default svgCubicMorph;

View file

@ -1,33 +1,39 @@
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 }
// Component Functions
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
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 );
}
}
elem.setAttribute("d", v === 1 ? b.original : pathToString(curve) )
}
}
}
// Component Base
const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
property: 'path',
// defaultValue: [],
Interpolate: {numbers,pathToString},
functions: {onStart:onStartCubicMorph}
}
export default baseSvgCubicMorph
import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers} },
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Functions
export function onStartCubicMorph(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
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 (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));
};
}
}
// Component Base
const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
property: 'path',
// defaultValue: [],
Interpolate: { numbers, pathToString },
functions: { onStart: onStartCubicMorph },
};
export default baseSvgCubicMorph;

View file

@ -1,145 +1,164 @@
import Components from '../objects/components.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 }
// Component Util
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);
}
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 c = p.split(',');
if (c.length != 2) { return; } // return undefined
if (isNaN(c[0]) || isNaN(c[1])) { return; }
return [parseFloat(c[0]), parseFloat(c[1])];
};
const dist = (c1, c2) => {
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]));
}
}
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
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);
}
function getCircleLength(el) { // return the length of the circle
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;
}
function getTotalLength(el) { // returns the result of any of the below functions
if ('rect'===el.tagName) {
return getRectLength(el);
} else if ('circle'===el.tagName) {
return getCircleLength(el);
} else if ('ellipse'===el.tagName) {
return getEllipseLength(el);
} else if (['polygon','polyline'].indexOf(el.tagName)>-1) {
return getPolyLength(el);
} else if ('line'===el.tagName) {
return getLineLength(el);
}
}
function getDraw(e,v) {
let length = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e),
start, end, d, o;
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(/\,/);
start = 0-o;
end = parseFloat(d[0]) + start || length;
}
return { s: start, e: end, l: length };
}
function resetDraw(elem) {
elem.style.strokeDashoffset = ``;
elem.style.strokeDasharray = ``;
}
// Component Functions
function getDrawValue(){
return getDraw(this.element);
}
function prepareDraw(a,o){
return getDraw(this.element,o);
}
// All Component Functions
const svgDrawFunctions = {
prepareStart: getDrawValue,
prepareProperty: prepareDraw,
onStart: onStartDraw
}
// Component Full
const svgDraw = {
component: 'svgDraw',
property: 'draw',
defaultValue: '0% 0%',
Interpolate: {numbers},
functions: svgDrawFunctions,
// Export to global for faster execution
Util: {
getRectLength,
getPolyLength,
getLineLength,
getCircleLength,
getEllipseLength,
getTotalLength,
resetDraw,
getDraw,
percent
}
}
export default svgDraw
Components.SVGDraw = svgDraw
import getStyleForProperty from '../process/getStyleForProperty.js';
import numbers from '../interpolation/numbers.js';
import { onStartDraw } from './svgDrawBase.js';
/* svgDraw = {
property: 'draw',
defaultValue,
Interpolate: {numbers} },
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Util
function percent(v, l) {
return (parseFloat(v) / 100) * l;
}
// http://stackoverflow.com/a/30376660
// 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) {
const points = el.getAttribute('points').split(' ');
let len = 0;
if (points.length > 1) {
const coord = (p) => {
const c = p.split(',');
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) {
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 += 1) {
len += dist(coord(points[i]), coord(points[i + 1]));
}
}
len += el.tagName === 'polygon'
? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
}
return len;
}
// 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 the length of the circle
function getCircleLength(el) {
const r = el.getAttribute('r');
return 2 * Math.PI * r;
}
// 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;
}
// returns the result of any of the below functions
function getTotalLength(el) {
if (el.tagName === 'rect') {
return getRectLength(el);
} if (el.tagName === 'circle') {
return getCircleLength(el);
} if (el.tagName === 'ellipse') {
return getEllipseLength(el);
} if (['polygon', 'polyline'].includes(el.tagName)) {
return getPolyLength(el);
} if (el.tagName === 'line') {
return getLineLength(el);
}
// ESLint
return 0;
}
function getDraw(element, value) {
const length = /path|glyph/.test(element.tagName)
? element.getTotalLength()
: getTotalLength(element);
let start;
let end;
let dasharray;
let offset;
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 - offset;
end = parseFloat(dasharray[0]) + start || length;
}
return { s: start, e: end, l: length };
}
function resetDraw(elem) {
elem.style.strokeDashoffset = '';
elem.style.strokeDasharray = '';
}
// Component Functions
function getDrawValue(/* prop, value */) {
return getDraw(this.element);
}
function prepareDraw(a, o) {
return getDraw(this.element, o);
}
// All Component Functions
const svgDrawFunctions = {
prepareStart: getDrawValue,
prepareProperty: prepareDraw,
onStart: onStartDraw,
};
// Component Full
const svgDraw = {
component: 'svgDraw',
property: 'draw',
defaultValue: '0% 0%',
Interpolate: { numbers },
functions: svgDrawFunctions,
// Export to global for faster execution
Util: {
getRectLength,
getPolyLength,
getLineLength,
getCircleLength,
getEllipseLength,
getTotalLength,
resetDraw,
getDraw,
percent,
},
};
export default svgDraw;

View file

@ -1,30 +1,35 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const 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;
elem.style.strokeDashoffset = `${offset}px`;
elem.style.strokeDasharray = `${((dashOne <1 ? 0 : dashOne)*100>>0)/100}px, ${pathLength}px`;
}
}
}
// Component Base
const baseSVGDraw = {
component: 'baseSVGDraw',
property: 'draw',
Interpolate: {numbers},
functions: {onStart:onStartDraw}
}
export default baseSVGDraw
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
/* 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) => {
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`;
};
}
}
// Component Base
const baseSVGDraw = {
component: 'baseSVGDraw',
property: 'draw',
Interpolate: { numbers },
functions: { onStart: onStartDraw },
};
export default baseSVGDraw;

View file

@ -1,267 +1,326 @@
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'
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component Interpolation
// function function(array1, array2, length, progress)
// Component Util
// 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 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;
if (!pathArray.length || pathArray[0][0] !== "M") {
return false;
}
for (let i = 0; i < pathlen; i++) {
segment = pathArray[i]
pathCommand = segment[0]
if (pathCommand === "M" && i || pathCommand === "Z") {
break; // !!
} else if ('ML'.indexOf( pathCommand) > -1) {
ring.push([segment[1], segment[2]]);
} else {
return false;
}
}
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;
if ( maxSegmentLength && !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)
ring.push([point.x, point.y]);
}
// Make all rings clockwise
if (!getDrawDirection(curvePath)) {
ring.reverse();
}
return {
pathLength,
ring,
skipBisect: true
};
}
function rotateRing(ring, vs) {
let len = ring.length, min = Infinity, bestOffset, sumOfSquares, spliced;
for (let offset = 0; offset < len; offset++) {
sumOfSquares = 0;
vs.forEach(function(p, i) {
let d = distanceSquareRoot(ring[(offset + i) % len], p);
sumOfSquares += d * d;
});
if (sumOfSquares < min) {
min = sumOfSquares;
bestOffset = offset;
}
}
if (bestOffset) {
spliced = ring.splice(0, bestOffset);
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;
while (ring.length < desiredLength) {
a = ring[i]
b = ring[(i + 1) % ring.length]
// console.log(step,a,b)
segment = distanceSquareRoot(a, b)
if (insertAt <= cursor + segment) {
ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) );
insertAt += step;
continue;
}
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];
// Could splice the whole set for a segment instead, but a bit messy
while (distanceSquareRoot(a, b) > maxSegmentLength) {
b = midPoint(a, b, 0.5);
ring.splice(i + 1, 0, b);
}
}
}
function normalizeRing(ring, maxSegmentLength) {
let points, skipBisect, pathLength;
if (typeof ring === "string") {
let converted = pathStringToRing(ring, maxSegmentLength)
ring = converted.ring
skipBisect = converted.skipBisect
pathLength = converted.pathLength
} else if (!Array.isArray(ring)) {
throw (invalidPathValue)
}
points = ring.slice(0)
points.pathLength = pathLength
if (!validRing(points)) {
throw (invalidPathValue)
}
// 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()
}
if ( !skipBisect && maxSegmentLength && !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]))
}
function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) {
morphPrecision = morphPrecision || defaultOptions.morphPrecision
let fromRing = normalizeRing(pathArray1, morphPrecision),
toRing = normalizeRing(pathArray2, morphPrecision),
diff = fromRing.length - toRing.length;
addPoints(fromRing, diff < 0 ? diff * -1 : 0);
addPoints(toRing, diff > 0 ? diff : 0);
rotateRing(fromRing,toRing);
return [roundPath(fromRing),roundPath(toRing)]
}
// Component functions
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
// first make sure we return pre-processed values
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,'');
}
return pathObject;
}
function crossCheckSVGMorph(prop){
if ( this.valuesEnd[prop]){
let pathArray1 = this.valuesStart[prop].pathArray,
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];
}
}
}
// All Component Functions
const svgMorphFunctions = {
prepareStart: getSVGMorph,
prepareProperty: prepareSVGMorph,
onStart: onStartSVGMorph,
crossCheck: crossCheckSVGMorph
}
// Component Full
const svgMorph = {
component: 'svgMorph',
property: 'path',
defaultValue: [],
Interpolate: coords,
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
}
}
export default svgMorph
Components.SVGMorph = svgMorph
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';
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers,coords},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Interpolation
// function function(array1, array2, length, progress)
// Component Util
// 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 exactRing(pathArray) {
const ring = [];
const pathlen = pathArray.length;
let segment = [];
let pathCommand = '';
let pathLength = 0;
if (!pathArray.length || pathArray[0][0] !== 'M') {
return false;
}
for (let i = 0; i < pathlen; i += 1) {
segment = pathArray[i];
[pathCommand] = segment;
if ((pathCommand === 'M' && i) || pathCommand === 'Z') {
break; // !!
} else if ('ML'.indexOf(pathCommand) > -1) {
ring.push([segment[1], segment[2]]);
} else {
return false;
}
}
pathLength = polygonLength(ring);
return pathlen ? { ring, pathLength } : false;
}
function approximateRing(parsed, maxSegmentLength) {
const ringPath = splitPath(pathToString(parsed))[0];
const curvePath = pathToCurve(ringPath, 4);
const pathLength = getPathLength(curvePath);
const ring = [];
let numPoints = 3;
let point;
if (maxSegmentLength && !Number.isNaN(maxSegmentLength) && +maxSegmentLength > 0) {
numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength));
}
for (let i = 0; i < numPoints; i += 1) {
point = getPointAtLength(curvePath, (pathLength * i) / numPoints);
ring.push([point.x, point.y]);
}
// Make all rings clockwise
if (!getDrawDirection(curvePath)) {
ring.reverse();
}
return {
pathLength,
ring,
skipBisect: true,
};
}
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((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;
bestOffset = offset;
}
}
if (bestOffset) {
spliced = ring.splice(0, bestOffset);
ring.splice(ring.length, 0, ...spliced);
}
}
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];
segment = distanceSquareRoot(a, b);
if (insertAt <= cursor + segment) {
ring.splice(i + 1, 0, segment
? midPoint(a, b, (insertAt - cursor) / segment)
: a.slice(0));
insertAt += step;
} else {
cursor += segment;
i += 1;
}
}
}
function bisect(ring, maxSegmentLength = Infinity) {
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) {
b = midPoint(a, b, 0.5);
ring.splice(i + 1, 0, b);
}
}
}
function validRing(ring) {
return Array.isArray(ring)
&& ring.every((point) => Array.isArray(point)
&& point.length === 2
&& !Number.isNaN(point[0])
&& !Number.isNaN(point[1]));
}
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 Error(`${invalidPathValue}: ${ring}`);
}
const points = ring.slice(0);
points.pathLength = pathLength;
if (!validRing(points)) {
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();
}
if (!skipBisect && maxSegmentLength
&& !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) {
bisect(points, maxSegmentLength);
}
return points;
}
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);
return [roundPath(fromRing), roundPath(toRing)];
}
// Component functions
function getSVGMorph(/* tweenProp */) {
return this.element.getAttribute('d');
}
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) {
return value;
} 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]) {
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)) {
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;
}
}
}
// All Component Functions
const svgMorphFunctions = {
prepareStart: getSVGMorph,
prepareProperty: prepareSVGMorph,
onStart: onStartSVGMorph,
crossCheck: crossCheckSVGMorph,
};
// Component Full
const svgMorph = {
component: 'svgMorph',
property: 'path',
defaultValue: [],
Interpolate: coords,
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,
},
};
export default svgMorph;

View file

@ -1,24 +1,30 @@
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 }
// Component functions
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`) );
}
}
}
// Component Base
const baseSVGMorph = {
component: 'baseSVGMorph',
property: 'path',
Interpolate: coords,
functions: {onStart:onStartSVGMorph}
}
export default baseSVGMorph
import KUTE from '../objects/kute.js';
import coords from '../interpolation/coords.js';
/* SVGMorph = {
property: 'path',
defaultValue: [],
interpolators: {numbers,coords} },
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component functions
export function onStartSVGMorph(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
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`));
};
}
}
// Component Base
const baseSVGMorph = {
component: 'baseSVGMorph',
property: 'path',
Interpolate: coords,
functions: { onStart: onStartSVGMorph },
};
export default baseSVGMorph;

View file

@ -1,130 +1,175 @@
import numbers from '../interpolation/numbers.js'
import Components from '../objects/components.js'
import {svgTransformOnStart} from './svgTransformBase.js'
// 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);
}
// 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 = {};
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];
}
}
return c;
}
function parseTransformSVG (p,v){
let 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;
let origin = this._transformOrigin;
let translation;
origin = typeof (origin) !== 'undefined' ? (origin.constructor === Array ? origin : origin.split(/\s/)) : [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);
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];
} else if (/skew/.test(i)) {
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);
}
// returns an obect with current transform attribute 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);
}
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')) );
// populate the valuesStart first
for ( let tp in currentTransform ) {
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
);
valuesStart.translate = [startMatrix.matrix.e,startMatrix.matrix.f]; // finally the translate we're looking for
// copy existing and unused properties to the valuesEnd
for ( let s in valuesStart) {
if ( !(s in valuesEnd) || s==='origin') {
valuesEnd[s] = valuesStart[s];
}
}
}
}
// All Component Functions
export const svgTransformFunctions = {
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform,
onStart: svgTransformOnStart,
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},
functions: svgTransformFunctions,
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG }
}
export default svgTransform
Components.SVGTransformProperty = svgTransform
import numbers from '../interpolation/numbers.js';
import { svgTransformOnStart } from './svgTransformBase.js';
/* const svgTransform = {
property: 'svgTransform',
subProperties,
defaultValue,
Interpolate: {numbers},
functions
} */
// Component Util
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) {
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 += 1) {
const [prop, val] = d[j].trim().split('(');
c[prop] = val;
}
}
return c;
}
function parseTransformSVG(p, v) {
const svgTransformObject = {};
// by default the transformOrigin is "50% 50%" of the shape box
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;
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);
svgTransformObject.origin = origin;
// 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;
}
});
return svgTransformObject;
}
// Component Functions
function prepareSvgTransform(p, v) {
return parseTransformSVG.call(this, p, v);
}
// returns an obect with current transform attribute value
function getStartSvgTransform(tweenProp, value) {
const transformObject = {};
const currentTransform = parseTransformString(this.element.getAttribute('transform'));
// 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]) {
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
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 // 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
);
// finally the translate we're looking for
valuesStart.translate = [startMatrix.matrix.e, startMatrix.matrix.f];
// copy existing and unused properties to the valuesEnd
Object.keys(valuesStart).forEach((s) => {
if (!(s in valuesEnd) || s === 'origin') {
valuesEnd[s] = valuesStart[s];
}
});
}
}
// All Component Functions
export const svgTransformFunctions = {
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform,
onStart: svgTransformOnStart,
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 },
functions: svgTransformFunctions,
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG },
};
export default svgTransform;

View file

@ -1,54 +1,66 @@
import KUTE from '../objects/kute.js'
import numbers from '../interpolation/numbers.js'
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions }
// Component Functions
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;
// 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
// 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})` : '' ) );
}
}
}
// Component Base
const baseSVGTransform = {
component: '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}
}
export default baseSVGTransform
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
/* svgTransform = {
property: 'svgTransform',
subProperties,
defaultValue,
Interpolate: {numbers},
functions
} */
// Component Functions
export function svgTransformOnStart(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (l, a, b, v) => {
let x = 0;
let y = 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
// 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})` : ''));
};
}
}
// Component Base
const baseSVGTransform = {
component: '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 },
};
export default baseSVGTransform;

View file

@ -1,45 +1,51 @@
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'
// const textProperties = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
// Component Properties
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];
}
export function prepareTextProp(prop,value) {
return trueDimension(value);
}
// All Component Functions
const textPropFunctions = {
prepareStart: getTextProp,
prepareProperty: prepareTextProp,
onStart: textOnStart
}
// Component Full
const textProperties = {
component: 'textProperties',
category: 'textProperties',
properties: textProps,
defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
functions: textPropFunctions,
Util: {trueDimension}
}
export default textProperties
Components.TextProperties = textProperties
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';
/* textProperties = {
category: 'textProperties',
defaultValues: [],
interpolators: {units}
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Properties
const textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
// Component Functions
textProps.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
export function getTextProp(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
}
export function prepareTextProp(prop, value) {
return trueDimension(value);
}
// All Component Functions
const textPropFunctions = {
prepareStart: getTextProp,
prepareProperty: prepareTextProp,
onStart: textOnStart,
};
// Component Full
const textProperties = {
component: 'textProperties',
category: 'textProperties',
properties: textProps,
defaultValues: {
fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0,
},
Interpolate: { units },
functions: textPropFunctions,
Util: { trueDimension },
};
export default textProperties;

View file

@ -1,31 +1,37 @@
import KUTE from '../objects/kute.js'
import units from '../interpolation/units.js'
// const opacity = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} }
// Component Properties
const textProperties = ['fontSize','lineHeight','letterSpacing','wordSpacing']
const textOnStart = {}
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);
}
}
}
textProperties.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart
})
// Component Base
const baseTextProperties = {
component: 'baseTextProperties',
category: 'textProps',
// properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units},
functions: {onStart:textOnStart}
}
export default baseTextProperties
import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js';
/* textProperties = {
category: 'textProperties',
defaultValues: [],
interpolators: {units},
functions = { prepareStart, prepareProperty, onStart:{}
} */
// Component Properties
const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {};
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);
};
}
}
textProperties.forEach((tweenProp) => {
textOnStart[tweenProp] = textPropOnStart;
});
// Component Base
const baseTextProperties = {
component: 'baseTextProperties',
category: 'textProps',
// properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: { units },
functions: { onStart: textOnStart },
};
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 {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){
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]
}
return textWriteWrapper
}
function getTextPartsArray(el,classNAME){
let elementsArray = []
if (el.children.length) {
let 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)
if (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],'')
}
!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 )
}
elementsArray = elementsArray.concat(textParts)
} else {
elementsArray = elementsArray.concat([wrapContentsSpan(el,classNAME)])
}
return elementsArray
}
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('')
return [oldTargetSegs,newTargetSegs]
}
export function createTextTweens(target,newText,options){
if (target.playing) return;
options = options || {}
options.duration = options.duration === 'auto' ? 'auto' : isFinite(options.duration*1) ? options.duration*1 : 1000;
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'));
let textTween = [], totalDelay = 0
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
totalDelay += options.duration
return new connect.tween(el, {text:el.innerHTML}, {text:''}, options );
}));
textTween = textTween.concat(newTargets.map((el,i)=> {
const 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
return new connect.tween(el, {text:''}, {text:newTargetSegs[i].innerHTML}, options );
}));
textTween.start = function(){
!target.playing && textTween.map(tw=>tw.start()) && (target.playing = true)
}
return textTween
}
// Component Functions
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
}
}
// All Component Functions
export const textWriteFunctions = {
prepareStart: getWrite,
prepareProperty: prepareText,
onStart: onStartWrite
}
// const 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'},
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
functions: textWriteFunctions,
// export to global for faster execution
Util: { charSet, createTextTweens }
}
export default textWrite
Components.TextWriteProperties = textWrite
import connect from '../objects/connect.js';
import numbers from '../interpolation/numbers.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) {
let textWriteWrapper;
let newElem;
if (typeof (el) === 'string') {
newElem = document.createElement('SPAN');
newElem.innerHTML = el;
newElem.className = classNAME;
return newElem;
}
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 = [];
const len = el.children.length;
if (len) {
const textParts = [];
let remainingMarkup = el.innerHTML;
let wrapperParts;
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], '');
} else if (wrapperParts[1] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME);
textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], '');
}
if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME);
textParts.push(currentChild);
remainingMarkup = remainingMarkup.replace(childOuter, '');
}
if (remainingMarkup !== '') {
const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME);
textParts.push(unTaggedRemaining);
}
elementsArray = elementsArray.concat(textParts);
} else {
elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]);
}
return elementsArray;
}
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('');
return [oldTargetSegs, newTargetSegs];
}
export function createTextTweens(target, newText, ops) {
if (target.playing) return false;
const options = ops || {};
options.duration = 1000;
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];
const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
const newTargets = [].slice.call(target.getElementsByClassName('newText'));
let textTween = [];
let totalDelay = 0;
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;
totalDelay += options.duration;
return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options);
}));
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;
return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options);
}));
textTween.start = function startTweens() {
if (!target.playing) {
textTween.forEach((tw) => tw.start());
target.playing = true;
}
};
return textTween;
}
// Component Functions
function getWrite(/* tweenProp, value */) {
return this.element.innerHTML;
}
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,
};
/* 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' },
defaultOptions: { textChars: 'alpha' },
Interpolate: { numbers },
functions: textWriteFunctions,
// export to global for faster execution
Util: { charSet, createTextTweens },
};
export default textWrite;

View file

@ -1,78 +1,86 @@
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 charSet = {
alpha: lowerCaseAlpha, // lowercase
upper: upperCaseAlpha, // uppercase
symbols: nonAlpha, // symbols
numeric: numeric,
alphanumeric: alphaNumeric,
all: allTypes,
}
export {charSet}
// Component Functions
export const onStartWrite = {
text: function(tweenProp){
if ( !KUTE[tweenProp] && this.valuesEnd[tweenProp] ) {
let chars = this._textChars,
charsets = chars in charSet ? charSet[chars]
: chars && chars.length ? chars
: charSet[defaultOptions.textChars]
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];
if (a === ' ') {
endText = firstLetterB.substring(Math.min(v * firstLetterB.length, firstLetterB.length)>>0, 0 );
elem.innerHTML = v < 1 ? ( ( endText + pointer ) ) : (b === '' ? ' ' : b);
} else if (b === ' ') {
initialText = firstLetterA.substring(0, Math.min((1-v) * firstLetterA.length, firstLetterA.length)>>0 );
elem.innerHTML = v < 1 ? ( ( initialText + pointer ) ) : (b === '' ? ' ' : b);
} 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);
}
}
}
},
number: function(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;
}
}
}
}
// Base Component
export const baseTextWrite = {
component: 'baseTextWrite',
category: 'textWrite',
// properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers},
functions: {onStart:onStartWrite},
// export to global for faster execution
Util: { charSet }
}
export default baseTextWrite
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
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,
alphanumeric: alphaNumeric,
all: allTypes,
};
export { charSet };
// Component Functions
export const onStartWrite = {
text(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
const chars = this._textChars;
let charsets = charSet[defaultOptions.textChars];
if (chars in charSet) {
charsets = charSet[chars];
} else if (chars && chars.length) {
charsets = chars;
}
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)) : finalText;
} else if (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)) : finalText;
}
};
}
},
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;
};
}
},
};
// Base Component
export const baseTextWrite = {
component: 'baseTextWrite',
category: 'textWrite',
// properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' },
Interpolate: { numbers },
functions: { onStart: onStartWrite },
// export to global for faster execution
Util: { charSet },
};
export default baseTextWrite;

View file

@ -1,109 +1,144 @@
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'
// const 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);
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]);
if (arrayFunctions.includes(x)) {
let 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
} 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;
}
transformObject[fnId] = fnArray;
} else if (x==='rotate') { // rotate
transformObject['rotate3d'] = [0,0,pv]
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
}
}
return transformObject;
}
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
}
}
}
}
// All Component Functions
const transformFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
crossCheck: crossCheckTransform
}
const supportedTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'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
}
// Full Component
const transformFunctionsComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: supportedTransformProperties,
defaultValues: defaultTransformValues,
functions: transformFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
export default transformFunctionsComponent
Components.TransformFunctions = transformFunctionsComponent
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';
/* 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 */) {
const currentStyle = getInlineStyle(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
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)) {
const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
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 = [];
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 { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
}
});
return transformObject;
}
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;
}
}
}
}
// All Component Functions
const transformFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
crossCheck: crossCheckTransform,
};
const supportedTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'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,
};
// Full Component
const transformFunctionsComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: supportedTransformProperties,
defaultValues: defaultTransformValues,
functions: transformFunctions,
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default transformFunctionsComponent;

View file

@ -1,39 +1,48 @@
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
// Component Functions
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
}
}
}
// Base Component
const BaseTransform = {
component: 'baseTransform',
property: 'transform',
functions: {onStart: onStartTransform},
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
}
}
export default BaseTransform
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';
/* transformFunctions = {
property: 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// same to svg transform, attr
// Component Functions
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
};
}
}
// Base Component
const BaseTransform = {
component: 'baseTransform',
property: 'transform',
functions: { onStart: onStartTransform },
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default BaseTransform;

View file

@ -1,134 +1,163 @@
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 {onStartLegacyTransform} from './transformLegacyBase.js'
import transformProperty from '../util/transformProperty.js'
import supportTransform from '../util/supportLegacyTransform.js'
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // 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){
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']
for (let x in obj) {
let pv = typeof(obj[x]) === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x])
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]
}
} 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
}
}
} 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;
}
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
} else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv
}
}
return transformObject;
}
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
}
}
}
}
// All Component Functions
const transformLegacyFunctions = {
prepareStart: getLegacyTransform,
prepareProperty: prepareLegacyTransform,
onStart: onStartLegacyTransform,
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
}
const legacyTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale'
]
// Full Component
const transformLegacyComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: legacyTransformProperties,
defaultValues: legacyTransformValues,
functions: transformLegacyFunctions,
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
},
Util: [transformProperty]
}
export default transformLegacyComponent
Components.TransformLegacy = transformLegacyComponent
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 { 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 } */
// 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 */) {
const currentStyle = getInlineStyleLegacy(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
function prepareLegacyTransform(prop, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
const translateArray = []; const rotateArray = []; const skewArray = [];
const transformObject = {};
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)) {
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;
}
}
} 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 = [];
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;
}
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;
}
});
return transformObject;
}
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;
}
}
}
}
// All Component Functions
const transformLegacyFunctions = {
prepareStart: getLegacyTransform,
prepareProperty: prepareLegacyTransform,
onStart: onStartLegacyTransform,
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,
};
const legacyTransformProperties = [
'perspective',
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
'skewX', 'skewY', 'skew',
'scale',
];
// Full Component
const transformLegacyComponent = {
component: 'transformFunctions',
property: 'transform',
subProperties: legacyTransformProperties,
defaultValues: legacyTransformValues,
functions: transformLegacyFunctions,
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: [transformProperty],
};
export default transformLegacyComponent;

View file

@ -1,56 +1,63 @@
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'
// const baseLegacyTransform = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr
// the component that handles all browsers IE9+
// Component Functions
export function onStartLegacyTransform(tweenProp){
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
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
}
} 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
}
}
}
}
// Base Component
const BaseLegacyTransform = {
component: 'baseLegacyTransform',
property: 'transform',
functions: {onStart: onStartLegacyTransform},
Interpolate: {
perspective: perspective,
translate3d: translate3d,
rotate3d: rotate3d,
translate: translate, rotate: rotate, scale: scale, skew: skew
},
Util: {transformProperty}
}
export default BaseLegacyTransform
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 supportTransform from '../util/supportLegacyTransform.js';
import transformProperty from '../util/transformProperty.js';
/* baseLegacyTransform = {
property: 'transform',
subProperties,
defaultValues,
Interpolate: {translate,rotate,skew,scale},
functions } */
// same to svg transform, attr
// the component that handles all browsers IE9+
// Component Functions
export function onStartLegacyTransform(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
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
};
} 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
};
}
}
}
// Base Component
const BaseLegacyTransform = {
component: 'baseLegacyTransform',
property: 'transform',
functions: { onStart: onStartLegacyTransform },
Interpolate: {
perspective,
translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
Util: { transformProperty },
};
export default BaseLegacyTransform;

View file

@ -1,117 +1,154 @@
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'
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component name
const matrixComponent = 'transformMatrix'
// Component Functions
function getTransform(tweenProp, value){
let transformObject = {}
if (this.element[matrixComponent]) {
const currentValue = this.element[matrixComponent]
for (const vS in currentValue) {
transformObject[vS] = currentValue[vS]
}
} else {
for (const vE in value){
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE]
}
}
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]
} else { // perspective
transformObject[prop] = parseInt(value[prop]);
}
}
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
}
})
return transformObject;
} else { // 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`)
}
}
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]
}
}
}
function crossCheckTransform(tweenProp){
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective
}
}
}
// All Component Functions
const matrixFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
onComplete: onCompleteTransform,
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},
functions: matrixFunctions,
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
export default matrixTransform
Components.TransformMatrix = matrixTransform
import defaultValues from '../objects/defaultValues.js';
import numbers from '../interpolation/numbers.js';
import arrays from '../interpolation/arrays.js';
import { onStartTransform } from './transformMatrixBase.js';
/* transformMatrix = {
property : 'transform',
defaultValue: {},
interpolators: {}
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component name
const matrixComponent = 'transformMatrix';
// Component Functions
function getTransform(tweenProp, value) {
const transformObject = {};
const currentValue = this.element[matrixComponent];
if (currentValue) {
Object.keys(currentValue).forEach((vS) => {
transformObject[vS] = currentValue[vS];
});
} else {
Object.keys(value).forEach((vE) => {
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE];
});
}
return transformObject;
}
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], 10);
}
});
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;
} // string | array
// if ( typeof (value) === 'object' && value.length ) {
// } else if ( typeof (value) === string && value.includes('matrix')) {
// decompose matrix to object
throw Error(`KUTE.js - "${value}" is not valid/supported transform function`);
}
function onCompleteTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
this.element[matrixComponent] = {};
Object.keys(this.valuesEnd[tweenProp]).forEach((tf) => {
this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf];
});
}
}
function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
}
}
}
// All Component Functions
const matrixFunctions = {
prepareStart: getTransform,
prepareProperty: prepareTransform,
onStart: onStartTransform,
onComplete: onCompleteTransform,
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,
},
functions: matrixFunctions,
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays,
},
};
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'
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component name
const matrixComponent = 'transformMatrixBase'
// Component special
const CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix
: null
// Component Functions
export const onStartTransform = {
transform : function(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix(), transformObject = {}
for ( const p in b ) {
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v)
}
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
}
}
},
CSS3Matrix: function(prop) {
if (this.valuesEnd.transform){
!KUTE[prop] && (KUTE[prop] = CSS3Matrix)
}
},
}
// Component Base Object
export const baseMatrixTransform = {
component: matrixComponent,
property: 'transform',
functions: {onStart: onStartTransform},
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays
}
}
export default baseMatrixTransform
import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import arrays from '../interpolation/arrays.js';
/* transformMatrix = {
property : 'transform',
defaultValue: {},
interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component name
const matrixComponent = 'transformMatrixBase';
// Component special
// this component is restricted to modern browsers only
const CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
// Component Functions
export const onStartTransform = {
transform(tweenProp) {
if (CSS3Matrix && this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix();
const tObject = {};
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;
}
// 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(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 },
Interpolate: {
perspective: numbers,
translate3d: arrays,
rotate3d: arrays,
skew: arrays,
scale3d: arrays,
},
};
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,15 +1,15 @@
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,
remove,
getAll,
removeAll,
stop,
linkInterpolation
}
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,
remove,
getAll,
removeAll,
stop,
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'
export default function() { // DON'T change
for (const component in linkProperty){
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])
} 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])
} else {
for (const j in componentLink[fnObj]){
if (componentLink[i] && typeof(componentLink[i][j]) === 'function' ) { // transformMatrix
!KUTE[j] && (KUTE[j] = componentLink[i][j])
}
}
}
}
}
}
}
}
}
import KUTE from '../objects/kute.js';
import linkProperty from '../objects/linkProperty.js';
import supportedProperties from '../objects/supportedProperties.js';
export default function linkInterpolation() { // DON'T change
Object.keys(linkProperty).forEach((component) => {
const componentLink = linkProperty[component];
const componentProps = supportedProperties[component];
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 {
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 {
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'
export default function(){
// fire onStart actions
for (let obj in onStart) {
if (typeof (onStart[obj]) === 'function') {
onStart[obj].call(this,obj) // easing functions
} else {
for (let prop in onStart[obj]) {
onStart[obj][prop].call(this,prop);
}
}
}
// add interpolations
linkInterpolation.call(this)
}
import onStart from '../objects/onStart.js';
import linkInterpolation from './linkInterpolation.js';
export default function queueStart() {
// fire onStart actions
Object.keys(onStart).forEach((obj) => {
if (typeof (onStart[obj]) === 'function') {
onStart[obj].call(this, obj); // easing functions
} else {
Object.keys(onStart[obj]).forEach((prop) => {
onStart[obj][prop].call(this, prop);
});
}
});
// add interpolations
linkInterpolation.call(this);
}

View file

@ -1,5 +1,6 @@
import Tweens from '../objects/tweens.js'
export default (tw) => {
let i = Tweens.indexOf(tw)
i !== -1 && Tweens.splice(i, 1)
}
import Tweens from '../objects/tweens.js';
export default (tw) => {
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,61 +1,62 @@
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 = {}
Time.now = self.performance.now.bind(self.performance)
// export {Time}
let Tick = 0
export {Tick}
let Ticker = (time) => {
let i = 0;
while ( i < Tweens.length ) {
if ( Tweens[i].update(time) ) {
i++;
} else {
Tweens.splice(i, 1);
}
}
Tick = requestAnimationFrame(Ticker);
}
export {Ticker}
// stop requesting animation frame
export function stop() {
setTimeout(() => { // re-added for #81
if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick);
Tick = null;
for (let obj in onStart) {
if (typeof (onStart[obj]) === 'function') {
KUTE[obj] && (delete KUTE[obj])
} else {
for (let prop in onStart[obj]) {
KUTE[prop] && (delete KUTE[prop])
}
}
}
for (let i in Interpolate) {
KUTE[i] && (delete KUTE[i])
}
}
},64)
}
// KUTE.js render update functions
// ===============================
const Render = {Tick,Ticker,Tweens,Time}
for ( const blob in Render ) {
if (!KUTE[blob]) {
KUTE[blob] = blob === 'Time' ? Time.now : Render[blob];
}
}
export default Render
globalObject[`_KUTE`] = KUTE
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 = {};
const that = window.self || window || {};
Time.now = that.performance.now.bind(that.performance);
let Tick = 0;
export { Tick };
const Ticker = (time) => {
let i = 0;
while (i < Tweens.length) {
if (Tweens[i].update(time)) {
i += 1;
} else {
Tweens.splice(i, 1);
}
}
Tick = requestAnimationFrame(Ticker);
};
export { Ticker };
// stop requesting animation frame
export function stop() {
setTimeout(() => { // re-added for #81
if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick);
Tick = null;
Object.keys(onStart).forEach((obj) => {
if (typeof (onStart[obj]) === 'function') {
if (KUTE[obj]) delete KUTE[obj];
} else {
Object.keys(onStart[obj]).forEach((prop) => {
if (KUTE[prop]) delete KUTE[prop];
});
}
});
Object.keys(Interpolate).forEach((i) => {
if (KUTE[i]) delete KUTE[i];
});
}
}, 64);
}
// KUTE.js render update functions
// ===============================
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;

View file

@ -1,36 +1,45 @@
import connect from '../objects/connect.js'
// Select Robert Penner's Easing Functions
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) => {
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)
}
}
function processEasing(fn) {
if ( typeof fn === 'function') {
return fn;
} else if ( typeof Easing[fn] === 'function' ) {
return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
}
}
connect.processEasing = processEasing
export default Easing
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 < 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;
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') {
return fn;
} if (typeof Easing[fn] === 'function') {
return Easing[fn]; // regular Robert Penner Easing Functions
}
return Easing.linear;
}
connect.processEasing = processEasing;
export default Easing;

View file

@ -1,57 +1,56 @@
import connect from '../objects/connect.js'
import CubicBezier from 'cubic-bezier-easing'
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'),
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'),
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'),
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'),
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') {
return fn;
} else 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
}
}
connect.processEasing = processBezierEasing
export default 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'),
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'),
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'),
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'),
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') {
return fn;
} if (typeof (Easing[fn]) === 'function') {
return Easing[fn];
} 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;
export default Easing;

View file

@ -1,79 +1,132 @@
import connect from '../objects/connect.js'
// Robert Penner's Easing Functions
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) => {
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)
},
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 ) )
},
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
},
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
},
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; }
},
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') {
return fn;
} else if ( typeof Easing[fn] === 'function' ) {
return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
}
}
// Tween constructor needs to know who will process easing functions
connect.processEasing = processEasing
export default Easing
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 < 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;
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: (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;
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: (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) => 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;
},
};
function processEasing(fn) {
if (typeof fn === 'function') {
return fn;
} if (typeof Easing[fn] === 'function') {
return Easing[fn]; // regular Robert Penner Easing Functions
}
return Easing.linear;
}
// Tween constructor needs to know who will process easing functions
connect.processEasing = processEasing;
export default Easing;

View file

@ -1,50 +1,50 @@
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'
// TweenConstructor
import Tween from './tween/tweenBase.js'
// Interface only fromTo
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 {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 Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here
export default {
Animation,
Components: {
Transform,
BoxModel,
Opacity,
// Move
},
Tween,
fromTo,
Objects,
Easing,
Util,
Render,
Interpolate,
Internals,
Selector,
Version
}
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';
// TweenConstructor
import Tween from './tween/tweenBase.js';
// Interface only fromTo
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 {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 Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here
export default {
Animation,
Components: {
Transform,
BoxModel,
Opacity,
// Move
},
Tween,
fromTo,
Objects,
Easing,
Util,
Render,
Interpolate,
Internals,
Selector,
Version,
};

View file

@ -1,73 +1,91 @@
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'
// TweenConstructor
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 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'
for (let component in Components) {
let compOps = Components[component]
Components[component] = new Animation(compOps)
}
export default {
Animation,
Components,
// Tween Interface
Tween,
fromTo,
to,
// Tween Collection
TweenCollection,
ProgressBar,
allFromTo,
allTo,
// Tween Interface
Objects,
Util,
Easing,
CubicBezier,
Render,
Interpolate,
Process,
Internals,
Selector,
Version
}
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';
// 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/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';
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,
Components,
// Tween Interface
Tween,
fromTo,
to,
// Tween Collection
TweenCollection,
ProgressBar,
allFromTo,
allTo,
// Tween Interface
Objects,
Util,
Easing,
CubicBezier,
Render,
Interpolate,
Process,
Internals,
Selector,
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,75 +1,74 @@
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'
// 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 {default as Animation} from './animation/animationDevelopment.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'
// init components
for (let component in Components) {
let 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,
CubicBezier,
Render,
Interpolate,
Process,
Internals,
Selector,
Version
}
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';
// 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 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
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,
CubicBezier,
Render,
Interpolate,
Process,
Internals,
Selector,
Version,
};

View file

@ -1,7 +1,7 @@
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)
}
import selector from '../util/selector.js';
import TweenCollection from '../tween/tweenCollection.js';
export default function allFromTo(elements, 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'
// 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)
}
import selector from '../util/selector.js';
import TweenCollection from '../tween/tweenCollection.js';
// multiple elements tween objects
export default function allTo(elements, 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'
export default function fromTo(element, startObject, endObject, optionsObj) {
optionsObj = optionsObj || {}
return new connect.tween(selector(element), startObject, endObject, optionsObj)
}
import selector from '../util/selector.js';
import connect from '../objects/connect.js';
export default function fromTo(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'
export default function to(element, endObject, optionsObj) {
optionsObj = optionsObj || {}
optionsObj.resetStart = endObject
return new connect.tween(selector(element), endObject, endObject, optionsObj)
}
import selector from '../util/selector.js';
import connect from '../objects/connect.js';
export default function to(element, 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
}
return result
}
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;
}

View file

@ -1,13 +1,23 @@
import numbers from './numbers.js'
export default function(a, b, v) {
let _c = {},
c,
ep = ')',
cm =',',
rgb = 'rgb(',
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;
}
import numbers from './numbers.js';
export default function colors(a, b, v) {
const _c = {};
const ep = ')';
const cm = ',';
const rgb = 'rgb(';
const rgba = 'rgba(';
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,10 +1,10 @@
export default function(a, b, l, v) {
const points = [];
for(let i=0;i<l;i++) { // 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 );
}
}
return points;
}
export default function coords(a, b, l, v) {
const points = [];
for (let i = 0; i < l; i += 1) { // for each point
points[i] = [];
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'
return `skew(${skewArray.join(',')})`;
}
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'
return `translate(${translateArray.join(',')})`;
}
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;
}
return `translate3d(${translateArray.join(',')})`;
}
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

@ -1,5 +1,5 @@
// checks for differences between the processed start and end values,
// 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 {}
// checks for differences between the processed start and end values,
// 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 {};

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