* 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 # Wiki
For a complete developer guide, usage and stuff like npm, visit [the wiki](https://github.com/thednp/kute.js/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 # 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>. 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; 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-clike:after {content: 'node';}
pre.language-markup:after {content: 'HTML';} pre.language-markup:after {content: 'HTML';}
pre code {background: none;padding: 0; font-weight: normal; font-size: 100%;} 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], trx = translateExamples.getElementsByTagName('div')[1],
trry = translateExamples.getElementsByTagName('div')[2], trry = translateExamples.getElementsByTagName('div')[2],
trz = translateExamples.getElementsByTagName('div')[3], trz = translateExamples.getElementsByTagName('div')[3],
tr2dTween = KUTE.to(tr2d, {translate:[170,0]}, {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}) 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}), 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}); trzTween = KUTE.to(trz, {perspective:200, translate3d:[0,0,-100]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500});
translateBtn.addEventListener('click', function(){ translateBtn.addEventListener('click', function(){
!tr2dTween.playing && tr2dTween.start(); !tr2dTween.playing && tr2dTween.start();
!trxTween.playing && trxTween.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}), 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}), 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}); rzTween = KUTE.to(rz, {rotateZ:360}, {easing:'easingBackOut', yoyo:true, repeat: 1, duration:1500});
rotBtn.addEventListener('click', function(){ rotBtn.addEventListener('click', function(){
!r2dTween.playing && r2dTween.start(); !r2dTween.playing && r2dTween.start();
!rxTween.playing && rxTween.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)">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)">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)">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"> <div class="example-buttons">
<a class="btn btn-blue" href="javascript:void(0)">Start</a> <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 * Copyright 2015-2021 © thednp
* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) * 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()); (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory());
}(this, (function () { 'use strict'; }(this, (function () { 'use strict';
var version = "2.1.0"; var version = "2.1.1-alpha1";
var KUTE = {}; var KUTE = {};
var Tweens = []; var Tweens = [];
var globalObject = typeof (global) !== 'undefined' ? global var globalObject;
: typeof(self) !== 'undefined' ? self
: typeof(window) !== 'undefined' ? window : {};
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 = {}; var Interpolate = {};
// schedule property specific function on animation start
// link property update function to KUTE.js execution context
var onStart = {}; var onStart = {};
var Time = {}; 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 Tick = 0;
var Ticker = function (time) { var Ticker = function (time) {
var i = 0; var i = 0;
while ( i < Tweens.length ) { while (i < Tweens.length) {
if ( Tweens[i].update(time) ) { if (Tweens[i].update(time)) {
i++; i += 1;
} else { } else {
Tweens.splice(i, 1); Tweens.splice(i, 1);
} }
} }
Tick = requestAnimationFrame(Ticker); Tick = requestAnimationFrame(Ticker);
}; };
// stop requesting animation frame
function stop() { function stop() {
setTimeout(function () { setTimeout(function () { // re-added for #81
if (!Tweens.length && Tick) { if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick); cancelAnimationFrame(Tick);
Tick = null; Tick = null;
for (var obj in onStart) { Object.keys(onStart).forEach(function (obj) {
if (typeof (onStart[obj]) === 'function') { if (typeof (onStart[obj]) === 'function') {
KUTE[obj] && (delete KUTE[obj]); if (KUTE[obj]) { delete KUTE[obj]; }
} else { } else {
for (var prop in onStart[obj]) { Object.keys(onStart[obj]).forEach(function (prop) {
KUTE[prop] && (delete KUTE[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]) { if (!KUTE[blob]) {
KUTE[blob] = blob === 'Time' ? Time.now : Render[blob]; KUTE[blob] = blob === 'Time' ? Time.now : Render[blob];
} }
} });
globalObject["_KUTE"] = KUTE; globalObject$1._KUTE = KUTE;
var defaultOptions = { var defaultOptions = {
duration: 700, duration: 700,
delay: 0, delay: 0,
easing: 'linear' easing: 'linear',
}; };
// link properties to interpolate functions
var linkProperty = {}; var linkProperty = {};
// schedule property specific function on animation complete
var onComplete = {}; var onComplete = {};
var Objects = { var Objects = {
defaultOptions: defaultOptions, defaultOptions: defaultOptions,
linkProperty: linkProperty, linkProperty: linkProperty,
onStart: onStart, onStart: onStart,
onComplete: onComplete onComplete: onComplete,
}; };
// util - a general object for utils like rgbToHex, processEasing
var Util = {}; var Util = {};
var connect = {}; var connect = {};
// Select Robert Penner's Easing Functions
// updated for ESLint
var Easing = { var Easing = {
linear : function (t) { return t; }, linear: function (t) { return t; },
easingQuadraticIn : function (t) { return t*t; }, easingQuadraticIn: function (t) { return t * t; },
easingQuadraticOut : function (t) { return t*(2-t); }, easingQuadraticOut: function (t) { return t * (2 - t); },
easingQuadraticInOut : function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t; }, easingQuadraticInOut: function (t) { return (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t); },
easingCubicIn : function (t) { return t*t*t; }, easingCubicIn: function (t) { return t * t * t; },
easingCubicOut : function (t) { return (--t)*t*t+1; }, easingCubicOut: function (t0) { var t = t0 - 1; return t * t * t + 1; },
easingCubicInOut : function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+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); }, easingCircularIn: function (t) { return -(Math.sqrt(1 - (t * t)) - 1); },
easingCircularOut : function (t) { return Math.sqrt(1 - (t = t - 1) * t); }, easingCircularOut: function (t0) { },
easingCircularInOut : function (t) { return ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); }, easingCircularInOut: function (t0) {
easingBackIn : function (t) { var s = 1.70158; return t * t * ((s + 1) * t - s) }, var t = t0 * 2;
easingBackOut : function (t) { var s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 }, if (t < 1) { return -0.5 * (Math.sqrt(1 - t * t) - 1); }
easingBackInOut : function (t) { 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; var s = 1.70158 * 1.525;
if ((t *= 2) < 1) { return 0.5 * (t * t * ((s + 1) * t - s)) } var t = t0 * 2;
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 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) { function processEasing(fn) {
if ( typeof fn === 'function') { if (typeof fn === 'function') {
return fn; return fn;
} else if ( typeof Easing[fn] === 'function' ) { } if (typeof Easing[fn] === 'function') {
return Easing[fn]; return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
} }
return Easing.linear;
} }
connect.processEasing = processEasing; connect.processEasing = processEasing;
function add (tw) { return Tweens.push(tw); } function add (tw) { return Tweens.push(tw); }
function remove (tw) { function remove (tw) {
var i = Tweens.indexOf(tw); var i = Tweens.indexOf(tw);
i !== -1 && Tweens.splice(i, 1); if (i !== -1) { Tweens.splice(i, 1); }
} }
function getAll () { return Tweens; } function getAll () { return Tweens; }
@ -131,33 +166,33 @@
function linkInterpolation() { function linkInterpolation() {
var this$1 = this; var this$1 = this;
var loop = function ( component ) { // DON'T change
Object.keys(linkProperty).forEach(function (component) {
var componentLink = linkProperty[component]; var componentLink = linkProperty[component];
var componentProps = supportedProperties[component]; var componentProps = supportedProperties[component];
for ( var fnObj in componentLink ) {
if ( typeof(componentLink[fnObj]) === 'function' Object.keys(componentLink).forEach(function (fnObj) {
&& Object.keys(this$1.valuesEnd).some(function (i) { return componentProps && componentProps.includes(i) if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius
|| i=== 'attr' && Object.keys(this$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); }); } ) ) && 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]); if (!KUTE[fnObj]) { KUTE[fnObj] = componentLink[fnObj]; }
} else { } else {
for ( var prop in this$1.valuesEnd ) { Object.keys(this$1.valuesEnd).forEach(function (prop) {
for ( var i in this$1.valuesEnd[prop] ) { Object.keys(this$1.valuesEnd[prop]).forEach(function (i) {
if ( typeof(componentLink[i]) === 'function' ) { if (typeof (componentLink[i]) === 'function') { // transformCSS3
!KUTE[i] && (KUTE[i] = componentLink[i]); if (!KUTE[i]) { KUTE[i] = componentLink[i]; }
} else { } else {
for (var j in componentLink[fnObj]){ Object.keys(componentLink[fnObj]).forEach(function (j) {
if (componentLink[i] && typeof(componentLink[i][j]) === 'function' ) { if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix
!KUTE[j] && (KUTE[j] = componentLink[i][j]); if (!KUTE[j]) { KUTE[j] = componentLink[i][j]; }
} }
} });
} }
} });
} });
} }
} });
}; });
for (var component in linkProperty)loop( component );
} }
var Internals = { var Internals = {
@ -166,136 +201,203 @@
getAll: getAll, getAll: getAll,
removeAll: removeAll, removeAll: removeAll,
stop: stop, stop: stop,
linkInterpolation: linkInterpolation linkInterpolation: linkInterpolation,
}; };
// a public selector utility
function selector(el, multi) { function selector(el, multi) {
try{ try {
var requestedElem; var requestedElem;
if (multi){ var itemsArray;
requestedElem = el instanceof HTMLCollection if (multi) {
|| el instanceof NodeList itemsArray = el instanceof Array && el.every(function (x) { return x instanceof Element; });
|| el instanceof Array && el.every(function (x) { return x instanceof Element; }) requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray
? el : document.querySelectorAll(el); ? el : document.querySelectorAll(el);
} else { } else {
requestedElem = el instanceof Element requestedElem = el instanceof Element || el === window // scroll
|| el === window ? el : document.querySelector(el);
? el : document.querySelector(el);
} }
return requestedElem; return requestedElem;
} catch(e){ } catch (e) {
console.error(("KUTE.js - Element(s) not found: " + el + ".")); throw TypeError(("KUTE.js - Element(s) not found: " + el + "."));
} }
} }
var AnimationBase = function AnimationBase(Component){ // Animation class
return this.setComponent(Component) 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; var ComponentName = Component.component;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
var Functions = { onStart: onStart, onComplete: onComplete }; var Functions = { onStart: onStart, onComplete: onComplete };
var Category = Component.category; var Category = Component.category;
var Property = Component.property; 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) { if (Component.defaultOptions) {
for (var op in Component.defaultOptions) { Object.keys(Component.defaultOptions).forEach(function (op) {
defaultOptions[op] = Component.defaultOptions[op]; defaultOptions[op] = Component.defaultOptions[op];
} });
} }
// set functions
if (Component.functions) { if (Component.functions) {
for (var fn in Functions) { Object.keys(Functions).forEach(function (fn) {
if (fn in Component.functions) { if (fn in Component.functions) {
if ( typeof (Component.functions[fn]) === 'function') { if (typeof (Component.functions[fn]) === 'function') {
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}); // if (!Functions[fn][ Category||Property ]) {
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn]); // Functions[fn][ Category||Property ] = Component.functions[fn];
} else { // }
for ( var ofn in Component.functions[fn] ){ if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; }
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}); if (!Functions[fn][ComponentName][Category || Property]) {
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]); 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) { if (Component.Interpolate) {
for (var fni in Component.Interpolate) { Object.keys(Component.Interpolate).forEach(function (fni) {
var compIntObj = Component.Interpolate[fni]; var compIntObj = Component.Interpolate[fni];
if ( typeof(compIntObj) === 'function' && !Interpolate[fni] ) { if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj; Interpolate[fni] = compIntObj;
} else { } else {
for ( var sfn in compIntObj ) { Object.keys(compIntObj).forEach(function (sfn) {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) { if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj[sfn]; Interpolate[fni] = compIntObj[sfn];
} }
} });
} }
} });
linkProperty[ComponentName] = Component.Interpolate; linkProperty[ComponentName] = Component.Interpolate;
} }
// set component util
if (Component.Util) { if (Component.Util) {
for (var fnu in Component.Util){ Object.keys(Component.Util).forEach(function (fnu) {
!Util[fnu] && (Util[fnu] = Component.Util[fnu]); if (!Util[fnu]) { Util[fnu] = Component.Util[fnu]; }
} });
} }
return {name:ComponentName}
return { name: ComponentName };
}; };
function queueStart(){ function queueStart() {
for (var obj in onStart) { var this$1 = this;
// fire onStart actions
Object.keys(onStart).forEach(function (obj) {
if (typeof (onStart[obj]) === 'function') { if (typeof (onStart[obj]) === 'function') {
onStart[obj].call(this,obj); onStart[obj].call(this$1, obj); // easing functions
} else { } else {
for (var prop in onStart[obj]) { Object.keys(onStart[obj]).forEach(function (prop) {
onStart[obj][prop].call(this,prop); onStart[obj][prop].call(this$1, prop);
} });
} }
} });
// add interpolations
linkInterpolation.call(this); 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.element = targetElement;
this.playing = false; this.playing = false;
this._startTime = null; this._startTime = null;
this._startFired = false; this._startFired = false;
this.valuesEnd = endObject;
this.valuesStart = startObject; this.valuesEnd = endObject; // valuesEnd
options = options || {}; 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; 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._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing);
this._duration = options.duration || defaultOptions.duration; this._duration = options.duration || defaultOptions.duration; // duration option | default
this._delay = options.delay || defaultOptions.delay; this._delay = options.delay || defaultOptions.delay; // delay option | default
for (var op in options) {
// set other options
Object.keys(options).forEach(function (op) {
var internalOption = "_" + 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; var easingFnName = this._easing.name;
if (!onStart[easingFnName]) { if (!onStart[easingFnName]) {
onStart[easingFnName] = function(prop){ onStart[easingFnName] = function easingFn(prop) {
!KUTE[prop] && prop === this._easing.name && (KUTE[prop] = this._easing); if (!KUTE[prop] && prop === this._easing.name) { KUTE[prop] = this._easing; }
}; };
} }
return this; 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) { TweenBase.prototype.start = function start (time) {
// now it's a good time to start
add(this); add(this);
this.playing = true; this.playing = true;
this._startTime = typeof time !== 'undefined' ? time : KUTE.Time(); this._startTime = typeof time !== 'undefined' ? time : KUTE.Time();
this._startTime += this._delay; this._startTime += this._delay;
if (!this._startFired) { if (!this._startFired) {
if (this._onStart) { if (this._onStart) {
this._onStart.call(this); this._onStart.call(this);
} }
queueStart.call(this); queueStart.call(this);
this._startFired = true; this._startFired = true;
} }
!Tick && Ticker();
if (!Tick) { Ticker(); }
return this; return this;
}; };
TweenBase.prototype.stop = function stop () { TweenBase.prototype.stop = function stop () {
if (this.playing) { if (this.playing) {
remove(this); remove(this);
this.playing = false; this.playing = false;
if (this._onStop) { if (this._onStop) {
this._onStop.call(this); this._onStop.call(this);
} }
@ -303,157 +405,254 @@
} }
return this; return this;
}; };
TweenBase.prototype.close = function close () { TweenBase.prototype.close = function close () {
for (var component in onComplete){ var this$1 = this;
for (var toClose in onComplete[component]){
onComplete[component][toClose].call(this,toClose); // 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; this._startFired = false;
stop.call(this); stop.call(this);
}; };
TweenBase.prototype.chain = function chain (args) { TweenBase.prototype.chain = function chain (args) {
this._chain = []; this._chain = [];
this._chain = args.length ? args : this._chain.concat(args); this._chain = args.length ? args : this._chain.concat(args);
return this; return this;
}; };
TweenBase.prototype.stopChainedTweens = function stopChainedTweens () { 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) { TweenBase.prototype.update = function update (time) {
time = time !== undefined ? time : KUTE.Time(); var this$1 = this;
var elapsed, progress;
if ( time < this._startTime && this.playing ) { return true; } var T = time !== undefined ? time : KUTE.Time();
elapsed = (time - this._startTime) / this._duration;
var elapsed;
if (T < this._startTime && this.playing) { return true; }
elapsed = (T - this._startTime) / this._duration;
elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed;
progress = this._easing(elapsed);
for (var tweenProp in this.valuesEnd){ // calculate progress
KUTE[tweenProp](this.element,this.valuesStart[tweenProp],this.valuesEnd[tweenProp],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) { if (this._onUpdate) {
this._onUpdate.call(this); this._onUpdate.call(this);
} }
if (elapsed === 1) { if (elapsed === 1) {
// fire the complete callback
if (this._onComplete) { if (this._onComplete) {
this._onComplete.call(this); this._onComplete.call(this);
} }
// now we're sure no animation is running
this.playing = false; this.playing = false;
// stop ticking when finished
this.close(); 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 false;
} }
return true; return true;
}; };
// Update Tween Interface
connect.tween = TweenBase; connect.tween = TweenBase;
function fromTo(element, startObject, endObject, optionsObj) { function fromTo(element, startObject, endObject, optionsObj) {
optionsObj = optionsObj || {}; var options = optionsObj || {};
return new connect.tween(selector(element), startObject, endObject, optionsObj) var TweenConstructor = connect.tween;
return new TweenConstructor(selector(element), startObject, endObject, options);
} }
function numbers(a, b, v) { function numbers(a, b, v) { // number1, number2, progress
a = +a; b -= a; return a + b * v; 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 = []; var result = [];
for ( var i=0, l=b.length; i<l; i++ ) { for (var i = 0, l = b.length; i < l; i += 1) {
result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0 ) / 1000; 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 matrixComponent = 'transformMatrixBase';
var CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix // Component special
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix // this component is restricted to modern browsers only
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix var CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
: null;
// Component Functions
var onStartTransform = { var onStartTransform = {
transform : function(tweenProp) { transform: function transform(tweenProp) {
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) { if (CSS3Matrix && this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = function (elem, a, b, v) { KUTE[tweenProp] = function (elem, a, b, v) {
var matrix = new CSS3Matrix(), transformObject = {}; var matrix = new CSS3Matrix();
for ( var p in b ) { var tObject = {};
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v);
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; // set scale
matrix = transformObject.rotate3d ? (matrix.rotate(transformObject.rotate3d[0],transformObject.rotate3d[1],transformObject.rotate3d[2])) : matrix; matrix = tObject.scale3d
if (transformObject.skew) { ? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2])
matrix = transformObject.skew[0] ? matrix.skewX(transformObject.skew[0]) : matrix; : matrix;
matrix = transformObject.skew[1] ? matrix.skewY(transformObject.skew[1]) : matrix;
} // set element style
matrix = transformObject.scale3d ? (matrix.scale(transformObject.scale3d[0],transformObject.scale3d[1],transformObject.scale3d[2])): matrix;
elem.style[tweenProp] = matrix.toString(); elem.style[tweenProp] = matrix.toString();
}; };
} }
}, },
CSS3Matrix: function(prop) { CSS3Matrix: function CSS3Matrix$1(prop) {
if (this.valuesEnd.transform){ if (CSS3Matrix && this.valuesEnd.transform) {
!KUTE[prop] && (KUTE[prop] = CSS3Matrix); if (!KUTE[prop]) { KUTE[prop] = CSS3Matrix; }
} }
}, },
}; };
// Component Base Object
var baseMatrixTransform = { var baseMatrixTransform = {
component: matrixComponent, component: matrixComponent,
property: 'transform', property: 'transform',
functions: {onStart: onStartTransform}, functions: { onStart: onStartTransform },
Interpolate: { Interpolate: {
perspective: numbers, perspective: numbers,
translate3d: arrays, translate3d: arrays,
rotate3d: arrays, rotate3d: arrays,
skew: arrays, skew: arrays,
scale3d: arrays scale3d: arrays,
} },
}; };
function boxModelOnStart(tweenProp){ // Component Functions
function boxModelOnStart(tweenProp) {
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) { if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = function (elem, a, b, v) { 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 = {}; var baseBoxOnStart = {};
baseBoxProps.map(function (x){ return baseBoxOnStart[x] = boxModelOnStart; }); baseBoxProps.forEach(function (x) { baseBoxOnStart[x] = boxModelOnStart; });
// Component Base
var baseBoxModel = { var baseBoxModel = {
component: 'baseBoxModel', component: 'baseBoxModel',
category: 'boxModel', category: 'boxModel',
properties: baseBoxProps, properties: baseBoxProps,
Interpolate: {numbers: numbers}, Interpolate: { numbers: numbers },
functions: {onStart: baseBoxOnStart} functions: { onStart: baseBoxOnStart },
}; };
function onStartOpacity(tweenProp){ /* opacityProperty = {
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { 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) { 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 = { var baseOpacity = {
component: 'baseOpacity', component: 'baseOpacity',
property: 'opacity', property: 'opacity',
Interpolate: {numbers: numbers}, // defaultValue: 1,
functions: {onStart: onStartOpacity} Interpolate: { numbers: numbers },
functions: { onStart: onStartOpacity },
}; };
// import {baseCrossBrowserMove} from './components/crossBrowserMove.js'
// const Transform = new Animation(baseTransform)
var Transform = new AnimationBase(baseMatrixTransform); var Transform = new AnimationBase(baseMatrixTransform);
var BoxModel = new AnimationBase(baseBoxModel); var BoxModel = new AnimationBase(baseBoxModel);
var Opacity = new AnimationBase(baseOpacity); var Opacity = new AnimationBase(baseOpacity);
// const Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here
var indexBase = { var indexBase = {
Animation: AnimationBase, Animation: AnimationBase,
Components: { Components: {
Transform: Transform, Transform: Transform,
BoxModel: BoxModel, BoxModel: BoxModel,
Opacity: Opacity, Opacity: Opacity,
// Move
}, },
Tween: TweenBase, Tween: TweenBase,
fromTo: fromTo, fromTo: fromTo,
Objects: Objects, Objects: Objects,
Easing: Easing, Easing: Easing,
Util: Util, Util: Util,
@ -461,7 +660,7 @@
Interpolate: Interpolate, Interpolate: Interpolate,
Internals: Internals, Internals: Internals,
Selector: selector, Selector: selector,
Version: version Version: version,
}; };
return indexBase; 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"; "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)}} 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"; "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 --> <!-- Placed at the end of the document so the pages load faster -->
<script src="./src/polyfill.min.js"></script> <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/prism.js"></script>
<script src="./assets/js/scripts.js"></script> <script src="./assets/js/scripts.js"></script>
<script src="./assets/js/svgMorph.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) * KUTE.js Polyfill v2.1.1-alpha1 (http://thednp.github.io/kute.js)
* Copyright 2015-2020 © thednp * Copyright 2015-2021 © thednp
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/ */
"use strict"; "use strict";
if (!Array.from) { if (!Array.from) {
Array.from = (function () { Array.from = (function () {
var toStr = Object.prototype.toString; var toStr = Object.prototype.toString;
var isCallable = function (fn) { var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
}; };
var toInteger = function (value) { var toInteger = function (value) {
var number = Number(value); var number = Number(value);
if (isNaN(number)) { return 0; } if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; } if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
}; };
var maxSafeInteger = Math.pow(2, 53) - 1; var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) { var toLength = function (value) {
var len = toInteger(value); var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger); return Math.min(Math.max(len, 0), maxSafeInteger);
}; };
return function from(arrayLike) {
var C = this, items = Object(arrayLike); return function from(arrayLike/*, mapFn, thisArg */) {
if (arrayLike == null) { var C = this, items = Object(arrayLike);
throw new TypeError('Array.from requires an array-like object - not null or undefined'); 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') { var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T;
if (!isCallable(mapFn)) { if (typeof mapFn !== 'undefined') {
throw new TypeError('Array.from: when provided, the second argument must be a function'); if (!isCallable(mapFn)) {
} throw new TypeError('Array.from: when provided, the second argument must be a function');
if (arguments.length > 2) { }
T = arguments[2];
} 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 len = toLength(items.length);
var kValue; var A = isCallable(C) ? Object(new C(len)) : new Array(len);
while (k < len) {
kValue = items[k]; var k = 0;
if (mapFn) { var kValue;
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); while (k < len) {
} else { kValue = items[k];
A[k] = kValue; if (mapFn) {
} A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
k += 1; } else {
} A[k] = kValue;
A.length = len; }
return A; k += 1;
} }
}()); A.length = len;
return A;
}
}());
} }
if (!Array.prototype.includes) { // https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
Array.prototype.includes = function(searchElement ) {
var O = Object(this); if (!Array.prototype.flat) {
var len = parseInt(O.length) || 0; Object.defineProperty(Array.prototype, 'flat', {
if (len === 0) { configurable: true,
return false; value: function flat () {
} var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);
var n = parseInt(arguments[1]) || 0;
var k; return depth ? Array.prototype.reduce.call(this, function (acc, cur) {
if (n >= 0) { if (Array.isArray(cur)) {
k = n; acc.push.apply(acc, flat.call(cur, depth - 1));
} else { } else {
k = len + n; acc.push(cur);
if (k < 0) {k = 0;} }
}
var currentElement; return acc;
while (k < len) { }, []) : Array.prototype.slice.call(this);
currentElement = O[k]; },
if (searchElement === currentElement || writable: true
(searchElement !== searchElement && currentElement !== currentElement)) { });
return true;
}
k++;
}
return false;
};
} }
if (!String.prototype.includes) { if (!Array.prototype.includes) {
String.prototype.includes = function(search, start) { Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
if (search instanceof RegExp) { var O = Object(this);
throw TypeError('first argument must not be a RegExp'); var len = parseInt(O.length) || 0;
} if (len === 0) {
if (start === undefined) { start = 0; } return false;
return this.indexOf(search, start) !== -1; }
}; 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"; "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", "name": "kute.js",
"version": "2.1.0", "version": "2.1.1-alpha1",
"description": "JavaScript animation engine of the future is called KUTE.js.", "description": "JavaScript animation engine",
"main": "dist/kute.min.js", "main": "dist/kute.min.js",
"module": "dist/kute.esm.js", "module": "dist/kute.esm.js",
"jsnext": "src/index.js", "jsnext": "src/index.js",
@ -13,8 +13,11 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"help": "rollup --help", "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", "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", "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": "rollup --environment DIST:standard,MIN:false,FORMAT:umd -c",
"build-standard-min": "rollup --environment DIST:standard,MIN:true,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", "homepage": "http://thednp.github.io/kute.js",
"dependencies": { "dependencies": {
"cubic-bezier-easing": "^1.0.2", "cubic-bezier-easing": "^1.0.3-alpha1",
"minifill": "^0.0.14", "minifill": "^0.0.16",
"shorter-js": "^0.1.7", "shorter-js": "^0.2.0-alpha1",
"svg-path-commander": "0.1.0" "svg-path-commander": "0.1.3-alpha4"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-buble": "^0.21.3", "@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.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", "npm-run-all": "^4.1.5",
"rollup": "^2.36.1", "rollup": "^2.36.1",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-terser": "^7.0.2" "rollup-plugin-terser": "^7.0.2"
} }
} }

View file

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

View file

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

View file

@ -1,116 +1,135 @@
import supportedProperties from '../objects/supportedProperties.js' import supportedProperties from '../objects/supportedProperties.js';
import defaultValues from '../objects/defaultValues.js' import defaultValues from '../objects/defaultValues.js';
import defaultOptions from '../objects/defaultOptions.js' import defaultOptions from '../objects/defaultOptions.js';
import prepareProperty from '../objects/prepareProperty.js' import prepareProperty from '../objects/prepareProperty.js';
import prepareStart from '../objects/prepareStart.js' import prepareStart from '../objects/prepareStart.js';
import onStart from '../objects/onStart.js' import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js' import onComplete from '../objects/onComplete.js';
import crossCheck from '../objects/crossCheck.js' import crossCheck from '../objects/crossCheck.js';
import linkProperty from '../objects/linkProperty.js' import linkProperty from '../objects/linkProperty.js';
import Util from '../objects/util.js' import Util from '../objects/util.js';
import Interpolate from '../objects/interpolate.js' import Interpolate from '../objects/interpolate.js';
// Animation class // Animation class
// * builds KUTE components // * builds KUTE components
// * populate KUTE objects // * populate KUTE objects
// * AnimatonBase creates a KUTE.js build for pre-made Tween objects // * AnimatonBase creates a KUTE.js build for pre-made Tween objects
// * AnimatonDevelopment can help you debug your new components // * AnimatonDevelopment can help you debug your new components
export default class Animation { export default class Animation {
constructor(Component){ constructor(Component) {
try { try {
if ( Component.component in supportedProperties ) { if (Component.component in supportedProperties) {
console.error(`KUTE.js - ${Component.component} already registered`); throw Error(`KUTE.js - ${Component.component} already registered`);
} else if ( Component.property in defaultValues ) { } else if (Component.property in defaultValues) {
console.error(`KUTE.js - ${Component.property} already registered`); throw Error(`KUTE.js - ${Component.property} already registered`);
} else { } else {
this.setComponent(Component) this.setComponent(Component);
} }
} catch(e){ } catch (e) {
console.error(e) throw Error(e);
} }
} }
setComponent(Component){
const propertyInfo = this setComponent(Component) {
const ComponentName = Component.component const propertyInfo = this;
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } const ComponentName = Component.component;
const Functions = { prepareProperty, prepareStart, onStart, onComplete, crossCheck } // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Category = Component.category const Functions = {
const Property = Component.property prepareProperty, prepareStart, onStart, onComplete, crossCheck,
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length };
const Category = Component.category;
// {property,defaultvalue,defaultOptions,Interpolate,functions} // single property const Property = Component.property;
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions} // category colors, boxModel, borderRadius const Length = (Component.properties && Component.properties.length)
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg transform, filter || (Component.subProperties && Component.subProperties.length);
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg attr
// single property
// set supported category/property // {property,defaultvalue,defaultOptions,Interpolate,functions}
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property
// category colors, boxModel, borderRadius
// set defaultValues // {category,properties,defaultvalues,defaultOptions,Interpolate,functions}
if ('defaultValue' in Component){ // value 0 will invalidate
defaultValues[ Property ] = Component.defaultValue // property with multiple sub properties. Eg transform, filter
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// minimal info
propertyInfo.supports = `${Property} property` // property with multiple sub properties. Eg htmlAttributes
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
} else if (Component.defaultValues) {
for (const dv in Component.defaultValues) { // set supported category/property
defaultValues[dv] = Component.defaultValues[dv] supportedProperties[ComponentName] = Component.properties
} || Component.subProperties || Component.property;
// minimal info
propertyInfo.supports = `${Length||Property} ${Property||Category} properties` // set defaultValues
} if ('defaultValue' in Component) { // value 0 will invalidate
defaultValues[Property] = Component.defaultValue;
// set additional options
if (Component.defaultOptions) { // minimal info
for (const op in Component.defaultOptions) { propertyInfo.supports = `${Property} property`;
defaultOptions[op] = Component.defaultOptions[op] } else if (Component.defaultValues) {
} Object.keys(Component.defaultValues).forEach((dv) => {
} defaultValues[dv] = Component.defaultValues[dv];
});
// set functions
if (Component.functions) { // minimal info
for (const fn in Functions) { propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
if (fn in Component.functions) { }
if (typeof (Component.functions[fn]) === 'function' ) {
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn]) // set additional options
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}) if (Component.defaultOptions) {
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn]) Object.keys(Component.defaultOptions).forEach((op) => {
} else { defaultOptions[op] = Component.defaultOptions[op];
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 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];
// set component interpolate // }
if (Component.Interpolate) { if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
for (const fni in Component.Interpolate) { if (!Functions[fn][ComponentName][Category || Property]) {
const compIntObj = Component.Interpolate[fni] Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
if ( typeof(compIntObj) === 'function' && !Interpolate[fni] ) { }
Interpolate[fni] = compIntObj; } else {
} else { Object.keys(Component.functions[fn]).forEach((ofn) => {
for ( const sfn in compIntObj ) { // !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) { if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
Interpolate[fni] = compIntObj[sfn]; if (!Functions[fn][ComponentName][ofn]) {
} Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
} }
} });
} }
linkProperty[ComponentName] = Component.Interpolate }
} });
}
// set component util
if (Component.Util) { // set component interpolate
for (const fnu in Component.Util){ if (Component.Interpolate) {
!Util[fnu] && (Util[fnu] = Component.Util[fnu]) Object.keys(Component.Interpolate).forEach((fni) => {
} const compIntObj = Component.Interpolate[fni];
} if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
Interpolate[fni] = compIntObj;
return propertyInfo } 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 supportedProperties from '../objects/supportedProperties.js';
import defaultOptions from '../objects/defaultOptions.js' import defaultOptions from '../objects/defaultOptions.js';
import onStart from '../objects/onStart.js' import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js' import onComplete from '../objects/onComplete.js';
import linkProperty from '../objects/linkProperty.js' import linkProperty from '../objects/linkProperty.js';
import Util from '../objects/util.js' import Util from '../objects/util.js';
import Interpolate from '../objects/interpolate.js' import Interpolate from '../objects/interpolate.js';
// Animation class // Animation class
export default class AnimationBase { export default class AnimationBase {
constructor(Component){ constructor(Component) {
return this.setComponent(Component) return this.setComponent(Component);
} }
setComponent(Component){
const ComponentName = Component.component setComponent(Component) {
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty } const ComponentName = Component.component;
const Functions = { onStart, onComplete } // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty }
const Category = Component.category const Functions = { onStart, onComplete };
const Property = Component.property const Category = Component.category;
const Property = Component.property;
// set supported category/property // ESLint
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property this._ = 0;
// set additional options // set supported category/property
if (Component.defaultOptions) { supportedProperties[ComponentName] = Component.properties
for (const op in Component.defaultOptions) { || Component.subProperties || Component.property;
defaultOptions[op] = Component.defaultOptions[op]
} // set additional options
} if (Component.defaultOptions) {
Object.keys(Component.defaultOptions).forEach((op) => {
// set functions defaultOptions[op] = Component.defaultOptions[op];
if (Component.functions) { });
for (const fn in Functions) { }
if (fn in Component.functions) {
if ( typeof (Component.functions[fn]) === 'function' ) { // set functions
// !Functions[fn][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn]) if (Component.functions) {
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}) Object.keys(Functions).forEach((fn) => {
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn]) if (fn in Component.functions) {
} else { if (typeof (Component.functions[fn]) === 'function') {
for ( const ofn in Component.functions[fn] ){ // if (!Functions[fn][ Category||Property ]) {
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn]) // Functions[fn][ Category||Property ] = Component.functions[fn];
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}) // }
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]) 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];
// set interpolate if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (Component.Interpolate) { if (!Functions[fn][ComponentName][ofn]) {
for (const fni in Component.Interpolate) { Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
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];
} // set interpolate
} if (Component.Interpolate) {
} Object.keys(Component.Interpolate).forEach((fni) => {
} const compIntObj = Component.Interpolate[fni];
linkProperty[ComponentName] = Component.Interpolate if (typeof (compIntObj) === 'function' && !Interpolate[fni]) {
} Interpolate[fni] = compIntObj;
} else {
// set component util Object.keys(compIntObj).forEach((sfn) => {
if (Component.Util) { if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) {
for (const fnu in Component.Util){ Interpolate[fni] = compIntObj[sfn];
!Util[fnu] && (Util[fnu] = Component.Util[fnu]) }
} });
} }
});
return {name:ComponentName}
} 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 prepareProperty from '../objects/prepareProperty.js';
import prepareStart from '../objects/prepareStart.js' import prepareStart from '../objects/prepareStart.js';
import onStart from '../objects/onStart.js' import onStart from '../objects/onStart.js';
import onComplete from '../objects/onComplete.js' import onComplete from '../objects/onComplete.js';
import crossCheck from '../objects/crossCheck.js' import crossCheck from '../objects/crossCheck.js';
import Interpolate from '../objects/interpolate.js' import Interpolate from '../objects/interpolate.js';
import Animation from './animation.js' import Animation from './animation.js';
// AnimationDevelopment class // AnimationDevelopment class
export default class AnimationDevelopment extends Animation { export default class AnimationDevelopment extends Animation {
constructor(...args){ constructor(...args) {
super(...args) super(...args);
}
setComponent(Component){ this.setComponent(...args);
super.setComponent(Component) }
const propertyInfo = this setComponent(Component) {
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } super.setComponent(Component);
const Functions = { prepareProperty,prepareStart,onStart,onComplete,crossCheck }
const Category = Component.category const propertyInfo = this;
const Property = Component.property // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
// set defaultValues };
if ('defaultValue' in Component){ // value 0 will invalidate const Category = Component.category;
const Property = Component.property;
propertyInfo.supports = `${Property} property` const Length = (Component.properties && Component.properties.length)
propertyInfo.defaultValue = `${(Component.defaultValue+'').length?"YES":"not set or incorrect"}` || (Component.subProperties && Component.subProperties.length);
} else if (Component.defaultValues) { // set defaultValues
propertyInfo.supports = `${Length||Property} ${Property||Category} properties` if ('defaultValue' in Component) { // value 0 will invalidate
propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? `YES` : `Not set or incomplete` propertyInfo.supports = `${Property} property`;
} propertyInfo.defaultValue = `${(`${Component.defaultValue}`).length ? 'YES' : 'not set or incorrect'}`;
} else if (Component.defaultValues) {
// set additional options propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
if (Component.defaultOptions) { propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? 'YES' : 'Not set or incomplete';
propertyInfo.extends = [] }
for (const op in Component.defaultOptions) { // set additional options
propertyInfo.extends.push(op) if (Component.defaultOptions) {
} propertyInfo.extends = [];
propertyInfo.extends.length ? propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)` : delete propertyInfo.extends Object.keys(Component.defaultOptions).forEach((op) => {
} propertyInfo.extends.push(op);
});
// set functions
if (Component.functions) { if (propertyInfo.extends.length) {
propertyInfo.interface = [] propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)`;
propertyInfo.render = [] } else {
propertyInfo.warning = [] delete propertyInfo.extends;
for (const fnf in Functions) { }
if (fnf in Component.functions) { }
fnf === 'prepareProperty' ? propertyInfo.interface.push(`fromTo()`) : 0
fnf === 'prepareStart' ? propertyInfo.interface.push(`to()`) : 0 // set functions
fnf === 'onStart' ? propertyInfo.render = `can render update` : 0 if (Component.functions) {
} else { propertyInfo.interface = [];
fnf === 'prepareProperty' ? propertyInfo.warning.push(`fromTo()`) : 0 propertyInfo.render = [];
fnf === 'prepareStart' ? propertyInfo.warning.push(`to()`) : 0 propertyInfo.warning = [];
fnf === 'onStart' ? propertyInfo.render = `no function to render update` : 0
} Object.keys(Functions).forEach((fnf) => {
} if (fnf in Component.functions) {
propertyInfo.interface.length ? propertyInfo.interface = `${Category||Property} can use [${propertyInfo.interface.join(', ')}] method(s)` : delete propertyInfo.uses if (fnf === 'prepareProperty') propertyInfo.interface.push('fromTo()');
propertyInfo.warning.length ? propertyInfo.warning = `${Category||Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed` : delete propertyInfo.warning if (fnf === 'prepareStart') propertyInfo.interface.push('to()');
} if (fnf === 'onStart') propertyInfo.render = 'can render update';
} else {
// register Interpolation functions if (fnf === 'prepareProperty') propertyInfo.warning.push('fromTo()');
if (Component.Interpolate) { if (fnf === 'prepareStart') propertyInfo.warning.push('to()');
propertyInfo.uses = [] if (fnf === 'onStart') propertyInfo.render = 'no function to render update';
propertyInfo.adds = [] }
});
for (let fni in Component.Interpolate) {
let compIntObj = Component.Interpolate[fni] if (propertyInfo.interface.length) {
// register new Interpolation functions propertyInfo.interface = `${Category || Property} can use [${propertyInfo.interface.join(', ')}] method(s)`;
if ( typeof(compIntObj) === 'function' ) { } else {
if ( !Interpolate[fni] ) { delete propertyInfo.uses;
propertyInfo.adds.push(`${fni}`) }
}
propertyInfo.uses.push(`${fni}`) if (propertyInfo.warning.length) {
} else { propertyInfo.warning = `${Category || Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed`;
for ( let sfn in compIntObj ) { } else {
if ( typeof(compIntObj[sfn]) === 'function' && !Interpolate[fni] ) { delete propertyInfo.warning;
propertyInfo.adds.push(`${sfn}`) }
} }
propertyInfo.uses.push(`${sfn}`)
} // register Interpolation functions
} if (Component.Interpolate) {
} propertyInfo.uses = [];
propertyInfo.adds = [];
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 Object.keys(Component.Interpolate).forEach((fni) => {
} else { const compIntObj = Component.Interpolate[fni];
propertyInfo.critical = `For ${Property||Category} no interpolation function[s] is set` // register new Interpolation functions
} if (typeof (compIntObj) === 'function') {
if (!Interpolate[fni]) {
// set component util propertyInfo.adds.push(`${fni}`);
if (Component.Util) { }
propertyInfo.hasUtil = Object.keys(Component.Util).join(',') propertyInfo.uses.push(`${fni}`);
} } else {
Object.keys(compIntObj).forEach((sfn) => {
return propertyInfo 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 defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import getStyleForProperty from '../process/getStyleForProperty.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import trueDimension from '../util/trueDimension.js';
import trueDimension from '../util/trueDimension.js' import { onStartBgPos } from './backgroundPositionBase.js';
import {onStartBgPos} from './backgroundPositionBase.js'
/* bgPosProp = {
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart } property: 'backgroundPosition',
defaultValue: [0,0],
// Component Functions interpolators: {numbers},
function getBgPos(prop){ functions = { prepareStart, prepareProperty, onStart }
return getStyleForProperty(this.element,prop) || defaultValues[prop]; } */
}
function prepareBgPos(prop,value){ // Component Functions
if ( value instanceof Array ){ function getBgPos(prop/* , value */) {
const x = trueDimension(value[0]).v, return getStyleForProperty(this.element, prop) || defaultValues[prop];
y = trueDimension(value[1]).v; }
return [ x !== NaN ? x : 50, y !== NaN ? y : 50 ];
} else { function prepareBgPos(prop, value) {
let posxy = value.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50); if (value instanceof Array) {
posxy = posxy.split(/(\,|\s)/g); const x = trueDimension(value[0]).v;
posxy = posxy.length === 2 ? posxy : [posxy[0],50]; const y = trueDimension(value[1]).v;
return [ trueDimension(posxy[0]).v, trueDimension(posxy[1]).v ]; return [!Number.isNaN(x * 1) ? x : 50, !Number.isNaN(y * 1) ? y : 50];
} }
}
let posxy = value.replace(/top|left/g, 0)
// All Component Functions .replace(/right|bottom/g, 100)
const bgPositionFunctions = { .replace(/center|middle/g, 50);
prepareStart: getBgPos,
prepareProperty: prepareBgPos, posxy = posxy.split(/(,|\s)/g);
onStart: onStartBgPos posxy = posxy.length === 2 ? posxy : [posxy[0], 50];
} return [trueDimension(posxy[0]).v, trueDimension(posxy[1]).v];
}
// Component Full Object
const BackgroundPosition = { // All Component Functions
component: 'backgroundPositionProp', const bgPositionFunctions = {
property: 'backgroundPosition', prepareStart: getBgPos,
defaultValue: [50,50], prepareProperty: prepareBgPos,
Interpolate: {numbers}, onStart: onStartBgPos,
functions: bgPositionFunctions, };
Util: {trueDimension}
} // Component Full Object
const BackgroundPosition = {
export default BackgroundPosition component: 'backgroundPositionProp',
property: 'backgroundPosition',
Components.BackgroundPosition = 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
// const bgPosProp = { property : 'backgroundPosition', defaultValue: [0,0], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart } /* bgPosProp = {
property: 'backgroundPosition',
// Component Functions defaultValue: [0,0],
export function onStartBgPos(prop){ interpolators: {numbers},
if ( this.valuesEnd[prop] && !KUTE[prop]) { // opacity could be 0 functions = { prepareStart, prepareProperty, onStart }
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 Functions
} export function onStartBgPos(prop) {
} if (this.valuesEnd[prop] && !KUTE[prop]) {
KUTE[prop] = (elem, a, b, v) => {
// Component Base Object elem.style[prop] = `${(numbers(a[0], b[0], v) * 100 >> 0) / 100}% ${((numbers(a[1], b[1], v) * 100 >> 0) / 100)}%`;
const baseBgPosOps = { };
component: 'baseBackgroundPosition', }
property: 'backgroundPosition', }
Interpolate: {numbers},
functions: {onStart: onStartBgPos} // Component Base Object
} const baseBgPosOps = {
export default 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 defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import getStyleForProperty from '../process/getStyleForProperty.js' import trueDimension from '../util/trueDimension.js';
import trueDimension from '../util/trueDimension.js' import units from '../interpolation/units.js';
import units from '../interpolation/units.js' import { radiusOnStartFn } from './borderRadiusBase.js';
import {radiusOnStartFn} from './borderRadiusBase.js'
/* borderRadius = {
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} } category: 'borderRadius',
properties : [..],
// Component Properties defaultValues: {..},
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'] interpolation: {units}
const radiusValues = {} } */
radiusProps.map(x => radiusValues[x] = 0); // Component Properties
const radiusProps = ['borderRadius',
// Component Functions 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
const radiusOnStart = {}
radiusProps.forEach(tweenProp => { const radiusValues = {};
radiusOnStart[tweenProp] = radiusOnStartFn radiusProps.forEach((x) => { radiusValues[x] = 0; });
});
export function getRadius(tweenProp){ // Component Functions
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp]; const radiusOnStart = {};
} radiusProps.forEach((tweenProp) => {
export function prepareRadius(tweenProp,value){ radiusOnStart[tweenProp] = radiusOnStartFn;
return trueDimension(value); });
}
export function getRadius(tweenProp) {
// All Component Functions return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
export const radiusFunctions = { }
prepareStart: getRadius,
prepareProperty: prepareRadius, export function prepareRadius(tweenProp, value) {
onStart: radiusOnStart return trueDimension(value);
} }
// Full Component // All Component Functions
const BorderRadius = { export const radiusFunctions = {
component: 'borderRadiusProperties', prepareStart: getRadius,
category: 'borderRadius', prepareProperty: prepareRadius,
properties: radiusProps, onStart: radiusOnStart,
defaultValues: radiusValues, };
Interpolate: {units},
functions: radiusFunctions, // Full Component
Util: {trueDimension} const BorderRadius = {
} component: 'borderRadiusProperties',
category: 'borderRadius',
export default BorderRadius properties: radiusProps,
defaultValues: radiusValues,
Components.BorderRadiusProperties = BorderRadius Interpolate: { units },
functions: radiusFunctions,
Util: { trueDimension },
};
export default BorderRadius;

View file

@ -1,29 +1,35 @@
import KUTE from '../objects/kute.js' import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js' import units from '../interpolation/units.js';
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} } /* borderRadius = {
category: 'borderRadius',
// Component Properties properties : [..],
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'] defaultValues: {..},
interpolation: {units}
// Component Functions } */
export function radiusOnStartFn(tweenProp){
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // Component Properties
KUTE[tweenProp] = (elem, a, b, v) => { const radiusProps = ['borderRadius',
elem.style[tweenProp] = units(a.v,b.v,b.u,v); 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
}
} // Component Functions
} export function radiusOnStartFn(tweenProp) {
const radiusOnStart = {} if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
radiusProps.forEach(tweenProp => { KUTE[tweenProp] = (elem, a, b, v) => {
radiusOnStart[tweenProp] = radiusOnStartFn elem.style[tweenProp] = units(a.v, b.v, b.u, v);
}); };
}
// Base Component }
const baseBorderRadius = { const radiusOnStart = {};
component: 'baseBorderRadius', radiusProps.forEach((tweenProp) => {
category: 'borderRadius', radiusOnStart[tweenProp] = radiusOnStartFn;
Interpolate: {units}, });
functions: {onStart: radiusOnStart}
} // Base Component
export default baseBorderRadius 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 defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import getStyleForProperty from '../process/getStyleForProperty.js' import trueDimension from '../util/trueDimension.js';
import trueDimension from '../util/trueDimension.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import { boxModelOnStart } from './boxModelBase.js';
import {boxModelOnStart} from './boxModelBase.js'
// Component Properties
// Component Properties const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
'padding', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight',
'margin', 'marginTop','marginBottom', 'marginLeft', 'marginRight', 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth'];
'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth']
const boxModelValues = {} const boxModelValues = {};
boxModelProperties.map(x => boxModelValues[x] = 0); boxModelProperties.forEach((x) => { boxModelValues[x] = 0; });
// Component Functions // Component Functions
function getBoxModel(tweenProp){ function getBoxModel(tweenProp) {
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp]; return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
} }
function prepareBoxModel(tweenProp,value){ function prepareBoxModel(tweenProp, value) {
const boxValue = trueDimension(value), offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; const boxValue = trueDimension(value); const
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v; offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
} return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v;
const boxPropsOnStart = {} }
boxModelProperties.map(x => boxPropsOnStart[x] = boxModelOnStart ); const boxPropsOnStart = {};
boxModelProperties.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; });
// All Component Functions
const boxModelFunctions = { // All Component Functions
prepareStart: getBoxModel, const boxModelFunctions = {
prepareProperty: prepareBoxModel, prepareStart: getBoxModel,
onStart: boxPropsOnStart prepareProperty: prepareBoxModel,
} onStart: boxPropsOnStart,
};
// Component Full Component
const boxModel = { // Component Full Component
component: 'boxModelProperties', const boxModel = {
category: 'boxModel', component: 'boxModelProperties',
properties: boxModelProperties, category: 'boxModel',
defaultValues: boxModelValues, properties: boxModelProperties,
Interpolate: {numbers}, defaultValues: boxModelValues,
functions: boxModelFunctions Interpolate: { numbers },
} functions: boxModelFunctions,
};
export default boxModel
export default boxModel;
Components.BoxModelProperties = boxModel

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,134 +1,169 @@
import getStyleForProperty from '../process/getStyleForProperty.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import defaultValues from '../objects/defaultValues.js' import defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import trueColor from '../util/trueColor.js';
import trueColor from '../util/trueColor.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import colors from '../interpolation/colors.js';
import colors from '../interpolation/colors.js' import { dropShadow, onStartFilter } from './filterEffectsBase.js';
import {dropShadow,onStartFilter} from './filterEffectsBase.js'
/* filterEffects = {
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } property: 'filter',
subProperties: {},
// Component Util defaultValue: {},
function replaceDashNamespace(str){ interpolators: {},
return str.replace('-r','R').replace('-s','S') functions = { prepareStart, prepareProperty, onStart, crossCheck }
} } */
function parseDropShadow (shadow){ // Component Util
let newShadow function replaceDashNamespace(str) {
return str.replace('-r', 'R').replace('-s', 'S');
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>] function parseDropShadow(shadow) {
newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]]; let newShadow;
}
if (shadow.length === 3) { // [h-shadow, v-shadow, color]
// make sure the values are ready to tween newShadow = [shadow[0], shadow[1], 0, shadow[2]];
for (let i=0;i<3;i++){ } else if (shadow.length === 4) { // ideal [<offset-x>, <offset-y>, <blur-radius>, <color>]
newShadow[i] = parseFloat(newShadow[i]); newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]];
} }
// also the color must be a rgb object
newShadow[3] = trueColor(newShadow[3]); // make sure the values are ready to tween
return newShadow; for (let i = 0; i < 3; i += 1) {
} newShadow[i] = parseFloat(newShadow[i]);
}
function parseFilterString(currentStyle){ // also the color must be a rgb object
let result = {} newShadow[3] = trueColor(newShadow[3]);
let fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g return newShadow;
let matches = currentStyle.match(fnReg); }
const fnArray = currentStyle !== 'none' ? matches : 'none'
function parseFilterString(currentStyle) {
if (fnArray instanceof Array) { const result = {};
for (let j=0, jl = fnArray.length; j<jl; j++){ const fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g;
let p = fnArray[j].trim().split(/\((.+)/); const matches = currentStyle.match(fnReg);
let pp = replaceDashNamespace(p[0]); const fnArray = currentStyle !== 'none' ? matches : 'none';
if ( pp === 'dropShadow' ) {
let shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0] if (fnArray instanceof Array) {
let params = p[1].replace(shadowColor,'').split(/\s/).map(parseFloat) for (let j = 0, jl = fnArray.length; j < jl; j += 1) {
result[pp] = params.filter((el)=>!isNaN(el)).concat(shadowColor); const p = fnArray[j].trim().split(/\((.+)/);
} else { const pp = replaceDashNamespace(p[0]);
result[pp] = p[1].replace(/\'|\"|\)/g,''); 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);
return result } else {
} result[pp] = p[1].replace(/'|"|\)/g, '');
}
// Component Functions }
function getFilter(tweenProp,value) { }
let currentStyle = getStyleForProperty(this.element,tweenProp),
filterObject = parseFilterString(currentStyle), fnp return result;
}
for (let fn in value){
fnp = replaceDashNamespace(fn) // Component Functions
if ( !filterObject[fnp] ){ function getFilter(tweenProp, value) {
filterObject[fnp] = defaultValues[tweenProp][fn] const currentStyle = getStyleForProperty(this.element, tweenProp);
} const filterObject = parseFilterString(currentStyle);
} let fnp;
return filterObject;
} Object.keys(value).forEach((fn) => {
function prepareFilter(tweenProp,value) { fnp = replaceDashNamespace(fn);
let filterObject = {}, fnp if (!filterObject[fnp]) {
filterObject[fnp] = defaultValues[tweenProp][fn];
// {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){ return filterObject;
fnp = replaceDashNamespace(fn) }
if ( /hue/.test(fn) ) { function prepareFilter(tweenProp, value) {
filterObject[fnp] = parseFloat(value[fn]) const filterObject = {};
} else if ( /drop/.test(fn) ) { let fnp;
filterObject[fnp] = parseDropShadow(value[fn])
} else if ( fn === 'url' ) { // property: range | default
filterObject[fn] = value[fn] // opacity: [0-100%] | 100
// } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) { // blur: [0-Nem] | 0
} else { // saturate: [0-N%] | 100
filterObject[fn] = parseFloat(value[fn]) // invert: [0-100%] | 0
} // grayscale: [0-100%] | 0
} // brightness: [0-N%] | 100
// contrast: [0-N%] | 100
return filterObject; // sepia: [0-N%] | 0
} // 'hueRotate': [0-Ndeg] | 0
// 'dropShadow': [0,0,0,(r:0,g:0,b:0)] | 0
function crossCheckFilter(tweenProp){ // url: '' | ''
if ( this.valuesEnd[tweenProp] ) {
for (const fn in this.valuesStart[tweenProp]){ Object.keys(value).forEach((fn) => {
if (!this.valuesEnd[tweenProp][fn]){ fnp = replaceDashNamespace(fn);
this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][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];
// All Component Functions // } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) {
const filterFunctions = { } else {
prepareStart: getFilter, filterObject[fn] = parseFloat(value[fn]);
prepareProperty: prepareFilter, }
onStart: onStartFilter, });
crossCheck: crossCheckFilter
} return filterObject;
}
// Full Component
const filterEffects = { function crossCheckFilter(tweenProp) {
component: 'filterEffects', if (this.valuesEnd[tweenProp]) {
property: 'filter', Object.keys(this.valuesStart[tweenProp]).forEach((fn) => {
// subProperties: ['blur', 'brightness','contrast','dropShadow','hueRotate','grayscale','invert','opacity','saturate','sepia','url'], // opacity function interfere with opacityProperty if (!this.valuesEnd[tweenProp][fn]) {
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:''}, this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn];
Interpolate: { }
opacity: numbers, });
blur: numbers, }
saturate: numbers, }
grayscale: numbers,
brightness: numbers, // All Component Functions
contrast: numbers, const filterFunctions = {
sepia: numbers, prepareStart: getFilter,
invert: numbers, prepareProperty: prepareFilter,
hueRotate: numbers, onStart: onStartFilter,
dropShadow: {numbers,colors,dropShadow} crossCheck: crossCheckFilter,
}, };
functions: filterFunctions,
Util: {parseDropShadow,parseFilterString,replaceDashNamespace,trueColor} // Full Component
} const filterEffects = {
component: 'filterEffects',
export default filterEffects property: 'filter',
// opacity function interfere with opacityProperty
Components.FilterEffects = filterEffects // 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js' import colors from '../interpolation/colors.js';
// const filterEffects = { property : 'filter', subProperties: {}, defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } /* filterEffects = {
property: 'filter',
// Component Interpolation subProperties: {},
export function dropShadow(a,b,v){ defaultValue: {},
let params = [], unit = 'px' interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
for (let i=0; i<3; i++){ } */
params[i] = ((numbers(a[i],b[i],v) * 100 >>0) /100) + unit
} // Component Interpolation
return `drop-shadow(${params.concat( colors(a[3],b[3],v) ).join(' ') })` export function dropShadow(a, b, v) {
} const params = [];
// Component Functions const unit = 'px';
export function onStartFilter(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) { for (let i = 0; i < 3; i += 1) {
KUTE[tweenProp] = (elem, a, b, v) => { params[i] = ((numbers(a[i], b[i], v) * 100 >> 0) / 100) + unit;
elem.style[tweenProp] = (b.url ? `url(${b.url})` : '') }
+ (a.opacity||b.opacity ? `opacity(${((numbers(a.opacity,b.opacity,v) * 100)>>0)/100}%)` : '') return `drop-shadow(${params.concat(colors(a[3], b[3], v)).join(' ')})`;
+ (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}%)` : '') // Component Functions
+ (a.invert||b.invert ? `invert(${((numbers(a.invert,b.invert,v) * 100)>>0)/100}%)` : '') export function onStartFilter(tweenProp) {
+ (a.grayscale||b.grayscale ? `grayscale(${((numbers(a.grayscale,b.grayscale,v) * 100)>>0)/100}%)` : '') if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
+ (a.hueRotate||b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate,b.hueRotate,v) * 100)>>0)/100 }deg)` : '') KUTE[tweenProp] = (elem, a, b, v) => {
+ (a.sepia||b.sepia ? `sepia(${((numbers(a.sepia,b.sepia,v) * 100)>>0)/100 }%)` : '') elem.style[tweenProp] = (b.url ? `url(${b.url})` : '')
+ (a.brightness||b.brightness ? `brightness(${((numbers(a.brightness,b.brightness,v) * 100)>>0)/100 }%)` : '') + (a.opacity || b.opacity ? `opacity(${((numbers(a.opacity, b.opacity, v) * 100) >> 0) / 100}%)` : '')
+ (a.contrast||b.contrast ? `contrast(${((numbers(a.contrast,b.contrast,v) * 100)>>0)/100 }%)` : '') + (a.blur || b.blur ? `blur(${((numbers(a.blur, b.blur, v) * 100) >> 0) / 100}em)` : '')
+ (a.dropShadow||b.dropShadow ? dropShadow(a.dropShadow,b.dropShadow,v) : '') + (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}%)` : '')
// Base Component + (a.contrast || b.contrast ? `contrast(${((numbers(a.contrast, b.contrast, v) * 100) >> 0) / 100}%)` : '')
const baseFilter = { + (a.dropShadow || b.dropShadow ? dropShadow(a.dropShadow, b.dropShadow, v) : '');
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: { // Base Component
opacity: numbers, const baseFilter = {
blur: numbers, component: 'baseFilter',
saturate: numbers, property: 'filter',
grayscale: numbers, // opacity function interfere with opacityProperty
brightness: numbers, // subProperties: ['blur', 'brightness','contrast','dropShadow',
contrast: numbers, // 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'],
sepia: numbers, // defaultValue: {
invert: numbers, // opacity: 100, blur: 0, saturate: 100, grayscale: 0,
hueRotate: numbers, // brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0,
dropShadow: {numbers,colors,dropShadow} // dropShadow: [0,0,0,{r:0,g:0,b:0}], url:''
}, // },
functions: {onStart:onStartFilter} Interpolate: {
} opacity: numbers,
blur: numbers,
export default baseFilter 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 defaultValues from '../objects/defaultValues.js';
import onStart from '../objects/onStart.js' import onStart from '../objects/onStart.js';
import Components from '../objects/components.js' import trueColor from '../util/trueColor.js';
import trueColor from '../util/trueColor.js' import trueDimension from '../util/trueDimension.js';
import trueDimension from '../util/trueDimension.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import colors from '../interpolation/colors.js';
import colors from '../interpolation/colors.js' import { attributes, onStartAttr } from './htmlAttributesBase.js';
import {attributes,onStartAttr} from './htmlAttributesBase.js'
// Component Name
// Component Name const ComponentName = 'htmlAttributes';
let ComponentName = 'htmlAttributes'
// Component Properties
// Component Properties const svgColors = ['fill', 'stroke', 'stop-color'];
const svgColors = ['fill','stroke','stop-color'];
// Component Util
// Component Util function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); }
function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); }
// Component Functions
// Component Functions export function getAttr(tweenProp, value) {
export function getAttr(tweenProp,value){ const attrStartValues = {};
let attrStartValues = {}; Object.keys(value).forEach((attr) => {
for (let attr in value){ // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px'
let attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px' const attribute = replaceUppercase(attr).replace(/_+[a-z]+/, '');
currentValue = this.element.getAttribute(attribute); const currentValue = this.element.getAttribute(attribute);
attrStartValues[attribute] = svgColors.includes(attribute) ? (currentValue || 'rgba(0,0,0,0)') : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); attrStartValues[attribute] = svgColors.includes(attribute)
} ? (currentValue || 'rgba(0,0,0,0)')
return attrStartValues; : (currentValue || (/opacity/i.test(attr) ? 1 : 0));
} });
export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object)
let attributesObject = {}; return attrStartValues;
for ( let p in attrObj ) { }
let prop = replaceUppercase(p),
regex = /(%|[a-z]+)$/, export function prepareAttr(tweenProp, attrObj) { // attr (string),attrObj (object)
currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); const attributesObject = {};
if ( !svgColors.includes(prop)) {
if ( currentValue !== null && regex.test(currentValue) ) { // attributes set with unit suffixes Object.keys(attrObj).forEach((p) => {
let unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u, const prop = replaceUppercase(p);
suffix = /%/.test(unit) ? '_percent' : `_${unit}`; const regex = /(%|[a-z]+)$/;
onStart[ComponentName][prop+suffix] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/, ''));
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) {
attributes[tp] = (elem, p, a, b, v) => { if (!svgColors.includes(prop)) {
let _p = p.replace(suffix,''); // attributes set with unit suffixes
elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u ); if (currentValue !== null && regex.test(currentValue)) {
} const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u;
} const suffix = /%/.test(unit) ? '_percent' : `_${unit}`;
}
attributesObject[prop+suffix] = trueDimension(attrObj[p]); // most "unknown" attributes cannot register into onStart, so we manually add them
} else if ( !regex.test(attrObj[p]) || currentValue === null || currentValue !== null && !regex.test(currentValue) ) { onStart[ComponentName][prop + suffix] = (tp) => {
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)) {
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { attributes[tp] = (elem, oneAttr, a, b, v) => {
attributes[tp] = (elem, oneAttr, a, b, v) => { const _p = oneAttr.replace(suffix, '');
elem.setAttribute(oneAttr, (numbers(a,b,v) * 1000 >> 0) / 1000 ); elem.setAttribute(_p, ((numbers(a.v, b.v, v) * 1000 >> 0) / 1000) + b.u);
} };
} }
} };
attributesObject[prop] = parseFloat(attrObj[p]); attributesObject[prop + suffix] = trueDimension(attrObj[p]);
} } else if (!regex.test(attrObj[p]) || currentValue === null
} else { // colors || (currentValue !== null && !regex.test(currentValue))) {
onStart[ComponentName][prop] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them // most "unknown" attributes cannot register into onStart, so we manually add them
if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { onStart[ComponentName][prop] = (tp) => {
attributes[tp] = (elem, oneAttr, a, b, v) => { if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
elem.setAttribute(oneAttr, colors(a,b,v)); attributes[tp] = (elem, oneAttr, a, b, v) => {
} elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000);
} };
} }
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; };
} attributesObject[prop] = parseFloat(attrObj[p]);
} }
return attributesObject; } else { // colors
} // most "unknown" attributes cannot register into onStart, so we manually add them
onStart[ComponentName][prop] = (tp) => {
// All Component Functions if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) {
const attrFunctions = { attributes[tp] = (elem, oneAttr, a, b, v) => {
prepareStart: getAttr, elem.setAttribute(oneAttr, colors(a, b, v));
prepareProperty: prepareAttr, };
onStart: onStartAttr }
} };
attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p];
// Component Full }
const htmlAttributes = { });
component: ComponentName,
property: 'attr', return attributesObject;
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 }, // All Component Functions
functions: attrFunctions, const attrFunctions = {
// export to global for faster execution prepareStart: getAttr,
Util: { replaceUppercase, trueColor, trueDimension } prepareProperty: prepareAttr,
} onStart: onStartAttr,
};
export default htmlAttributes
// Component Full
Components.HTMLAttributes = htmlAttributes 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js' import colors from '../interpolation/colors.js';
// Component Name // Component Name
let ComponentName = 'baseHTMLAttributes' const ComponentName = 'baseHTMLAttributes';
// Component Special // Component Special
let attributes = {}; const attributes = {};
export {attributes} export { attributes };
export const onStartAttr = { export const onStartAttr = {
attr : function(tweenProp){ attr(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
KUTE[tweenProp] = (elem, vS, vE, v) => { KUTE[tweenProp] = (elem, vS, vE, v) => {
for ( const oneAttr in vE ){ Object.keys(vE).forEach((oneAttr) => {
KUTE.attributes[oneAttr](elem,oneAttr,vS[oneAttr],vE[oneAttr],v); KUTE.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v);
} });
} };
} }
}, },
attributes : function(tweenProp){ attributes(tweenProp) {
if (!KUTE[tweenProp] && this.valuesEnd.attr) { if (!KUTE[tweenProp] && this.valuesEnd.attr) {
KUTE[tweenProp] = attributes KUTE[tweenProp] = attributes;
} }
} },
} };
// Component Base // Component Base
const baseAttributes = { const baseAttributes = {
component: ComponentName, component: ComponentName,
property: 'attr', property: 'attr',
// subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], // the Animation class will need some values to validate this Object attribute // 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 // subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'],
Interpolate: { numbers,colors }, // defaultValue:
functions: {onStart:onStartAttr} // fill : 'rgb(0,0,0)',
} // stroke: 'rgb(0,0,0)',
// 'stop-color': 'rgb(0,0,0)',
export default baseAttributes // 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 getStyleForProperty from '../process/getStyleForProperty.js';
import Components from '../objects/components.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import { onStartOpacity } from './opacityPropertyBase.js';
import {onStartOpacity} from './opacityPropertyBase.js'
/* opacityProperty = {
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart } property: 'opacity',
defaultValue: 1,
// Component Functions interpolators: {numbers},
function getOpacity(tweenProp){ functions = { prepareStart, prepareProperty, onStart }
return getStyleForProperty(this.element,tweenProp) } */
}
function prepareOpacity(tweenProp,value){ // Component Functions
return parseFloat(value); // opacity always FLOAT function getOpacity(tweenProp/* , value */) {
} return getStyleForProperty(this.element, tweenProp);
}
// All Component Functions
const opacityFunctions = { function prepareOpacity(tweenProp, value) {
prepareStart: getOpacity, return parseFloat(value); // opacity always FLOAT
prepareProperty: prepareOpacity, }
onStart: onStartOpacity
} // All Component Functions
const opacityFunctions = {
// Full Component prepareStart: getOpacity,
const opacityProperty = { prepareProperty: prepareOpacity,
component: 'opacityProperty', onStart: onStartOpacity,
property: 'opacity', };
defaultValue: 1,
Interpolate: {numbers}, // Full Component
functions: opacityFunctions const opacityProperty = {
} component: 'opacityProperty',
property: 'opacity',
export default opacityProperty defaultValue: 1,
Interpolate: { numbers },
Components.OpacityProperty = opacityProperty functions: opacityFunctions,
};
export default opacityProperty;

View file

@ -1,24 +1,30 @@
import KUTE from '../objects/kute.js' import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
// const opacityProperty = { property : 'opacity', defaultValue: 1, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart } /* opacityProperty = {
property: 'opacity',
// Component Functions defaultValue: 1,
export function onStartOpacity(tweenProp){ interpolators: {numbers},
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // opacity could be 0 functions = { prepareStart, prepareProperty, onStart }
KUTE[tweenProp] = (elem, a, b, v) => { } */
elem.style[tweenProp] = ((numbers(a,b,v) * 1000)>>0)/1000;
} // Component Functions
} export function onStartOpacity(tweenProp/* , value */) {
} // opacity could be 0 sometimes, we need to check regardless
if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
// Base Component KUTE[tweenProp] = (elem, a, b, v) => {
const baseOpacity = { elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000;
component: 'baseOpacity', };
property: 'opacity', }
// defaultValue: 1, }
Interpolate: {numbers},
functions: {onStart: onStartOpacity} // Base Component
} const baseOpacity = {
component: 'baseOpacity',
export default 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 supportPassive from 'shorter-js/src/boolean/supportPassive.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import supportPassive from 'shorter-js/src/boolean/supportPassive.js'
import {
scrollContainer,
import {scrollContainer,onStartScroll,onCompleteScroll,scrollIn,scrollOut,getScrollTargets,preventScroll,toggleScrollEvents} from './scrollPropertyBase.js' onStartScroll,
onCompleteScroll,
// Component Functions scrollIn,
function getScroll(){ scrollOut,
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element; getScrollTargets,
return this.element === scrollContainer ? (window.pageYOffset || scrollContainer.scrollTop) : this.element.scrollTop; preventScroll,
} toggleScrollEvents,
function prepareScroll(prop,value){ } from './scrollPropertyBase.js';
return parseInt(value);
} // Component Functions
function getScroll() {
// All Component Functions this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
const scrollFunctions = { ? scrollContainer : this.element;
prepareStart: getScroll,
prepareProperty: prepareScroll, return this.element === scrollContainer
onStart: onStartScroll, ? (window.pageYOffset || scrollContainer.scrollTop)
onComplete: onCompleteScroll : this.element.scrollTop;
} }
// Full Component function prepareScroll(prop, value) {
const scrollProperty = { return parseInt(value, 10);
component: 'scrollProperty', }
property: 'scroll',
defaultValue: 0, // All Component Functions
Interpolate: {numbers}, const scrollFunctions = {
functions: scrollFunctions, prepareStart: getScroll,
// export stuff to global prepareProperty: prepareScroll,
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, supportPassive } onStart: onStartScroll,
} onComplete: onCompleteScroll,
};
export default scrollProperty
// Full Component
Components.ScrollProperty = scrollProperty 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 supportPassive from 'shorter-js/src/boolean/supportPassive.js';
import numbers from '../interpolation/numbers.js' import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents.js';
import supportTouch from 'shorter-js/src/boolean/supportTouch.js';
import supportPassive from 'shorter-js/src/boolean/supportPassive.js' import numbers from '../interpolation/numbers.js';
import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents.js' import KUTE from '../objects/kute.js';
import supportTouch from 'shorter-js/src/boolean/supportTouch.js'
// Component Util
// Component Util // events preventing scroll
// events preventing scroll const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel';
const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel'
// true scroll container
// true scroll container // very important and specific to the component
// very important and specific to the component export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent)
export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent) ? document.body : document.documentElement ? document.body
: document.documentElement;
// scroll event options
// it's important to stop propagating when animating scroll // scroll event options
const passiveHandler = supportPassive ? { passive: false } : false // 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) { // prevent mousewheel or touch events while tweening scroll
this.scrolling && e.preventDefault() export function preventScroll(e) {
} if (this.scrolling) e.preventDefault();
export function getScrollTargets(){ }
let el = this.element export function getScrollTargets() {
return el === scrollContainer ? { el: document, st: document.body } : { el: el, st: el} 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); export function toggleScrollEvents(action, element) {
element[action]( touchOrWheel, preventScroll, passiveHandler); element[action](mouseHoverEvents[0], preventScroll, passiveHandler);
} element[action](touchOrWheel, preventScroll, passiveHandler);
export function scrollIn(){ }
let targets = getScrollTargets.call(this) export function scrollIn() {
const targets = getScrollTargets.call(this);
if ( 'scroll' in this.valuesEnd && !targets.el.scrolling) {
targets.el.scrolling = 1; if ('scroll' in this.valuesEnd && !targets.el.scrolling) {
toggleScrollEvents('addEventListener',targets.el) targets.el.scrolling = 1;
targets.st.style.pointerEvents = 'none' toggleScrollEvents('addEventListener', targets.el);
} targets.st.style.pointerEvents = 'none';
} }
export function scrollOut(){ //prevent scroll when tweening scroll }
let targets = getScrollTargets.call(this) export function scrollOut() { // prevent scroll when tweening scroll
const targets = getScrollTargets.call(this);
if ( 'scroll' in this.valuesEnd && targets.el.scrolling) {
targets.el.scrolling = 0; if ('scroll' in this.valuesEnd && targets.el.scrolling) {
toggleScrollEvents('removeEventListener',targets.el) targets.el.scrolling = 0;
targets.st.style.pointerEvents = '' toggleScrollEvents('removeEventListener', targets.el);
} targets.st.style.pointerEvents = '';
} }
}
// Component Functions
export function onStartScroll(tweenProp){ // Component Functions
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // checking 0 will NOT add the render function export function onStartScroll(tweenProp) {
this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) ? scrollContainer : this.element; // checking 0 will NOT add the render function
scrollIn.call(this); if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => { this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window)
elem.scrollTop = (numbers(a,b,v))>>0; ? 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) }
} }
export function onCompleteScroll(/* tweenProp */) {
// Base Component scrollOut.call(this);
const baseScroll = { }
component: 'baseScroll',
property: 'scroll', // Base Component
// defaultValue: 0, const baseScroll = {
Interpolate: {numbers}, component: 'baseScroll',
functions: { property: 'scroll',
onStart: onStartScroll, // defaultValue: 0,
onComplete: onCompleteScroll Interpolate: { numbers },
}, functions: {
// unfortunatelly scroll needs all them no matter the packaging onStart: onStartScroll,
Util: { preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive } onComplete: onCompleteScroll,
} },
// unfortunatelly scroll needs all them no matter the packaging
export default baseScroll Util: {
preventScroll, scrollIn, scrollOut, getScrollTargets, supportPassive,
},
};
export default baseScroll;

View file

@ -1,93 +1,110 @@
import defaultValues from '../objects/defaultValues.js' import defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import getStyleForProperty from '../process/getStyleForProperty.js' import trueColor from '../util/trueColor.js';
import trueColor from '../util/trueColor.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import colors from '../interpolation/colors.js';
import colors from '../interpolation/colors.js' import { onStartShadow } from './shadowPropertiesBase.js';
import {onStartShadow} from './shadowPropertiesBase.js'
// Component Properties
// Component Properties const shadowProps = ['boxShadow', 'textShadow'];
const shadowProps = ['boxShadow','textShadow']
// Component Util
// Component Util
// box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit
// 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
// text-shadow: none | offset-x offset-y blur-radius color |initial|inherit // utility function to process values accordingly
// utility function to process values accordingly // numbers must be floats and color must be rgb object
// numbers must be floats and color must be rgb object function processShadowArray(shadow, tweenProp) {
function processShadowArray (shadow,tweenProp){ let newShadow;
let newShadow, i;
// [h-shadow, v-shadow, color]
if (shadow.length === 3) { // [h-shadow, v-shadow, color] if (shadow.length === 3) {
newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none']; 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] // [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 === 4) {
} else if (shadow.length === 5) { // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color] newShadow = /inset|none/.test(shadow[3])
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']; ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]]
} else if (shadow.length === 6) { // ideal [h-shadow, v-shadow, blur, spread, color, inset] : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none'];
newShadow = shadow; // [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])
// make sure the values are ready to tween ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]]
for (i=0;i<4;i++){ : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none'];
newShadow[i] = parseFloat(newShadow[i]); // ideal [h-shadow, v-shadow, blur, spread, color, inset]
} } else if (shadow.length === 6) {
// also the color must be a rgb object newShadow = shadow;
newShadow[4] = trueColor(newShadow[4]); }
// return tweenProp === 'boxShadow' ? newShadow : [newShadow[0],newShadow[1],newShadow[2],newShadow[4]]; // make sure the values are ready to tween
newShadow = tweenProp === 'boxShadow' ? newShadow : newShadow.filter((x,i)=>[0,1,2,4].indexOf(i)>-1); for (let i = 0; i < 4; i += 1) {
return newShadow; newShadow[i] = parseFloat(newShadow[i]);
} }
// Component Functions // also the color must be a rgb object
export function getShadow(tweenProp,value){ newShadow[4] = trueColor(newShadow[4]);
let cssShadow = getStyleForProperty(this.element,tweenProp);
return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow) ? defaultValues[tweenProp] : cssShadow; // '0px 0px 0px 0px rgb(0,0,0)' newShadow = tweenProp === 'boxShadow'
} ? newShadow
export function prepareShadow(tweenProp,value) { : newShadow.filter((x, i) => [0, 1, 2, 4].includes(i));
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
// parseProperty for boxShadow, builds basic structure with ready to tween values return newShadow;
if (typeof value === 'string'){ }
let currentColor, inset = 'none';
// a full RegEx for color strings // Component Functions
const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi export function getShadow(tweenProp/* , value */) {
const cssShadow = getStyleForProperty(this.element, tweenProp);
// make sure to always have the inset last if possible // '0px 0px 0px 0px rgb(0,0,0)'
inset = /inset/.test(value) ? 'inset' : inset; return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow)
value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g,'') : value; ? defaultValues[tweenProp]
: cssShadow;
// 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]); export function prepareShadow(tweenProp, propValue) {
// [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset]
value = processShadowArray(value,tweenProp); // parseProperty for boxShadow, builds basic structure with ready to tween values
} else if (value instanceof Array){ let value = propValue;
value = processShadowArray(value,tweenProp); if (typeof value === 'string') {
} let inset = 'none';
return value; // 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);
const shadowPropOnStart = {}
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow) // make sure to always have the inset last if possible
inset = /inset/.test(value) ? 'inset' : inset;
// All Component Functions value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g, '') : value;
const shadowFunctions = {
prepareStart: getShadow, // also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset"
prepareProperty: prepareShadow, value = value.replace(currentColor[0], '').split(' ').concat([currentColor[0].replace(/\s/g, '')], [inset]);
onStart: shadowPropOnStart
} value = processShadowArray(value, tweenProp);
} else if (value instanceof Array) {
// Component Full value = processShadowArray(value, tweenProp);
const shadowProperties = { }
component: 'shadowProperties',
properties: shadowProps, return value;
defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px rgb(0,0,0)'}, }
Interpolate: {numbers,colors},
functions: shadowFunctions, const shadowPropOnStart = {};
Util: { processShadowArray, trueColor } shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
}
// All Component Functions
export default shadowProperties const shadowFunctions = {
prepareStart: getShadow,
Components.ShadowProperties = shadowProperties 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import colors from '../interpolation/colors.js' import colors from '../interpolation/colors.js';
// Component Properties // Component Properties
const shadowProps = ['boxShadow','textShadow'] const shadowProps = ['boxShadow', 'textShadow'];
// Component Functions // Component Functions
export function onStartShadow(tweenProp) { export function onStartShadow(tweenProp) {
if ( this.valuesEnd[tweenProp] && !KUTE[tweenProp]) { if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
KUTE[tweenProp] = (elem, a, b, v) => { KUTE[tweenProp] = (elem, a, b, v) => {
// let's start with the numbers | set unit | also determine inset // let's start with the numbers | set unit | also determine inset
let params = [], unit = 'px', sl = tweenProp === 'textShadow' ? 3 : 4, const params = [];
colA = sl === 3 ? a[3] : a[4], colB = sl === 3 ? b[3] : b[4], const unit = 'px';
inset = a[5] && a[5] !== 'none' || b[5] && b[5] !== 'none' ? ' inset' : false; const sl = tweenProp === 'textShadow' ? 3 : 4;
const colA = sl === 3 ? a[3] : a[4];
for (let i=0; i<sl; i++){ const colB = sl === 3 ? b[3] : b[4];
params.push( ((numbers( a[i], b[i], v ) * 1000 >> 0) / 1000) + unit ); const inset = (a[5] && a[5] !== 'none') || (b[5] && b[5] !== 'none') ? ' inset' : false;
}
// the final piece of the puzzle, the DOM update for (let i = 0; i < sl; i += 1) {
elem.style[tweenProp] = inset ? colors(colA,colB,v) + params.join(' ') + inset params.push(((numbers(a[i], b[i], v) * 1000 >> 0) / 1000) + unit);
: colors(colA,colB,v) + params.join(' '); }
} // the final piece of the puzzle, the DOM update
} elem.style[tweenProp] = inset
} ? colors(colA, colB, v) + params.join(' ') + inset
const shadowPropOnStart = {} : colors(colA, colB, v) + params.join(' ');
shadowProps.map(x=>shadowPropOnStart[x]=onStartShadow) };
}
// Component Base }
const baseShadow = { const shadowPropOnStart = {};
component: 'baseShadow', shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; });
// properties: shadowProps,
// defaultValues: {boxShadow :'0px 0px 0px 0px rgb(0,0,0)', textShadow: '0px 0px 0px 0px rgb(0,0,0)'}, // Component Base
Interpolate: {numbers,colors}, const baseShadow = {
functions: {onStart: shadowPropOnStart} component: 'baseShadow',
} // properties: shadowProps,
// defaultValues: {
export default baseShadow // 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 parsePathString from 'svg-path-commander/src/process/parsePathString.js';
import selector from '../util/selector.js' import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js';
import numbers from '../interpolation/numbers.js' import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import {onStartCubicMorph} from './svgCubicMorphBase.js' import reverseCurve from 'svg-path-commander/src/process/reverseCurve.js';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js';
import parsePathString from 'svg-path-commander/src/process/parsePathString.js' import clonePath from 'svg-path-commander/src/process/clonePath.js';
import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js' import splitCubic from 'svg-path-commander/src/process/splitCubic.js';
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js' import splitPath from 'svg-path-commander/src/process/splitPath.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js' import getSegCubicLength from 'svg-path-commander/src/util/getSegCubicLength.js';
import reverseCurve from 'svg-path-commander/src/process/reverseCurve.js' import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js' import { onStartCubicMorph } from './svgCubicMorphBase.js';
import clonePath from 'svg-path-commander/src/process/clonePath.js' import numbers from '../interpolation/numbers.js';
import splitCubic from 'svg-path-commander/src/process/splitCubic.js' import selector from '../util/selector.js';
import splitPath from 'svg-path-commander/src/process/splitPath.js'
import getSegCubicLength from 'svg-path-commander/src/util/getSegCubicLength.js' /* SVGMorph = {
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js' property: 'path',
defaultValue: [],
interpolators: {numbers},
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Util
function getCurveArray(pathString){ // Component Util
return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map((segment,i,pathArray)=>{ function getCurveArray(pathString) {
let segmentData = i && pathArray[i-1].slice(-2).concat(segment.slice(1)), return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0])
curveLength = i ? getSegCubicLength.apply(0, segmentData ) : 0, .map((segment, i, pathArray) => {
subsegs = i ? (curveLength ? splitCubic( segmentData ) : [segment,segment]) : [segment]; // must be [segment,segment] const segmentData = i && pathArray[i - 1].slice(-2).concat(segment.slice(1));
return { const curveLength = i ? getSegCubicLength.apply(0, segmentData) : 0;
s: segment,
ss: subsegs, let subsegs;
l: curveLength if (i) {
} // must be [segment,segment]
}) subsegs = curveLength ? splitCubic(segmentData) : [segment, segment];
} } else {
subsegs = [segment];
function equalizeSegments(path1,path2,TL){ }
let c1 = getCurveArray(path1),
c2 = getCurveArray(path2), return {
L1 = c1.length, s: segment,
L2 = c2.length, ss: subsegs,
l1 = c1.filter(x=>x.l).length, l: curveLength,
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], function equalizeSegments(path1, path2, TL) {
dif = [tl-L1,tl-L2], const c1 = getCurveArray(path1);
canSplit = 0, const c2 = getCurveArray(path2);
result = [c1,c2].map((x,i) => x.l === tl ? x.map(y=>y.s) const L1 = c1.length;
: x.map((y,j) => { const L2 = c2.length;
canSplit = j && dif[i] && y.l >= mm[i] const l1 = c1.filter((x) => x.l).length;
dif[i] -= canSplit ? 1 : 0 const l2 = c2.filter((x) => x.l).length;
return canSplit ? y.ss : [y.s] const m1 = c1.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l1 || 0;
}).flat()) const m2 = c2.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l2 || 0;
const tl = TL || Math.max(L1, L2);
return result[0].length === result[1].length ? result : equalizeSegments(result[0],result[1],tl) const mm = [m1, m2];
} const dif = [tl - L1, tl - L2];
let canSplit = 0;
function getRotations(a) { const result = [c1, c2]
let segCount = a.length, pointCount = segCount - 1 .map((x, i) => (x.l === tl
? x.map((y) => y.s)
return a.map((f,idx) => { : x.map((y, j) => {
return a.map((p,i)=>{ canSplit = j && dif[i] && y.l >= mm[i];
let oldSegIdx = idx + i, seg; dif[i] -= canSplit ? 1 : 0;
if (i===0 || a[oldSegIdx] && a[oldSegIdx][0] === 'M') { return canSplit ? y.ss : [y.s];
seg = a[oldSegIdx] }).flat()));
return ['M'].concat(seg.slice(-2))
} else { return result[0].length === result[1].length
if (oldSegIdx >= segCount) oldSegIdx -= pointCount; ? result
return a[oldSegIdx] : equalizeSegments(result[0], result[1], tl);
} }
})
}) function getRotations(a) {
} const segCount = a.length;
const pointCount = segCount - 1;
function getRotatedCurve(a,b) {
let segCount = a.length - 1, return a.map((f, idx) => a.map((p, i) => {
lineLengths = [], let oldSegIdx = idx + i;
computedIndex = 0, let seg;
sumLensSqrd = 0,
rotations = getRotations(a); if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) {
seg = a[oldSegIdx];
rotations.map((r,i)=>{ return ['M'].concat(seg.slice(-2));
a.slice(1).map((s,j) => { }
sumLensSqrd += distanceSquareRoot(a[(i+j) % segCount].slice(-2),b[j % segCount].slice(-2)) if (oldSegIdx >= segCount) oldSegIdx -= pointCount;
}) return a[oldSegIdx];
lineLengths[i] = sumLensSqrd }));
sumLensSqrd = 0 }
})
function getRotatedCurve(a, b) {
computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)) const segCount = a.length - 1;
const lineLengths = [];
return rotations[computedIndex] let computedIndex = 0;
} let sumLensSqrd = 0;
const rotations = getRotations(a);
// Component Functions
function getCubicMorph(tweenProp){ rotations.forEach((r, i) => {
return this.element.getAttribute('d'); a.slice(1).forEach((s, j) => {
} sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2));
function prepareCubicMorph(tweenProp,value){ });
// get path d attribute or create a path from string value lineLengths[i] = sumLensSqrd;
let pathObject = {}, sumLensSqrd = 0;
el = value instanceof SVGElement ? value : /^\.|^\#/.test(value) ? selector(value) : null, });
pathReg = new RegExp('\\n','ig'); // remove newlines, they break some JSON strings
computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths));
// make sure to return pre-processed values
if ( typeof(value) === 'object' && value.curve ) { return rotations[computedIndex];
return value; }
} else if ( el && /path|glyph/.test(el.tagName) ) {
pathObject.original = el.getAttribute('d').replace(pathReg,''); // Component Functions
} else if (!el && typeof(value) === 'string') { // maybe it's a string path already function getCubicMorph(/* tweenProp, value */) {
pathObject.original = value.replace(pathReg,''); return this.element.getAttribute('d');
} }
return pathObject; function prepareCubicMorph(tweenProp, value) {
} // get path d attribute or create a path from string value
function crossCheckCubicMorph(tweenProp){ const pathObject = {};
if (this.valuesEnd[tweenProp]) { // remove newlines, they break some JSON strings
let pathCurve1 = this.valuesStart[tweenProp].curve, const pathReg = new RegExp('\\n', 'ig');
pathCurve2 = this.valuesEnd[tweenProp].curve
let el = null;
if ( !pathCurve1 || !pathCurve2 || ( pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length) ) { if (value instanceof SVGElement) {
let path1 = this.valuesStart[tweenProp].original, el = value;
path2 = this.valuesEnd[tweenProp].original, } else if (/^\.|^#/.test(value)) {
curves = equalizeSegments(path1,path2), el = selector(value);
curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) ? reverseCurve(curves[0]) : clonePath(curves[0]) }
this.valuesStart[tweenProp].curve = curve0; // make sure to return pre-processed values
this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1],curve0) 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
// All Component Functions } else if (!el && typeof (value) === 'string') {
const svgCubicMorphFunctions = { pathObject.original = value.replace(pathReg, '');
prepareStart: getCubicMorph, }
prepareProperty: prepareCubicMorph, return pathObject;
onStart: onStartCubicMorph, }
crossCheck: crossCheckCubicMorph function crossCheckCubicMorph(tweenProp) {
} if (this.valuesEnd[tweenProp]) {
const pathCurve1 = this.valuesStart[tweenProp].curve;
// Component Full const pathCurve2 = this.valuesEnd[tweenProp].curve;
const svgCubicMorph = {
component: 'svgCubicMorph', if (!pathCurve1 || !pathCurve2
property: 'path', || (pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length)) {
defaultValue: [], const path1 = this.valuesStart[tweenProp].original;
Interpolate: {numbers,pathToString}, const path2 = this.valuesEnd[tweenProp].original;
functions: svgCubicMorphFunctions, const curves = equalizeSegments(path1, path2);
// export utils to global for faster execution const curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1])
Util: { ? reverseCurve(curves[0])
pathToCurve, pathToAbsolute, pathToString, parsePathString, : clonePath(curves[0]);
getRotatedCurve, getRotations, equalizeSegments,
reverseCurve, clonePath, getDrawDirection, this.valuesStart[tweenProp].curve = curve0;
splitCubic, getCurveArray this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1], curve0);
} }
} }
}
export default svgCubicMorph
// All Component Functions
Components.SVGCubicMorph = svgCubicMorph 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 pathToString from 'svg-path-commander/src/convert/pathToString.js';
import numbers from '../interpolation/numbers.js' import KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js'
/* SVGMorph = {
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } property: 'path',
defaultValue: [],
// Component Functions interpolators: {numbers} },
export function onStartCubicMorph(tweenProp){ functions = { prepareStart, prepareProperty, onStart, crossCheck }
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { } */
KUTE[tweenProp] = function(elem,a,b,v){
let curve = [], path1 = a.curve, path2 = b.curve; // Component Functions
for(let i=0, l=path2.length; i<l; i++) { // each path command export function onStartCubicMorph(tweenProp) {
curve.push([path1[i][0]]); if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
for(var j=1,l2=path1[i].length;j<l2;j++) { // each command coordinate KUTE[tweenProp] = function updateMorph(elem, a, b, v) {
curve[i].push( (numbers(path1[i][j], path2[i][j], v) * 1000 >>0)/1000 ); const curve = [];
} const path1 = a.curve;
} const path2 = b.curve;
elem.setAttribute("d", v === 1 ? b.original : pathToString(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);
}
// Component Base }
const baseSvgCubicMorph = { elem.setAttribute('d', v === 1 ? b.original : pathToString(curve));
component: 'baseSVGCubicMorph', };
property: 'path', }
// defaultValue: [], }
Interpolate: {numbers,pathToString},
functions: {onStart:onStartCubicMorph} // Component Base
} const baseSvgCubicMorph = {
component: 'baseSVGCubicMorph',
export default 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 getStyleForProperty from '../process/getStyleForProperty.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import { onStartDraw } from './svgDrawBase.js';
import {onStartDraw} from './svgDrawBase.js'
/* svgDraw = {
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart } property: 'draw',
defaultValue,
// Component Util Interpolate: {numbers} },
function percent (v,l) { functions = { prepareStart, prepareProperty, onStart }
return parseFloat(v) / 100 * l } */
}
// Component Util
// http://stackoverflow.com/a/30376660 function percent(v, l) {
function getRectLength(el) { // returns the length of a Rect return (parseFloat(v) / 100) * l;
let w = el.getAttribute('width'), }
h = el.getAttribute('height');
return (w*2)+(h*2); // http://stackoverflow.com/a/30376660
} // returns the length of a Rect
function getRectLength(el) {
function getPolyLength(el) { const w = el.getAttribute('width');
// getPolygonLength / getPolylineLength - return the length of the Polygon / Polyline const h = el.getAttribute('height');
const points = el.getAttribute('points').split(' '); return (w * 2) + (h * 2);
}
let len = 0;
if (points.length > 1) { // getPolygonLength / getPolylineLength
const coord = p => { // returns the length of the Polygon / Polyline
const c = p.split(','); function getPolyLength(el) {
if (c.length != 2) { return; } // return undefined const points = el.getAttribute('points').split(' ');
if (isNaN(c[0]) || isNaN(c[1])) { return; }
return [parseFloat(c[0]), parseFloat(c[1])]; let len = 0;
}; if (points.length > 1) {
const coord = (p) => {
const dist = (c1, c2) => { const c = p.split(',');
if (c1 != undefined && c2 != undefined) { if (c.length !== 2) { return 0; } // return undefined
return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2); if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; }
} return [parseFloat(c[0]), parseFloat(c[1])];
return 0; };
};
const dist = (c1, c2) => {
if (points.length > 2) { if (c1 !== undefined && c2 !== undefined) {
for (let i=0; i<points.length-1; i++) { return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2);
len += dist(coord(points[i]), coord(points[i+1])); }
} return 0;
} };
len += el.tagName === 'polygon' ? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
} if (points.length > 2) {
return len; for (let i = 0; i < points.length - 1; i += 1) {
} len += dist(coord(points[i]), coord(points[i + 1]));
}
function getLineLength(el) { // return the length of the line }
const x1 = el.getAttribute('x1'); len += el.tagName === 'polygon'
const x2 = el.getAttribute('x2'); ? dist(coord(points[0]), coord(points[points.length - 1])) : 0;
const y1 = el.getAttribute('y1'); }
const y2 = el.getAttribute('y2'); return len;
return Math.sqrt((x2 - x1) ** 2+(y2 - y1) ** 2); }
}
// return the length of the line
function getCircleLength(el) { // return the length of the circle function getLineLength(el) {
const r = el.getAttribute('r'); const x1 = el.getAttribute('x1');
return 2 * Math.PI * r; const x2 = el.getAttribute('x2');
} const y1 = el.getAttribute('y1');
const y2 = el.getAttribute('y2');
function getEllipseLength(el) { // returns the length of an ellipse return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
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;
} // return the length of the circle
function getCircleLength(el) {
function getTotalLength(el) { // returns the result of any of the below functions const r = el.getAttribute('r');
if ('rect'===el.tagName) { return 2 * Math.PI * r;
return getRectLength(el); }
} else if ('circle'===el.tagName) {
return getCircleLength(el); // returns the length of an ellipse
} else if ('ellipse'===el.tagName) { function getEllipseLength(el) {
return getEllipseLength(el); const rx = el.getAttribute('rx');
} else if (['polygon','polyline'].indexOf(el.tagName)>-1) { const ry = el.getAttribute('ry');
return getPolyLength(el); const len = 2 * rx;
} else if ('line'===el.tagName) { const wid = 2 * ry;
return getLineLength(el); return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2;
} }
}
// returns the result of any of the below functions
function getDraw(e,v) { function getTotalLength(el) {
let length = /path|glyph/.test(e.tagName) ? e.getTotalLength() : getTotalLength(e), if (el.tagName === 'rect') {
start, end, d, o; return getRectLength(el);
} if (el.tagName === 'circle') {
if ( v instanceof Object ) { return getCircleLength(el);
return v; } if (el.tagName === 'ellipse') {
} else if (typeof v === 'string') { return getEllipseLength(el);
v = v.split(/\,|\s/); } if (['polygon', 'polyline'].includes(el.tagName)) {
start = /%/.test(v[0]) ? percent(v[0].trim(),length) : parseFloat(v[0]); return getPolyLength(el);
end = /%/.test(v[1]) ? percent(v[1].trim(),length) : parseFloat(v[1]); } if (el.tagName === 'line') {
} else if (typeof v === 'undefined') { return getLineLength(el);
o = parseFloat(getStyleForProperty(e,'stroke-dashoffset')); }
d = getStyleForProperty(e,'stroke-dasharray').split(/\,/); // ESLint
return 0;
start = 0-o; }
end = parseFloat(d[0]) + start || length;
} function getDraw(element, value) {
return { s: start, e: end, l: length }; const length = /path|glyph/.test(element.tagName)
} ? element.getTotalLength()
: getTotalLength(element);
function resetDraw(elem) { let start;
elem.style.strokeDashoffset = ``; let end;
elem.style.strokeDasharray = ``; let dasharray;
} let offset;
// Component Functions if (value instanceof Object) {
function getDrawValue(){ return value;
return getDraw(this.element); } if (typeof value === 'string') {
} const v = value.split(/,|\s/);
function prepareDraw(a,o){ start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]);
return getDraw(this.element,o); end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]);
} } else if (typeof value === 'undefined') {
offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset'));
// All Component Functions dasharray = getStyleForProperty(element, 'stroke-dasharray').split(',');
const svgDrawFunctions = {
prepareStart: getDrawValue, start = 0 - offset;
prepareProperty: prepareDraw, end = parseFloat(dasharray[0]) + start || length;
onStart: onStartDraw }
} return { s: start, e: end, l: length };
}
// Component Full
const svgDraw = { function resetDraw(elem) {
component: 'svgDraw', elem.style.strokeDashoffset = '';
property: 'draw', elem.style.strokeDasharray = '';
defaultValue: '0% 0%', }
Interpolate: {numbers},
functions: svgDrawFunctions, // Component Functions
// Export to global for faster execution function getDrawValue(/* prop, value */) {
Util: { return getDraw(this.element);
getRectLength, }
getPolyLength, function prepareDraw(a, o) {
getLineLength, return getDraw(this.element, o);
getCircleLength, }
getEllipseLength,
getTotalLength, // All Component Functions
resetDraw, const svgDrawFunctions = {
getDraw, prepareStart: getDrawValue,
percent prepareProperty: prepareDraw,
} onStart: onStartDraw,
} };
export default svgDraw // Component Full
const svgDraw = {
Components.SVGDraw = 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
// const svgDraw = { property : 'draw', defaultValue, Interpolate: {numbers} }, functions = { prepareStart, prepareProperty, onStart } /* svgDraw = {
property: 'draw',
// Component Functions defaultValue,
export function onStartDraw(tweenProp){ Interpolate: {numbers} },
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { functions = { prepareStart, prepareProperty, onStart }
KUTE[tweenProp] = (elem,a,b,v) => { } */
let pathLength = (a.l*100>>0)/100,
start = (numbers(a.s,b.s,v)*100>>0)/100, // Component Functions
end = (numbers(a.e,b.e,v)*100>>0)/100, export function onStartDraw(tweenProp) {
offset = 0 - start, if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) {
dashOne = end+offset; KUTE[tweenProp] = (elem, a, b, v) => {
const pathLength = (a.l * 100 >> 0) / 100;
elem.style.strokeDashoffset = `${offset}px`; const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100;
elem.style.strokeDasharray = `${((dashOne <1 ? 0 : dashOne)*100>>0)/100}px, ${pathLength}px`; const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100;
} const offset = 0 - start;
} const dashOne = end + offset;
}
elem.style.strokeDashoffset = `${offset}px`;
// Component Base elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`;
const baseSVGDraw = { };
component: 'baseSVGDraw', }
property: 'draw', }
Interpolate: {numbers},
functions: {onStart:onStartDraw} // Component Base
} const baseSVGDraw = {
component: 'baseSVGDraw',
export default baseSVGDraw property: 'draw',
Interpolate: { numbers },
functions: { onStart: onStartDraw },
};
export default baseSVGDraw;

View file

@ -1,267 +1,326 @@
import selector from '../util/selector.js' import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js';
import defaultOptions from '../objects/defaultOptions.js' import pathToString from 'svg-path-commander/src/convert/pathToString.js';
import Components from '../objects/components.js' import normalizePath from 'svg-path-commander/src/process/normalizePath.js';
import coords from '../interpolation/coords.js' import splitPath from 'svg-path-commander/src/process/splitPath.js';
import {onStartSVGMorph} from './svgMorphBase.js' import roundPath from 'svg-path-commander/src/process/roundPath.js';
import invalidPathValue from 'svg-path-commander/src/util/invalidPathValue.js';
import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js' import getPathLength from 'svg-path-commander/src/util/getPathLength.js';
import pathToString from 'svg-path-commander/src/convert/pathToString.js' import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength.js';
import normalizePath from 'svg-path-commander/src/process/normalizePath.js' import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js';
import splitPath from 'svg-path-commander/src/process/splitPath.js' import epsilon from 'svg-path-commander/src/math/epsilon.js';
import roundPath from 'svg-path-commander/src/process/roundPath.js' import midPoint from 'svg-path-commander/src/math/midPoint.js';
import invalidPathValue from 'svg-path-commander/src/util/invalidPathValue.js' import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js';
import getPathLength from 'svg-path-commander/src/util/getPathLength.js' import { onStartSVGMorph } from './svgMorphBase.js';
import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength.js' import coords from '../interpolation/coords.js';
import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js' import defaultOptions from '../objects/defaultOptions.js';
import epsilon from 'svg-path-commander/src/math/epsilon.js' import selector from '../util/selector.js';
import midPoint from 'svg-path-commander/src/math/midPoint.js'
import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js' /* SVGMorph = {
property: 'path',
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } defaultValue: [],
interpolators: {numbers,coords},
// Component Interpolation functions = { prepareStart, prepareProperty, onStart, crossCheck }
// function function(array1, array2, length, progress) } */
// Component Util // Component Interpolation
// original script flubber // function function(array1, array2, length, progress)
// https://github.com/veltman/flubber
// Component Util
function polygonLength(ring){ // original script flubber
return ring.reduce((length, point, i) => // https://github.com/veltman/flubber
i ? length + distanceSquareRoot(ring[i-1],point) : 0, 0 )
} function polygonLength(ring) {
return ring.reduce((length, point, i) => (i
function pathStringToRing(str, maxSegmentLength) { ? length + distanceSquareRoot(ring[i - 1], point)
let parsed = normalizePath(str,0) : 0), 0);
return exactRing(parsed) || approximateRing(parsed, maxSegmentLength); }
}
function exactRing(pathArray) { function exactRing(pathArray) {
let ring = [], const ring = [];
segment = [], pathCommand = '', const pathlen = pathArray.length;
pathlen = pathArray.length, let segment = [];
pathLength = 0; let pathCommand = '';
let pathLength = 0;
if (!pathArray.length || pathArray[0][0] !== "M") {
return false; if (!pathArray.length || pathArray[0][0] !== 'M') {
} return false;
}
for (let i = 0; i < pathlen; i++) {
segment = pathArray[i] for (let i = 0; i < pathlen; i += 1) {
pathCommand = segment[0] segment = pathArray[i];
[pathCommand] = segment;
if (pathCommand === "M" && i || pathCommand === "Z") {
break; // !! if ((pathCommand === 'M' && i) || pathCommand === 'Z') {
} else if ('ML'.indexOf( pathCommand) > -1) { break; // !!
ring.push([segment[1], segment[2]]); } else if ('ML'.indexOf(pathCommand) > -1) {
} else { ring.push([segment[1], segment[2]]);
return false; } else {
} return false;
} }
}
pathLength = polygonLength(ring)
pathLength = polygonLength(ring);
return pathlen ? { ring, pathLength } : false;
} return pathlen ? { ring, pathLength } : false;
}
function approximateRing(parsed, maxSegmentLength) {
let ringPath = splitPath(pathToString(parsed))[0], function approximateRing(parsed, maxSegmentLength) {
curvePath = pathToCurve(ringPath,4), const ringPath = splitPath(pathToString(parsed))[0];
pathLength = getPathLength(curvePath), const curvePath = pathToCurve(ringPath, 4);
ring = [], numPoints = 3, point; const pathLength = getPathLength(curvePath);
const ring = [];
if ( maxSegmentLength && !isNaN(maxSegmentLength) && +maxSegmentLength > 0 ) { let numPoints = 3;
numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength)); let point;
}
if (maxSegmentLength && !Number.isNaN(maxSegmentLength) && +maxSegmentLength > 0) {
for (let i = 0; i < numPoints; i++) { numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength));
point = getPointAtLength(curvePath,pathLength * i / numPoints) }
ring.push([point.x, point.y]);
} for (let i = 0; i < numPoints; i += 1) {
point = getPointAtLength(curvePath, (pathLength * i) / numPoints);
// Make all rings clockwise ring.push([point.x, point.y]);
if (!getDrawDirection(curvePath)) { }
ring.reverse();
} // Make all rings clockwise
if (!getDrawDirection(curvePath)) {
return { ring.reverse();
pathLength, }
ring,
skipBisect: true return {
}; pathLength,
} ring,
function rotateRing(ring, vs) { skipBisect: true,
let len = ring.length, min = Infinity, bestOffset, sumOfSquares, spliced; };
}
for (let offset = 0; offset < len; offset++) {
sumOfSquares = 0; function pathStringToRing(str, maxSegmentLength) {
const parsed = normalizePath(str, 0);
vs.forEach(function(p, i) { return exactRing(parsed) || approximateRing(parsed, maxSegmentLength);
let d = distanceSquareRoot(ring[(offset + i) % len], p); }
sumOfSquares += d * d;
}); function rotateRing(ring, vs) {
const len = ring.length;
if (sumOfSquares < min) { let min = Infinity;
min = sumOfSquares; let bestOffset;
bestOffset = offset; let sumOfSquares = 0;
} let spliced;
} let d;
let p;
if (bestOffset) {
spliced = ring.splice(0, bestOffset); for (let offset = 0; offset < len; offset += 1) {
ring.splice(ring.length, 0, ...spliced); sumOfSquares = 0;
}
} // vs.forEach((p, i) => {
function addPoints(ring, numPoints) { // const d = distanceSquareRoot(ring[(offset + i) % len], p);
let desiredLength = ring.length + numPoints, // sumOfSquares += d * d;
// step = ring.pathLength / numPoints; // });
step = polygonLength(ring) / numPoints; for (let i = 0; i < vs.length; i += 1) {
p = vs[i];
let i = 0, cursor = 0, insertAt = step / 2, a, b, segment; d = distanceSquareRoot(ring[(offset + i) % len], p);
sumOfSquares += d * d;
while (ring.length < desiredLength) { }
a = ring[i]
b = ring[(i + 1) % ring.length] if (sumOfSquares < min) {
// console.log(step,a,b) min = sumOfSquares;
segment = distanceSquareRoot(a, b) bestOffset = offset;
}
if (insertAt <= cursor + segment) { }
ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) );
insertAt += step; if (bestOffset) {
continue; spliced = ring.splice(0, bestOffset);
} ring.splice(ring.length, 0, ...spliced);
}
cursor += segment; }
i++;
} function addPoints(ring, numPoints) {
} const desiredLength = ring.length + numPoints;
function bisect(ring, maxSegmentLength = Infinity) { // const step = ring.pathLength / numPoints;
let a = [], b = [] const step = polygonLength(ring) / numPoints;
for (let i = 0; i < ring.length; i++) {
a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; let i = 0;
let cursor = 0;
// Could splice the whole set for a segment instead, but a bit messy let insertAt = step / 2;
while (distanceSquareRoot(a, b) > maxSegmentLength) { let a;
b = midPoint(a, b, 0.5); let b;
ring.splice(i + 1, 0, b); let segment;
}
} while (ring.length < desiredLength) {
} a = ring[i];
b = ring[(i + 1) % ring.length];
function normalizeRing(ring, maxSegmentLength) {
let points, skipBisect, pathLength; segment = distanceSquareRoot(a, b);
if (typeof ring === "string") { if (insertAt <= cursor + segment) {
let converted = pathStringToRing(ring, maxSegmentLength) ring.splice(i + 1, 0, segment
ring = converted.ring ? midPoint(a, b, (insertAt - cursor) / segment)
skipBisect = converted.skipBisect : a.slice(0));
pathLength = converted.pathLength insertAt += step;
} else if (!Array.isArray(ring)) { } else {
throw (invalidPathValue) cursor += segment;
} i += 1;
}
points = ring.slice(0) }
points.pathLength = pathLength }
if (!validRing(points)) { function bisect(ring, maxSegmentLength = Infinity) {
throw (invalidPathValue) let a = [];
} let b = [];
// TODO skip this test to avoid scale issues? for (let i = 0; i < ring.length; i += 1) {
// Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9 a = ring[i];
if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { b = i === ring.length - 1 ? ring[0] : ring[i + 1];
points.pop()
} // Could splice the whole set for a segment instead, but a bit messy
while (distanceSquareRoot(a, b) > maxSegmentLength) {
if ( !skipBisect && maxSegmentLength && !isNaN(maxSegmentLength) && (+maxSegmentLength) > 0 ) { b = midPoint(a, b, 0.5);
bisect(points, maxSegmentLength) ring.splice(i + 1, 0, b);
} }
}
return points }
}
function validRing(ring) { function validRing(ring) {
return Array.isArray(ring) && ring.every( point => return Array.isArray(ring)
Array.isArray(point) && point.length === 2 && !isNaN(point[0]) && !isNaN(point[1])) && ring.every((point) => Array.isArray(point)
} && point.length === 2
&& !Number.isNaN(point[0])
function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { && !Number.isNaN(point[1]));
morphPrecision = morphPrecision || defaultOptions.morphPrecision }
let fromRing = normalizeRing(pathArray1, morphPrecision),
toRing = normalizeRing(pathArray2, morphPrecision), function normalizeRing(input, maxSegmentLength) {
diff = fromRing.length - toRing.length; let skipBisect;
let pathLength;
addPoints(fromRing, diff < 0 ? diff * -1 : 0); let ring = input;
addPoints(toRing, diff > 0 ? diff : 0);
if (typeof (ring) === 'string') {
rotateRing(fromRing,toRing); const converted = pathStringToRing(ring, maxSegmentLength);
ring = converted.ring;
return [roundPath(fromRing),roundPath(toRing)] skipBisect = converted.skipBisect;
} pathLength = converted.pathLength;
} else if (!Array.isArray(ring)) {
throw Error(`${invalidPathValue}: ${ring}`);
// Component functions }
function getSVGMorph(tweenProp){
return this.element.getAttribute('d'); const points = ring.slice(0);
} points.pathLength = pathLength;
function prepareSVGMorph(tweenProp,value){
let pathObject = {}, elem = value instanceof SVGElement ? value : /^\.|^\#/.test(value) ? selector(value) : null, if (!validRing(points)) {
pathReg = new RegExp('\\n','ig'); // remove newlines, they brake JSON strings sometimes throw Error(`${invalidPathValue}: ${points}`);
}
// first make sure we return pre-processed values
if ( typeof(value) === 'object' && value.pathArray ) { // TODO skip this test to avoid scale issues?
return value; // Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9
} else if ( elem && /path|glyph/.test(elem.tagName) ) { if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) {
pathObject.original = elem.getAttribute('d').replace(pathReg,''); points.pop();
} else if ( !elem && typeof(value) === 'string' ) { // maybe it's a string path already }
pathObject.original = value.replace(pathReg,'');
} if (!skipBisect && maxSegmentLength
return pathObject; && !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) {
} bisect(points, maxSegmentLength);
function crossCheckSVGMorph(prop){ }
if ( this.valuesEnd[prop]){
let pathArray1 = this.valuesStart[prop].pathArray, return points;
pathArray2 = this.valuesEnd[prop].pathArray }
// skip already processed paths
// allow the component to work with pre-processed values function getInterpolationPoints(pathArray1, pathArray2, precision) {
if ( !pathArray1 || !pathArray2 || pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length ) { const morphPrecision = precision || defaultOptions.morphPrecision;
let p1 = this.valuesStart[prop].original, const fromRing = normalizeRing(pathArray1, morphPrecision);
p2 = this.valuesEnd[prop].original, const toRing = normalizeRing(pathArray2, morphPrecision);
// process morphPrecision const diff = fromRing.length - toRing.length;
morphPrecision = this._morphPrecision ? parseInt(this._morphPrecision) : defaultOptions.morphPrecision,
paths = getInterpolationPoints(p1,p2,morphPrecision); addPoints(fromRing, diff < 0 ? diff * -1 : 0);
this.valuesStart[prop].pathArray = paths[0]; addPoints(toRing, diff > 0 ? diff : 0);
this.valuesEnd[prop].pathArray = paths[1];
} rotateRing(fromRing, toRing);
}
} return [roundPath(fromRing), roundPath(toRing)];
}
// All Component Functions
const svgMorphFunctions = { // Component functions
prepareStart: getSVGMorph, function getSVGMorph(/* tweenProp */) {
prepareProperty: prepareSVGMorph, return this.element.getAttribute('d');
onStart: onStartSVGMorph, }
crossCheck: crossCheckSVGMorph
} function prepareSVGMorph(tweenProp, value) {
const pathObject = {};
// remove newlines, they brake JSON strings sometimes
// Component Full const pathReg = new RegExp('\\n', 'ig');
const svgMorph = { let elem = null;
component: 'svgMorph',
property: 'path', if (value instanceof SVGElement) {
defaultValue: [], elem = value;
Interpolate: coords, } else if (/^\.|^#/.test(value)) {
defaultOptions: {morphPrecision : 10, morphIndex:0}, elem = selector(value);
functions: svgMorphFunctions, }
// Export utils to global for faster execution
Util: { // first make sure we return pre-processed values
addPoints,bisect,normalizeRing,validRing, // component if (typeof (value) === 'object' && value.pathArray) {
getInterpolationPoints,pathStringToRing, return value;
distanceSquareRoot,midPoint, } if (elem && ['path', 'glyph'].includes(elem.tagName)) {
approximateRing,rotateRing, pathObject.original = elem.getAttribute('d').replace(pathReg, '');
pathToString,pathToCurve,// svg-path-commander // maybe it's a string path already
getPathLength,getPointAtLength,getDrawDirection,roundPath } else if (!elem && typeof (value) === 'string') {
} pathObject.original = value.replace(pathReg, '');
} }
export default svgMorph return pathObject;
}
Components.SVGMorph = svgMorph 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 KUTE from '../objects/kute.js';
import coords from '../interpolation/coords.js' import coords from '../interpolation/coords.js';
// const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } /* SVGMorph = {
property: 'path',
// Component functions defaultValue: [],
export function onStartSVGMorph(tweenProp){ interpolators: {numbers,coords} },
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { functions = { prepareStart, prepareProperty, onStart, crossCheck }
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 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
// Component Base len = path2.length;
const baseSVGMorph = { elem.setAttribute('d', (v === 1 ? b.original : `M${coords(path1, path2, len, v).join('L')}Z`));
component: 'baseSVGMorph', };
property: 'path', }
Interpolate: coords, }
functions: {onStart:onStartSVGMorph}
} // Component Base
const baseSVGMorph = {
export default 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 numbers from '../interpolation/numbers.js';
import Components from '../objects/components.js' import { svgTransformOnStart } from './svgTransformBase.js';
import {svgTransformOnStart} from './svgTransformBase.js'
/* const svgTransform = {
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions } property: 'svgTransform',
subProperties,
// Component Util defaultValue,
function parseStringOrigin (origin, {x, width}) { Interpolate: {numbers},
return /[a-z]/i.test(origin) && !/px/.test(origin) functions
? origin.replace(/top|left/,0).replace(/right|bottom/,100).replace(/center|middle/,50) } */
: /%/.test(origin) ? (x + parseFloat(origin) * width / 100) : parseFloat(origin);
} // Component Util
// helper function that turns transform value from string to object function parseStringOrigin(origin, { x, width }) {
function parseTransformString (a) { let result;
let d = a && /\)/.test(a) ? a.substring(0, a.length-1).split(/\)\s|\)/) : 'none', c = {}; if (/[a-z]/i.test(origin) && !/px/.test(origin)) {
result = origin.replace(/top|left/, 0)
if (d instanceof Array) { .replace(/right|bottom/, 100)
for (let j=0, jl = d.length; j<jl; j++){ .replace(/center|middle/, 50);
let p = d[j].trim().split('('); } else {
c[p[0]] = p[1]; result = /%/.test(origin) ? (x + (parseFloat(origin) * width) / 100) : parseFloat(origin);
} }
} return result;
return c; }
}
function parseTransformSVG (p,v){ // helper function that turns transform value from string to object
let svgTransformObject = {}; function parseTransformString(a) {
const c = {};
// by default the transformOrigin is "50% 50%" of the shape box const d = a && /\)/.test(a)
let bb = this.element.getBBox(); ? a.substring(0, a.length - 1).split(/\)\s|\)/)
let cx = bb.x + bb.width/2; : 'none';
let cy = bb.y + bb.height/2;
if (d instanceof Array) {
let origin = this._transformOrigin; for (let j = 0, jl = d.length; j < jl; j += 1) {
let translation; const [prop, val] = d[j].trim().split('(');
c[prop] = val;
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); return c;
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1],bb); }
svgTransformObject.origin = origin; function parseTransformSVG(p, v) {
const svgTransformObject = {};
for ( let i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){ // by default the transformOrigin is "50% 50%" of the shape box
svgTransformObject[i] = typeof v[i] === 'number' ? v[i] : v[i] instanceof Array ? v[i][0] : v[i].split(/\s/)[0]*1; const bb = this.element.getBBox();
} else if (i === 'translate'){ const cx = bb.x + bb.width / 2;
translation = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(',') : [v[i],0]; const cy = bb.y + bb.height / 2;
svgTransformObject[i] = [translation[0]*1||0, translation[1]*1||0];
} else if (/skew/.test(i)) { let origin = this._transformOrigin;
svgTransformObject[i] = v[i]*1||0; let translation;
} else if (i === 'scale'){
svgTransformObject[i] = parseFloat(v[i])||1; if (typeof (origin) !== 'undefined') {
} origin = origin instanceof Array ? origin : origin.split(/\s/);
} } else {
return svgTransformObject; origin = [cx, cy];
} }
// Component Functions origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0], bb);
function prepareSvgTransform(p,v){ origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1], bb);
return parseTransformSVG.call(this,p,v);
} svgTransformObject.origin = origin;
// returns an obect with current transform attribute value
function getStartSvgTransform (tweenProp,value) { // populate the valuesStart and / or valuesEnd
const transformObject = {}; Object.keys(v).forEach((i) => {
const currentTransform = parseTransformString(this.element.getAttribute('transform')); if (i === 'rotate') {
for (let j in value) { if (typeof v[i] === 'number') {
// find a value in current attribute value or add a default value svgTransformObject[i] = v[i];
transformObject[j] = j in currentTransform ? currentTransform[j] : (j==='scale'?1:0); } else if (v[i] instanceof Array) {
} [svgTransformObject[i]] = v[i];
return transformObject; } else {
} svgTransformObject[i] = v[i].split(/\s/)[0] * 1;
}
function svgTransformCrossCheck(prop) { } else if (i === 'translate') {
if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method if (v[i] instanceof Array) {
translation = v[i];
if ( this.valuesEnd[prop] ) { } else if (/,|\s/.test(v[i])) {
let valuesStart = this.valuesStart[prop]; translation = v[i].split(',');
let valuesEnd = this.valuesEnd[prop]; } else {
let currentTransform = parseTransformSVG.call(this, prop, parseTransformString(this.element.getAttribute('transform')) ); translation = [v[i], 0];
}
// populate the valuesStart first svgTransformObject[i] = [translation[0] * 1 || 0, translation[1] * 1 || 0];
for ( let tp in currentTransform ) { } else if (/skew/.test(i)) {
valuesStart[tp] = currentTransform[tp]; svgTransformObject[i] = v[i] * 1 || 0;
} } else if (i === 'scale') {
svgTransformObject[i] = parseFloat(v[i]) || 1;
// now try to determine the REAL translation }
const parentSVG = this.element.ownerSVGElement; });
const startMatrix = parentSVG.createSVGTransformFromMatrix(
parentSVG.createSVGMatrix() return svgTransformObject;
.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 // Component Functions
.translate(+valuesStart.origin[0],+valuesStart.origin[1]) // + origin function prepareSvgTransform(p, v) {
); return parseTransformSVG.call(this, p, v);
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) { // returns an obect with current transform attribute value
if ( !(s in valuesEnd) || s==='origin') { function getStartSvgTransform(tweenProp, value) {
valuesEnd[s] = valuesStart[s]; 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;
// All Component Functions transformObject[j] = j in currentTransform ? currentTransform[j] : scaleValue;
export const svgTransformFunctions = { });
prepareStart: getStartSvgTransform,
prepareProperty: prepareSvgTransform, return transformObject;
onStart: svgTransformOnStart, }
crossCheck: svgTransformCrossCheck
} function svgTransformCrossCheck(prop) {
if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method
// Component Full if (this.valuesEnd[prop]) {
export const svgTransform = { const valuesStart = this.valuesStart[prop];
component: 'svgTransformProperty', const valuesEnd = this.valuesEnd[prop];
property: 'svgTransform', const currentTransform = parseTransformSVG.call(this, prop,
// subProperties: ['translate','rotate','skewX','skewY','scale'], parseTransformString(this.element.getAttribute('transform')));
defaultOptions: {transformOrigin:'50% 50%'},
defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1}, // populate the valuesStart first
Interpolate: {numbers}, Object.keys(currentTransform).forEach((tp) => {
functions: svgTransformFunctions, valuesStart[tp] = currentTransform[tp];
});
// export utils to globals for faster execution
Util: { parseStringOrigin, parseTransformString, parseTransformSVG } // now try to determine the REAL translation
} const parentSVG = this.element.ownerSVGElement;
const startMatrix = parentSVG.createSVGTransformFromMatrix(
export default svgTransform parentSVG.createSVGMatrix()
.translate(-valuesStart.origin[0], -valuesStart.origin[1]) // - origin
Components.SVGTransformProperty = svgTransform .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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
// const svgTransform = { property : 'svgTransform', subProperties, defaultValue, Interpolate: {numbers}, functions } /* svgTransform = {
property: 'svgTransform',
// Component Functions subProperties,
export function svgTransformOnStart (tweenProp){ defaultValue,
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { Interpolate: {numbers},
KUTE[tweenProp] = (l, a, b, v) => { functions
let x = 0; } */
let y = 0;
let tmp; // Component Functions
const deg = Math.PI/180; export function svgTransformOnStart(tweenProp) {
const scale = 'scale' in b ? numbers(a.scale,b.scale,v) : 1; if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
const rotate = 'rotate' in b ? numbers(a.rotate,b.rotate,v) : 0; KUTE[tweenProp] = (l, a, b, v) => {
const sin = Math.sin(rotate*deg); let x = 0;
const cos = Math.cos(rotate*deg); let y = 0;
const skewX = 'skewX' in b ? numbers(a.skewX,b.skewX,v) : 0; const deg = Math.PI / 180;
const skewY = 'skewY' in b ? numbers(a.skewY,b.skewY,v) : 0; const scale = 'scale' in b ? numbers(a.scale, b.scale, v) : 1;
const complex = rotate||skewX||skewY||scale!==1 || 0; const rotate = 'rotate' in b ? numbers(a.rotate, b.rotate, v) : 0;
const sin = Math.sin(rotate * deg);
// start normalizing the translation, we start from last to first (from last chained translation) const cos = Math.cos(rotate * deg);
// the normalized translation will handle the transformOrigin tween option and makes sure to have a consistent transformation const skewX = 'skewX' in b ? numbers(a.skewX, b.skewX, v) : 0;
x -= complex ? b.origin[0] : 0;y -= complex ? b.origin[1] : 0; // we start with removing transformOrigin from translation const skewY = 'skewY' in b ? numbers(a.skewY, b.skewY, v) : 0;
x *= scale;y *= scale; // we now apply the scale const complex = rotate || skewX || skewY || scale !== 1 || 0;
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 // start normalizing the translation, we start from last to first
y = rotate ? sin*x + cos*y : y;x = rotate ? tmp : x; // (from last chained translation)
x += 'translate' in b ? numbers(a.translate[0],b.translate[0],v) : 0; // now we apply the actual translation // the normalized translation will handle the transformOrigin tween option
y += 'translate' in b ? numbers(a.translate[1],b.translate[1],v) : 0; // and makes sure to have a consistent transformation
x += complex ? b.origin[0] : 0;y += complex ? b.origin[1] : 0; // normalizing ends with the addition of the transformOrigin to the translation
// we start with removing transformOrigin from translation
// finally we apply the transform attribute value x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0;
l.setAttribute('transform', ( x||y ? (`translate(${(x*1000>>0)/1000}${y ? (`,${(y*1000>>0)/1000}`) : ''})`) : '' ) x *= scale; y *= scale; // we now apply the scale
+( rotate ? `rotate(${(rotate*1000>>0)/1000})` : '' ) // now we apply skews
+( skewX ? `skewX(${(skewX*1000>>0)/1000})` : '' ) y += skewY ? x * Math.tan(skewY * deg) : 0; x += skewX ? y * Math.tan(skewX * deg) : 0;
+( skewY ? `skewY(${(skewY*1000>>0)/1000})` : '' ) const cxsy = cos * x - sin * y; // apply rotation as well
+( scale !== 1 ? `scale(${(scale*1000>>0)/1000})` : '' ) ); 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
// Component Base x += complex ? b.origin[0] : 0; y += complex ? b.origin[1] : 0;
const baseSVGTransform = {
component: 'baseSVGTransform', // finally we apply the transform attribute value
property: 'svgTransform', l.setAttribute('transform', (x || y ? (`translate(${(x * 1000 >> 0) / 1000}${y ? (`,${(y * 1000 >> 0) / 1000}`) : ''})`) : '')
// subProperties: ['translate','rotate','skewX','skewY','scale'], + (rotate ? `rotate(${(rotate * 1000 >> 0) / 1000})` : '')
// defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1}, + (skewX ? `skewX(${(skewX * 1000 >> 0) / 1000})` : '')
defaultOptions: {transformOrigin:'50% 50%'}, + (skewY ? `skewY(${(skewY * 1000 >> 0) / 1000})` : '')
Interpolate: {numbers}, + (scale !== 1 ? `scale(${(scale * 1000 >> 0) / 1000})` : ''));
functions: {onStart:svgTransformOnStart} };
} }
}
export default baseSVGTransform
// 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 defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getStyleForProperty from '../process/getStyleForProperty.js';
import getStyleForProperty from '../process/getStyleForProperty.js' import trueDimension from '../util/trueDimension.js';
import trueDimension from '../util/trueDimension.js' import units from '../interpolation/units.js';
import units from '../interpolation/units.js' import { textPropOnStart } from './textPropertiesBase.js';
import {textPropOnStart} from './textPropertiesBase.js'
/* textProperties = {
// const textProperties = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} } category: 'textProperties',
defaultValues: [],
// Component Properties interpolators: {units}
const textProps = ['fontSize','lineHeight','letterSpacing','wordSpacing'] functions = { prepareStart, prepareProperty, onStart }
const textOnStart = {} } */
// Component Functions // Component Properties
textProps.forEach(tweenProp => { const textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
textOnStart[tweenProp] = textPropOnStart const textOnStart = {};
})
export function getTextProp(prop) { // Component Functions
return getStyleForProperty(this.element,prop) || defaultValues[prop]; textProps.forEach((tweenProp) => {
} textOnStart[tweenProp] = textPropOnStart;
export function prepareTextProp(prop,value) { });
return trueDimension(value);
} export function getTextProp(prop/* , value */) {
return getStyleForProperty(this.element, prop) || defaultValues[prop];
// All Component Functions }
const textPropFunctions = {
prepareStart: getTextProp, export function prepareTextProp(prop, value) {
prepareProperty: prepareTextProp, return trueDimension(value);
onStart: textOnStart }
}
// All Component Functions
// Component Full const textPropFunctions = {
const textProperties = { prepareStart: getTextProp,
component: 'textProperties', prepareProperty: prepareTextProp,
category: 'textProperties', onStart: textOnStart,
properties: textProps, };
defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units}, // Component Full
functions: textPropFunctions, const textProperties = {
Util: {trueDimension} component: 'textProperties',
} category: 'textProperties',
properties: textProps,
export default textProperties defaultValues: {
fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0,
Components.TextProperties = textProperties },
Interpolate: { units },
functions: textPropFunctions,
Util: { trueDimension },
};
export default textProperties;

View file

@ -1,31 +1,37 @@
import KUTE from '../objects/kute.js' import KUTE from '../objects/kute.js';
import units from '../interpolation/units.js' import units from '../interpolation/units.js';
// const opacity = { category : 'textProperties', defaultValues: [], interpolators: {units} }, functions = { prepareStart, prepareProperty, onStart:{} } /* textProperties = {
category: 'textProperties',
// Component Properties defaultValues: [],
const textProperties = ['fontSize','lineHeight','letterSpacing','wordSpacing'] interpolators: {units},
const textOnStart = {} functions = { prepareStart, prepareProperty, onStart:{}
} */
export function textPropOnStart(tweenProp){
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) { // Component Properties
KUTE[tweenProp] = (elem,a,b,v) => { const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
elem.style[tweenProp] = units(a.v,b.v,b.u,v); const textOnStart = {};
}
} export function textPropOnStart(tweenProp) {
} if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
textProperties.forEach(tweenProp => { KUTE[tweenProp] = (elem, a, b, v) => {
textOnStart[tweenProp] = textPropOnStart elem.style[tweenProp] = units(a.v, b.v, b.u, v);
}) };
}
// Component Base }
const baseTextProperties = {
component: 'baseTextProperties', textProperties.forEach((tweenProp) => {
category: 'textProps', textOnStart[tweenProp] = textPropOnStart;
// properties: textProperties, });
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units}, // Component Base
functions: {onStart:textOnStart} const baseTextProperties = {
} component: 'baseTextProperties',
category: 'textProps',
export default baseTextProperties // 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 connect from '../objects/connect.js';
import Components from '../objects/components.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js'
import { onStartWrite, charSet } from './textWriteBase.js';
import {onStartWrite,charSet} from './textWriteBase.js'
// Component Util
// Component Util // utility for multi-child targets
// utility for multi-child targets // wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class
// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class function wrapContentsSpan(el, classNAME) {
function wrapContentsSpan(el,classNAME){ let textWriteWrapper;
let textWriteWrapper; let newElem;
let newElem; if (typeof (el) === 'string') {
if ( typeof(el) === 'string' ) { newElem = document.createElement('SPAN');
newElem = document.createElement('SPAN') newElem.innerHTML = el;
newElem.innerHTML = el newElem.className = classNAME;
newElem.className = classNAME return newElem;
return newElem }
} else if (!el.children.length || el.children.length && el.children[0].className !== classNAME ) { if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) {
let elementInnerHTML = el.innerHTML const elementInnerHTML = el.innerHTML;
textWriteWrapper = document.createElement('SPAN') textWriteWrapper = document.createElement('SPAN');
textWriteWrapper.className = classNAME textWriteWrapper.className = classNAME;
textWriteWrapper.innerHTML = elementInnerHTML textWriteWrapper.innerHTML = elementInnerHTML;
el.appendChild(textWriteWrapper) el.appendChild(textWriteWrapper);
el.innerHTML = textWriteWrapper.outerHTML el.innerHTML = textWriteWrapper.outerHTML;
} else if (el.children.length && el.children[0].className === classNAME){ } else if (el.children.length && el.children[0].className === classNAME) {
textWriteWrapper = el.children[0] [textWriteWrapper] = el.children;
} }
return textWriteWrapper return textWriteWrapper;
} }
function getTextPartsArray(el,classNAME){ function getTextPartsArray(el, classNAME) {
let elementsArray = [] let elementsArray = [];
if (el.children.length) { const len = el.children.length;
let textParts = []; if (len) {
let remainingMarkup = el.innerHTML; const textParts = [];
let wrapperParts; let remainingMarkup = el.innerHTML;
let wrapperParts;
for ( let i=0, l = el.children.length, currentChild, childOuter, unTaggedContent; i<l; i++) {
for (let i = 0, currentChild, childOuter, unTaggedContent; i < len; i += 1) {
currentChild = el.children[i] currentChild = el.children[i];
childOuter = currentChild.outerHTML childOuter = currentChild.outerHTML;
wrapperParts = remainingMarkup.split(childOuter) wrapperParts = remainingMarkup.split(childOuter);
if (wrapperParts[0] !== '') { if (wrapperParts[0] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[0],classNAME) unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME);
textParts.push( unTaggedContent ) textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0],'') remainingMarkup = remainingMarkup.replace(wrapperParts[0], '');
} else if (wrapperParts[1] !== '') { } else if (wrapperParts[1] !== '') {
unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0],classNAME) unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME);
textParts.push( unTaggedContent ) textParts.push(unTaggedContent);
remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0],'') remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], '');
} }
!currentChild.classList.contains(classNAME) && currentChild.classList.add(classNAME) if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME);
textParts.push( currentChild ) textParts.push(currentChild);
remainingMarkup = remainingMarkup.replace(childOuter,'') remainingMarkup = remainingMarkup.replace(childOuter, '');
} }
if (remainingMarkup!==''){ if (remainingMarkup !== '') {
let unTaggedRemaining = wrapContentsSpan(remainingMarkup,classNAME) const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME);
textParts.push( unTaggedRemaining ) textParts.push(unTaggedRemaining);
} }
elementsArray = elementsArray.concat(textParts) elementsArray = elementsArray.concat(textParts);
} else { } else {
elementsArray = elementsArray.concat([wrapContentsSpan(el,classNAME)]) elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]);
} }
return elementsArray return elementsArray;
} }
function setSegments(target,newText){ function setSegments(target, newText) {
const oldTargetSegs = getTextPartsArray( target,'text-part'); const oldTargetSegs = getTextPartsArray(target, 'text-part');
const newTargetSegs = getTextPartsArray( wrapContentsSpan( newText ), 'text-part' ); const newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part');
target.innerHTML = '' target.innerHTML = '';
target.innerHTML += oldTargetSegs.map(s=>{ s.className += ' oldText'; return s.outerHTML }).join('') target.innerHTML += oldTargetSegs.map((s) => { s.className += ' oldText'; return s.outerHTML; }).join('');
target.innerHTML += newTargetSegs.map(s=>{ s.className += ' newText'; return s.outerHTML.replace(s.innerHTML,'') }).join('') target.innerHTML += newTargetSegs.map((s) => { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join('');
return [oldTargetSegs,newTargetSegs] return [oldTargetSegs, newTargetSegs];
} }
export function createTextTweens(target,newText,options){ export function createTextTweens(target, newText, ops) {
if (target.playing) return; if (target.playing) return false;
options = options || {} const options = ops || {};
options.duration = options.duration === 'auto' ? 'auto' : isFinite(options.duration*1) ? options.duration*1 : 1000; options.duration = 1000;
const segs = setSegments(target,newText); if (ops.duration === 'auto') {
const oldTargetSegs = segs[0]; options.duration = 'auto';
const newTargetSegs = segs[1]; } else if (Number.isFinite(ops.duration * 1)) {
let oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); options.duration = ops.duration * 1;
let newTargets = [].slice.call(target.getElementsByClassName('newText')); }
let textTween = [], totalDelay = 0 const TweenContructor = connect.tween;
const segs = setSegments(target, newText);
textTween = textTween.concat(oldTargets.map((el,i) => { const oldTargetSegs = segs[0];
options.duration = options.duration === 'auto' ? oldTargetSegs[i].innerHTML.length * 75 : options.duration; const newTargetSegs = segs[1];
options.delay = totalDelay; const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
options.onComplete = null const newTargets = [].slice.call(target.getElementsByClassName('newText'));
totalDelay += options.duration let textTween = [];
return new connect.tween(el, {text:el.innerHTML}, {text:''}, options ); let totalDelay = 0;
}));
textTween = textTween.concat(newTargets.map((el,i)=> { textTween = textTween.concat(oldTargets.map((el, i) => {
const onComplete = () => {target.innerHTML = newText, target.playing = false}; options.duration = options.duration === 'auto'
? oldTargetSegs[i].innerHTML.length * 75
options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; : options.duration;
options.delay = totalDelay; options.delay = totalDelay;
options.onComplete = i === newTargetSegs.length-1 ? onComplete : null options.onComplete = null;
totalDelay += options.duration
totalDelay += options.duration;
return new connect.tween(el, {text:''}, {text:newTargetSegs[i].innerHTML}, options ); return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options);
})); }));
textTween = textTween.concat(newTargets.map((el, i) => {
textTween.start = function(){ function onComplete() {
!target.playing && textTween.map(tw=>tw.start()) && (target.playing = true) target.innerHTML = newText;
} target.playing = false;
}
return textTween
} options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay;
// Component Functions options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null;
function getWrite(tweenProp,value){ totalDelay += options.duration;
return this.element.innerHTML;
} return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options);
function prepareText(tweenProp,value) { }));
if( tweenProp === 'number' ) {
return parseFloat(value) textTween.start = function startTweens() {
} else { if (!target.playing) {
// empty strings crash the update function textTween.forEach((tw) => tw.start());
return value === '' ? ' ' : value target.playing = true;
} }
} };
// All Component Functions return textTween;
export const textWriteFunctions = { }
prepareStart: getWrite,
prepareProperty: prepareText, // Component Functions
onStart: onStartWrite function getWrite(/* tweenProp, value */) {
} return this.element.innerHTML;
}
// const textWrite = { category : 'textWrite', defaultValues: {}, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart }
function prepareText(tweenProp, value) {
// Full Component if (tweenProp === 'number') {
export const textWrite = { return parseFloat(value);
component: 'textWriteProperties', }
category: 'textWrite', // empty strings crash the update function
properties: ['text','number'], return value === '' ? ' ' : value;
defaultValues: {text: ' ',numbers:'0'}, }
defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers}, // All Component Functions
functions: textWriteFunctions, export const textWriteFunctions = {
// export to global for faster execution prepareStart: getWrite,
Util: { charSet, createTextTweens } prepareProperty: prepareText,
} onStart: onStartWrite,
};
export default textWrite
/* textWrite = {
Components.TextWriteProperties = 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import defaultOptions from '../objects/defaultOptions.js' import defaultOptions from '../objects/defaultOptions.js';
// Component Values // Component Values
const lowerCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").split(""), // lowercase const lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase
upperCaseAlpha = String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""), // uppercase const upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase
nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?\=-").split(""), // symbols const nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols
numeric = String("0123456789").split(""), // numeric const numeric = String('0123456789').split(''); // numeric
alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha,numeric), // alpha numeric const alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric
allTypes = alphaNumeric.concat(nonAlpha); // all caracters const allTypes = alphaNumeric.concat(nonAlpha); // all caracters
const charSet = { const charSet = {
alpha: lowerCaseAlpha, // lowercase alpha: lowerCaseAlpha, // lowercase
upper: upperCaseAlpha, // uppercase upper: upperCaseAlpha, // uppercase
symbols: nonAlpha, // symbols symbols: nonAlpha, // symbols
numeric: numeric, numeric,
alphanumeric: alphaNumeric, alphanumeric: alphaNumeric,
all: allTypes, all: allTypes,
} };
export {charSet} export { charSet };
// Component Functions // Component Functions
export const onStartWrite = { export const onStartWrite = {
text: function(tweenProp){ text(tweenProp) {
if ( !KUTE[tweenProp] && this.valuesEnd[tweenProp] ) { if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) {
const chars = this._textChars;
let chars = this._textChars, let charsets = charSet[defaultOptions.textChars];
charsets = chars in charSet ? charSet[chars]
: chars && chars.length ? chars if (chars in charSet) {
: charSet[defaultOptions.textChars] charsets = charSet[chars];
} else if (chars && chars.length) {
KUTE[tweenProp] = function(elem,a,b,v) { charsets = chars;
}
let initialText = '',
endText = '', KUTE[tweenProp] = (elem, a, b, v) => {
firstLetterA = a.substring(0), let initialText = '';
firstLetterB = b.substring(0), let endText = '';
pointer = charsets[(Math.random() * charsets.length)>>0]; const finalText = b === '' ? ' ' : b;
const firstLetterA = a.substring(0);
if (a === ' ') { const firstLetterB = b.substring(0);
endText = firstLetterB.substring(Math.min(v * firstLetterB.length, firstLetterB.length)>>0, 0 ); const pointer = charsets[(Math.random() * charsets.length) >> 0];
elem.innerHTML = v < 1 ? ( ( endText + pointer ) ) : (b === '' ? ' ' : b);
} else if (b === ' ') { if (a === ' ') {
initialText = firstLetterA.substring(0, Math.min((1-v) * firstLetterA.length, firstLetterA.length)>>0 ); endText = firstLetterB
elem.innerHTML = v < 1 ? ( ( initialText + pointer ) ) : (b === '' ? ' ' : b); .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0);
} else { elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText;
initialText = firstLetterA.substring(firstLetterA.length, Math.min(v * firstLetterA.length, firstLetterA.length)>>0 ); } else if (b === ' ') {
endText = firstLetterB.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length)>>0 ); initialText = firstLetterA
elem.innerHTML = v < 1 ? ( (endText + pointer + initialText) ) : (b === '' ? ' ' : b); .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0);
} elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText;
} } else {
} initialText = firstLetterA
}, .substring(firstLetterA.length,
number: function(tweenProp) { Math.min(v * firstLetterA.length, firstLetterA.length) >> 0);
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0 endText = firstLetterB
KUTE[tweenProp] = (elem, a, b, v) => { .substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0);
elem.innerHTML = numbers(a, b, v)>>0; elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText;
} }
} };
} }
} },
number(tweenProp) {
// Base Component if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0
export const baseTextWrite = { KUTE[tweenProp] = (elem, a, b, v) => {
component: 'baseTextWrite', elem.innerHTML = numbers(a, b, v) >> 0;
category: 'textWrite', };
// properties: ['text','number'], }
// defaultValues: {text: ' ',numbers:'0'}, },
defaultOptions: { textChars: 'alpha' }, };
Interpolate: {numbers},
functions: {onStart:onStartWrite}, // Base Component
// export to global for faster execution export const baseTextWrite = {
Util: { charSet } component: 'baseTextWrite',
} category: 'textWrite',
// properties: ['text','number'],
export default baseTextWrite // 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 defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import getInlineStyle from '../process/getInlineStyle.js';
import getInlineStyle from '../process/getInlineStyle.js' import perspective from '../interpolation/perspective.js';
import perspective from '../interpolation/perspective.js' import translate3d from '../interpolation/translate3d.js';
import translate3d from '../interpolation/translate3d.js' import rotate3d from '../interpolation/rotate3d.js';
import rotate3d from '../interpolation/rotate3d.js' import translate from '../interpolation/translate.js';
import translate from '../interpolation/translate.js' import rotate from '../interpolation/rotate.js';
import rotate from '../interpolation/rotate.js' import scale from '../interpolation/scale.js';
import scale from '../interpolation/scale.js' import skew from '../interpolation/skew.js';
import skew from '../interpolation/skew.js' import { onStartTransform } from './transformFunctionsBase.js';
import {onStartTransform} from './transformFunctionsBase.js'
/* transformFunctions = {
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr property: 'transform',
// the component developed for modern browsers supporting non-prefixed transform subProperties,
defaultValues,
// Component Functions Interpolate: {translate,rotate,skew,scale},
function getTransform(tweenProperty,value){ functions } */
let currentStyle = getInlineStyle(this.element);
return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty]; // same to svg transform, attr
} // the component developed for modern browsers supporting non-prefixed transform
function prepareTransform(prop,obj){
let prepAxis = ['X', 'Y', 'Z'], // coordinates // Component Functions
transformObject = {}, function getTransform(tweenProperty/* , value */) {
translateArray = [], rotateArray = [], skewArray = [], const currentStyle = getInlineStyle(this.element);
arrayFunctions = ['translate3d','translate','rotate3d','skew'] return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty];
}
for (let x in obj) {
let pv = typeof obj[x] === 'object' && obj[x].length ? obj[x].map(v=>parseInt(v)) : parseInt(obj[x]); function prepareTransform(prop, obj) {
const prepAxis = ['X', 'Y', 'Z']; // coordinates
if (arrayFunctions.includes(x)) { const transformObject = {};
let propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x; const translateArray = []; const rotateArray = []; const skewArray = [];
const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew'];
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] ) Object.keys(obj).forEach((x) => {
: [pv[0]||0, pv[1]||0,pv[2]||0] // translate3d | rotate3d const pv = typeof obj[x] === 'object' && obj[x].length
? obj[x].map((v) => parseInt(v, 10))
} else if ( /[XYZ]/.test(x) ) { : parseInt(obj[x], 10);
let fn = x.replace(/[XYZ]/,''),
fnId = fn === 'skew' ? fn : `${fn}3d`, if (arrayFunctions.includes(x)) {
fnLen = fn === 'skew' ? 2 : 3, const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x;
fnArray = fn === 'translate' ? translateArray
: fn === 'rotate' ? rotateArray if (x === 'skew') {
: fn === 'skew' ? skewArray : {} transformObject[propId] = pv.length
for (let fnIndex = 0; fnIndex < fnLen; fnIndex++) { ? [pv[0] || 0, pv[1] || 0]
let fnAxis = prepAxis[fnIndex]; : [pv || 0, 0];
fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`]) : 0; } else if (x === 'translate') {
} transformObject[propId] = pv.length
transformObject[fnId] = fnArray; ? [pv[0] || 0, pv[1] || 0, pv[2] || 0]
} else if (x==='rotate') { // rotate : [pv || 0, 0, 0];
transformObject['rotate3d'] = [0,0,pv] } else { // translate3d | rotate3d
} else { // scale | perspective transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0];
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv }
} } else if (/[XYZ]/.test(x)) {
} const fn = x.replace(/[XYZ]/, '');
return transformObject; const fnId = fn === 'skew' ? fn : `${fn}3d`;
} const fnLen = fn === 'skew' ? 2 : 3;
let fnArray = [];
function crossCheckTransform(tweenProp){
if (this.valuesEnd[tweenProp]) { if (fn === 'translate') {
if ( this.valuesEnd[tweenProp] ) { fnArray = translateArray;
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){ } else if (fn === 'rotate') {
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective fnArray = rotateArray;
} } else if (fn === 'skew') {
} fnArray = skewArray;
} }
}
for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) {
// All Component Functions const fnAxis = prepAxis[fnIndex];
const transformFunctions = { fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0;
prepareStart: getTransform, }
prepareProperty: prepareTransform, transformObject[fnId] = fnArray;
onStart: onStartTransform, } else if (x === 'rotate') { // rotate
crossCheck: crossCheckTransform transformObject.rotate3d = [0, 0, pv];
} } else { // scale | perspective
transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv;
const supportedTransformProperties = [ }
'perspective', });
'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate', return transformObject;
'skewX', 'skewY', 'skew', }
'scale'
] function crossCheckTransform(tweenProp) {
if (this.valuesEnd[tweenProp]) {
const defaultTransformValues = { if (this.valuesEnd[tweenProp]) {
perspective: 400, if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
translate3d : [0,0,0], translateX : 0, translateY : 0, translateZ : 0, translate : [0,0], this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
rotate3d: [0,0,0], rotateX : 0, rotateY : 0, rotateZ : 0, rotate : 0, }
skewX : 0, skewY : 0, skew: [0,0], }
scale : 1 }
} }
// Full Component // All Component Functions
const transformFunctionsComponent = { const transformFunctions = {
component: 'transformFunctions', prepareStart: getTransform,
property: 'transform', prepareProperty: prepareTransform,
subProperties: supportedTransformProperties, onStart: onStartTransform,
defaultValues: defaultTransformValues, crossCheck: crossCheckTransform,
functions: transformFunctions, };
Interpolate: {
perspective: perspective, const supportedTransformProperties = [
translate3d: translate3d, 'perspective',
rotate3d: rotate3d, 'translate3d', 'translateX', 'translateY', 'translateZ', 'translate',
translate: translate, rotate: rotate, scale: scale, skew: skew 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate',
} 'skewX', 'skewY', 'skew',
} 'scale',
];
export default transformFunctionsComponent
const defaultTransformValues = {
Components.TransformFunctions = transformFunctionsComponent 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 KUTE from '../objects/kute.js';
import perspective from '../interpolation/perspective.js' import perspective from '../interpolation/perspective.js';
import translate3d from '../interpolation/translate3d.js' import translate3d from '../interpolation/translate3d.js';
import rotate3d from '../interpolation/rotate3d.js' import rotate3d from '../interpolation/rotate3d.js';
import translate from '../interpolation/translate.js' import translate from '../interpolation/translate.js';
import rotate from '../interpolation/rotate.js' import rotate from '../interpolation/rotate.js';
import scale from '../interpolation/scale.js' import scale from '../interpolation/scale.js';
import skew from '../interpolation/skew.js' import skew from '../interpolation/skew.js';
// const transformFunctions = { property : 'transform', subProperties, defaultValues, Interpolate: {translate,rotate,skew,scale}, functions } // same to svg transform, attr /* transformFunctions = {
property: 'transform',
// Component Functions subProperties,
export function onStartTransform(tweenProp){ defaultValues,
if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { Interpolate: {translate,rotate,skew,scale},
KUTE[tweenProp] = (elem, a, b, v) => { functions } */
elem.style[tweenProp] =
(a.perspective||b.perspective ? perspective(a.perspective,b.perspective,'px',v) : '') // one side might be 0 // same to svg transform, attr
+ (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] // Component Functions
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'') // array [x,y] export function onStartTransform(tweenProp) {
+ (a.scale||b.scale ? scale(a.scale,b.scale,v):'') // one side might be 0 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]
// Base Component + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y]
const BaseTransform = { + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0
component: 'baseTransform', };
property: 'transform', }
functions: {onStart: onStartTransform}, }
Interpolate: {
perspective: perspective, // Base Component
translate3d: translate3d, const BaseTransform = {
rotate3d: rotate3d, component: 'baseTransform',
translate: translate, rotate: rotate, scale: scale, skew: skew property: 'transform',
} functions: { onStart: onStartTransform },
} Interpolate: {
perspective,
export default BaseTransform translate3d,
rotate3d,
translate,
rotate,
scale,
skew,
},
};
export default BaseTransform;

View file

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

View file

@ -1,117 +1,154 @@
import defaultValues from '../objects/defaultValues.js' import defaultValues from '../objects/defaultValues.js';
import Components from '../objects/components.js' import numbers from '../interpolation/numbers.js';
import numbers from '../interpolation/numbers.js' import arrays from '../interpolation/arrays.js';
import arrays from '../interpolation/arrays.js' import { onStartTransform } from './transformMatrixBase.js';
import {onStartTransform} from './transformMatrixBase.js'
/* transformMatrix = {
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } property : 'transform',
defaultValue: {},
// Component name interpolators: {}
const matrixComponent = 'transformMatrix' functions = { prepareStart, prepareProperty, onStart, crossCheck }
} */
// Component Functions
function getTransform(tweenProp, value){ // Component name
let transformObject = {} const matrixComponent = 'transformMatrix';
if (this.element[matrixComponent]) { // Component Functions
const currentValue = this.element[matrixComponent] function getTransform(tweenProp, value) {
for (const vS in currentValue) { const transformObject = {};
transformObject[vS] = currentValue[vS] const currentValue = this.element[matrixComponent];
}
} else { if (currentValue) {
for (const vE in value){ Object.keys(currentValue).forEach((vS) => {
transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE] transformObject[vS] = currentValue[vS];
} });
} } else {
return transformObject Object.keys(value).forEach((vE) => {
} transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE];
function prepareTransform(tweenProp,value){ });
if ( typeof(value) === 'object' && !value.length) { }
let pv, return transformObject;
transformObject = {}, }
translate3dObj = {},
rotate3dObj = {}, function prepareTransform(tweenProp, value) {
scale3dObj = {}, if (typeof (value) === 'object' && !value.length) {
skewObj = {}, let pv;
axis = [{translate3d:translate3dObj},{rotate3d:rotate3dObj},{skew:skewObj},{scale3d:scale3dObj}]; const transformObject = {};
const translate3dObj = {};
for (const prop in value) { const rotate3dObj = {};
if ( /3d/.test(prop) && typeof(value[prop]) === 'object' && value[prop].length ){ const scale3dObj = {};
pv = value[prop].map( (v) => prop === 'scale3d' ? parseFloat(v) : parseInt(v) ) const skewObj = {};
transformObject[prop] = prop === 'scale3d' ? [pv[0]||1, pv[1]||1, pv[2]||1] : [pv[0]||0, pv[1]||0, pv[2]||0] const axis = [{ translate3d: translate3dObj },
} else if ( /[XYZ]/.test(prop) ) { { rotate3d: rotate3dObj },
let obj = /translate/.test(prop) ? translate3dObj { skew: skewObj },
: /rotate/.test(prop) ? rotate3dObj { scale3d: scale3dObj }];
: /scale/.test(prop) ? scale3dObj
: /skew/.test(prop) ? skewObj : {}; Object.keys(value).forEach((prop) => {
let idx = prop.replace(/translate|rotate|scale|skew/,'').toLowerCase() if (/3d/.test(prop) && typeof (value[prop]) === 'object' && value[prop].length) {
obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop]) pv = value[prop].map((v) => (prop === 'scale3d' ? parseFloat(v) : parseInt(v, 10)));
} else if ('skew' === prop ) { transformObject[prop] = prop === 'scale3d' ? [pv[0] || 1, pv[1] || 1, pv[2] || 1] : [pv[0] || 0, pv[1] || 0, pv[2] || 0];
pv = value[prop].map(v => parseInt(v)||0) } else if (/[XYZ]/.test(prop)) {
transformObject[prop] = [pv[0]||0, pv[1]||0] let obj = {};
} else { // perspective if (/translate/.test(prop)) {
transformObject[prop] = parseInt(value[prop]); obj = translate3dObj;
} } else if (/rotate/.test(prop)) {
} obj = rotate3dObj;
} else if (/scale/.test(prop)) {
axis.map((o) => { obj = scale3dObj;
let tp = Object.keys(o)[0], tv = o[tp] } else if (/skew/.test(prop)) {
if ( Object.keys(tv).length && !transformObject[tp]) { obj = skewObj;
transformObject[tp] = tp === 'scale3d' ? [tv.x || 1, tv.y || 1, tv.z || 1] }
: tp === 'skew' ? [tv.x || 0, tv.y || 0] const idx = prop.replace(/translate|rotate|scale|skew/, '').toLowerCase();
: [tv.x || 0, tv.y || 0, tv.z || 0]; // translate|rotate 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);
return transformObject; transformObject[prop] = [pv[0] || 0, pv[1] || 0];
} else { // string | array } else { // perspective
// if ( typeof (value) === 'object' && value.length ) { transformObject[prop] = parseInt(value[prop], 10);
// } else if ( typeof (value) === string && value.includes('matrix')) { }
// decompose matrix to object });
console.error(`KUTE.js - "${value}" is not valid/supported transform function`)
} axis.forEach((o) => {
} const tp = Object.keys(o)[0];
const tv = o[tp];
function onCompleteTransform(tweenProp){ if (Object.keys(tv).length && !transformObject[tp]) {
if (this.valuesEnd[tweenProp]) { if (tp === 'scale3d') {
this.element[matrixComponent] = {} transformObject[tp] = [tv.x || 1, tv.y || 1, tv.z || 1];
for (const tf in this.valuesEnd[tweenProp]){ } else if (tp === 'skew') {
this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf] transformObject[tp] = [tv.x || 0, tv.y || 0];
} } else { // translate | rotate
} transformObject[tp] = [tv.x || 0, tv.y || 0, tv.z || 0];
} }
function crossCheckTransform(tweenProp){ }
if (this.valuesEnd[tweenProp]) { });
if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective){ return transformObject;
this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective } // 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`);
// All Component Functions }
const matrixFunctions = {
prepareStart: getTransform, function onCompleteTransform(tweenProp) {
prepareProperty: prepareTransform, if (this.valuesEnd[tweenProp]) {
onStart: onStartTransform, this.element[matrixComponent] = {};
onComplete: onCompleteTransform, Object.keys(this.valuesEnd[tweenProp]).forEach((tf) => {
crossCheck: crossCheckTransform this.element[matrixComponent][tf] = this.valuesEnd[tweenProp][tf];
} });
}
// Component Full Object }
const matrixTransform = { function crossCheckTransform(tweenProp) {
component: matrixComponent, if (this.valuesEnd[tweenProp]) {
property: 'transform', if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) {
// subProperties: ['perspective','translate3d','translateX','translateY','translateZ','rotate3d','rotateX','rotateY','rotateZ','skew','skewX','skewY','scale3d','scaleX','scaleY','scaleZ'], this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective;
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, // All Component Functions
rotate3d: arrays, const matrixFunctions = {
skew: arrays, prepareStart: getTransform,
scale3d: arrays prepareProperty: prepareTransform,
} onStart: onStartTransform,
} onComplete: onCompleteTransform,
crossCheck: crossCheckTransform,
export default matrixTransform };
Components.TransformMatrix = matrixTransform // 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 KUTE from '../objects/kute.js';
import numbers from '../interpolation/numbers.js' import numbers from '../interpolation/numbers.js';
import arrays from '../interpolation/arrays.js' import arrays from '../interpolation/arrays.js';
// const transformMatrix = { property : 'transform', defaultValue: {}, interpolators: {} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } /* transformMatrix = {
property : 'transform',
// Component name defaultValue: {},
const matrixComponent = 'transformMatrixBase' interpolators: {},
functions = { prepareStart, prepareProperty, onStart, crossCheck }
// Component special } */
const CSS3Matrix = typeof(DOMMatrix) !== 'undefined' ? DOMMatrix
: typeof(WebKitCSSMatrix) !== 'undefined' ? WebKitCSSMatrix // Component name
: typeof(CSSMatrix) !== 'undefined' ? CSSMatrix const matrixComponent = 'transformMatrixBase';
: typeof(MSCSSMatrix) !== 'undefined' ? MSCSSMatrix
: null // Component special
// this component is restricted to modern browsers only
// Component Functions const CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null;
export const onStartTransform = {
transform : function(tweenProp) { // Component Functions
if (this.valuesEnd[tweenProp] && !KUTE[tweenProp]) { export const onStartTransform = {
transform(tweenProp) {
KUTE[tweenProp] = (elem, a, b, v) => { if (CSS3Matrix && this.valuesEnd[tweenProp] && !KUTE[tweenProp]) {
let matrix = new CSS3Matrix(), transformObject = {} KUTE[tweenProp] = (elem, a, b, v) => {
let matrix = new CSS3Matrix();
for ( const p in b ) { const tObject = {};
transformObject[p] = p === 'perspective' ? numbers(a[p],b[p],v) : arrays(a[p],b[p],v)
} Object.keys(b).forEach((p) => {
tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v);
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 // set perspective
if (transformObject.skew) { // set skew if (tObject.perspective) matrix.m34 = -1 / tObject.perspective;
matrix = transformObject.skew[0] ? matrix.skewX(transformObject.skew[0]) : matrix;
matrix = transformObject.skew[1] ? matrix.skewY(transformObject.skew[1]) : matrix; // set translate
} matrix = tObject.translate3d
matrix = transformObject.scale3d ? (matrix.scale(transformObject.scale3d[0],transformObject.scale3d[1],transformObject.scale3d[2])): matrix // set scale ? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2])
elem.style[tweenProp] = matrix.toString() // set element style : matrix;
}
} // set rotation
}, matrix = tObject.rotate3d
CSS3Matrix: function(prop) { ? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2])
if (this.valuesEnd.transform){ : matrix;
!KUTE[prop] && (KUTE[prop] = CSS3Matrix)
} // 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;
// Component Base Object }
export const baseMatrixTransform = {
component: matrixComponent, // set scale
property: 'transform', matrix = tObject.scale3d
functions: {onStart: onStartTransform}, ? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2])
Interpolate: { : matrix;
perspective: numbers,
translate3d: arrays, // set element style
rotate3d: arrays, elem.style[tweenProp] = matrix.toString();
skew: arrays, };
scale3d: arrays }
} },
} CSS3Matrix(prop) {
if (CSS3Matrix && this.valuesEnd.transform) {
export default baseMatrixTransform 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' import Tweens from '../objects/tweens.js';
export default (tw) => Tweens.push(tw)
export default (tw) => Tweens.push(tw);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,79 +1,132 @@
import connect from '../objects/connect.js' import connect from '../objects/connect.js';
// Robert Penner's Easing Functions // Robert Penner's Easing Functions
const Easing = { // updated for ESLint
linear : (t) => t, const Easing = {
easingSinusoidalIn : (t) => -Math.cos(t * Math.PI / 2) + 1, linear: (t) => t,
easingSinusoidalOut : (t) => Math.sin(t * Math.PI / 2), easingSinusoidalIn: (t) => -Math.cos((t * Math.PI) / 2) + 1,
easingSinusoidalInOut : (t) => -0.5 * (Math.cos(Math.PI * t) - 1), easingSinusoidalOut: (t) => Math.sin((t * Math.PI) / 2),
easingQuadraticIn : (t) => t*t, easingSinusoidalInOut: (t) => -0.5 * (Math.cos(Math.PI * t) - 1),
easingQuadraticOut : (t) => t*(2-t), easingQuadraticIn: (t) => t * t,
easingQuadraticInOut : (t) => t<.5 ? 2*t*t : -1+(4-2*t)*t, easingQuadraticOut: (t) => t * (2 - t),
easingCubicIn : (t) => t*t*t, easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
easingCubicOut : (t) => (--t)*t*t+1, easingCubicIn: (t) => t * t * t,
easingCubicInOut : (t) => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1, easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; },
easingQuarticIn : (t) => t*t*t*t, easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
easingQuarticOut : (t) => 1-(--t)*t*t*t, easingQuarticIn: (t) => t * t * t * t,
easingQuarticInOut : (t) => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t, easingQuarticOut: (t0) => { const t = t0 - 1; return 1 - t * t * t * t; },
easingQuinticIn : (t) => t*t*t*t*t, easingQuarticInOut: (t0) => {
easingQuinticOut : (t) => 1+(--t)*t*t*t*t, let t = t0;
easingQuinticInOut : (t) => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t, if (t < 0.5) return 8 * t * t * t * t;
easingCircularIn : (t) => -(Math.sqrt(1 - (t * t)) - 1), t -= 1; return 1 - 8 * t * t * t * t;
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), easingQuinticIn: (t) => t * t * t * t * t,
easingExponentialIn : (t) => 2 ** (10 * (t - 1)) - 0.001, easingQuinticOut: (t0) => { const t = t0 - 1; return 1 + t * t * t * t * t; },
easingExponentialOut : (t) => 1 - 2 ** (-10 * t), easingQuinticInOut: (t0) => {
easingExponentialInOut : (t) => (t *= 2) < 1 ? 0.5 * (2 ** (10 * (t - 1))) : 0.5 * (2 - 2 ** (-10 * (t - 1))), let t = t0;
easingBackIn : (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s) }, if (t < 0.5) return 16 * t * t * t * t * t;
easingBackOut : (t) => { const s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 }, t -= 1; return 1 + 16 * t * t * t * t * t;
easingBackInOut : (t) => { },
const s = 1.70158 * 1.525; easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1),
if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s)) easingCircularOut: (t0) => { const t = t0 - 1; return Math.sqrt(1 - t * t); },
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2) easingCircularInOut: (t0) => {
}, let t = t0 * 2;
easingElasticIn : (t) => { if (t < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1);
let s, _kea = 0.1, _kep = 0.4 t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1);
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 easingExponentialIn: (t) => 2 ** (10 * (t - 1)) - 0.001,
return - ( _kea * (2 ** (10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) ) easingExponentialOut: (t) => 1 - 2 ** (-10 * t),
}, easingExponentialInOut: (t0) => {
easingElasticOut : (t) => { const t = t0 * 2;
let s, _kea = 0.1, _kep = 0.4 if (t < 1) return 0.5 * (2 ** (10 * (t - 1)));
if ( t === 0 ) return 0;if ( t === 1 ) return 1 return 0.5 * (2 - 2 ** (-10 * (t - 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 easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); },
}, easingBackOut: (t0) => {
easingElasticInOut : (t) => { const s = 1.70158;
let s, _kea = 0.1, _kep = 0.4 const t = t0 - 1;
if ( t === 0 ) return 0;if ( t === 1 ) return 1 return t * t * ((s + 1) * t + s) + 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 ) ) easingBackInOut: (t0) => {
return _kea * (2 ** (-10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) * 0.5 + 1 const s = 1.70158 * 1.525;
}, let t = t0 * 2;
easingBounceIn : (t) => { return 1 - Easing.easingBounceOut( 1 - t ) }, if (t < 1) return 0.5 * (t * t * ((s + 1) * t - s));
easingBounceOut : (t) => { t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2);
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; } easingElasticIn: (t0) => {
else if ( t < ( 2.5 / 2.75 ) ) { return 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + 0.9375; } let s;
else {return 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + 0.984375; } let k1 = 0.1;
}, const k2 = 0.4;
easingBounceInOut : (t) => { let t = t0;
if ( t < 0.5 ) return Easing.easingBounceIn( t * 2 ) * 0.5; if (t === 0) return 0;
return Easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5 if (t === 1) return 1;
} if (!k1 || k1 < 1) {
} k1 = 1; s = k2 / 4;
} else {
function processEasing(fn) { s = ((k2 * Math.asin(1 / k1)) / Math.PI) * 2;
if ( typeof fn === 'function') { }
return fn; t -= 1;
} else if ( typeof Easing[fn] === 'function' ) { return -(k1 * (2 ** (10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2));
return Easing[fn]; // regular Robert Penner Easing Functions },
} else { easingElasticOut: (t) => {
return Easing.linear let s;
} let k1 = 0.1;
} const k2 = 0.4;
if (t === 0) return 0;
// Tween constructor needs to know who will process easing functions if (t === 1) return 1;
connect.processEasing = processEasing if (!k1 || k1 < 1) {
k1 = 1;
export default Easing 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 { version as Version } from '../package.json';
import Render from './core/render.js' import Render from './core/render.js';
import Interpolate from './objects/interpolate.js' import Interpolate from './objects/interpolate.js';
import Objects from './objects/objectsBase.js' import Objects from './objects/objectsBase.js';
import Util from './objects/util.js' import Util from './objects/util.js';
import Easing from './easing/easing-base.js' import Easing from './easing/easing-base.js';
import Internals from './core/internals.js' import Internals from './core/internals.js';
import Selector from './util/selector.js' import Selector from './util/selector.js';
import Animation from './animation/animationBase.js' import Animation from './animation/animationBase.js';
// TweenConstructor // TweenConstructor
import Tween from './tween/tweenBase.js' import Tween from './tween/tweenBase.js';
// Interface only fromTo // Interface only fromTo
import fromTo from './interface/fromTo.js' import fromTo from './interface/fromTo.js';
// import baseTransform from './components/transformFunctionsBase.js' // import baseTransform from './components/transformFunctionsBase.js'
import baseTransformMatrix from './components/transformMatrixBase.js' import baseTransformMatrix from './components/transformMatrixBase.js';
import baseBoxModel from './components/boxModelBase.js' import baseBoxModel from './components/boxModelBase.js';
import baseOpacity from './components/opacityPropertyBase.js' import baseOpacity from './components/opacityPropertyBase.js';
// import {baseCrossBrowserMove} from './components/crossBrowserMove.js' // import {baseCrossBrowserMove} from './components/crossBrowserMove.js'
// const Transform = new Animation(baseTransform) // const Transform = new Animation(baseTransform)
const Transform = new Animation(baseTransformMatrix) const Transform = new Animation(baseTransformMatrix);
const BoxModel = new Animation(baseBoxModel) const BoxModel = new Animation(baseBoxModel);
const Opacity = new Animation(baseOpacity) const Opacity = new Animation(baseOpacity);
// const Move = new Animation(baseCrossBrowserMove) // const Move = new Animation(baseCrossBrowserMove)
// support for kute-base.js ends here // support for kute-base.js ends here
export default { export default {
Animation, Animation,
Components: { Components: {
Transform, Transform,
BoxModel, BoxModel,
Opacity, Opacity,
// Move // Move
}, },
Tween, Tween,
fromTo, fromTo,
Objects, Objects,
Easing, Easing,
Util, Util,
Render, Render,
Interpolate, Interpolate,
Internals, Internals,
Selector, Selector,
Version Version,
} };

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,13 +1,23 @@
import numbers from './numbers.js' import numbers from './numbers.js';
export default function(a, b, v) { export default function colors(a, b, v) {
let _c = {}, const _c = {};
c, const ep = ')';
ep = ')', const cm = ',';
cm =',', const rgb = 'rgb(';
rgb = 'rgb(', const rgba = 'rgba(';
rgba = 'rgba(';
Object.keys(b).forEach((c) => {
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; } // _c[c] = c !== 'a' ? (numbers(a[c], b[c], v) >> 0 || 0) : (a[c] && b[c])
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; // ? (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) { export default function coords(a, b, l, v) {
const points = []; const points = [];
for(let i=0;i<l;i++) { // for each point for (let i = 0; i < l; i += 1) { // for each point
points[i] = []; points[i] = [];
for(let j=0;j<2;j++) { // each point coordinate 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 ); points[i].push(((a[i][j] + (b[i][j] - a[i][j]) * v) * 1000 >> 0) / 1000);
} }
} }
return points; return points;
} }

View file

@ -1,3 +1,6 @@
export default function(a, b, v) { // number1, number2, progress export default function numbers(a, b, v) { // number1, number2, progress
a = +a; b -= a; return a + b * v; 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) { export default function perspective(a, b, u, v) {
return `perspective(${((a + (b - a) * v) * 1000 >> 0 ) / 1000}${u})` return `perspective(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,6 @@
export default function(a, b, u, v) { // number1, number2, unit, progress export default function units(a, b, u, v) { // number1, number2, unit, progress
a = +a; b -= a; return ( a + b * v ) + u; 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, // checks for differences between the processed start and end values,
// can be set to make sure start unit and end unit are same, // can be set to make sure start unit and end unit are same,
// stack transforms, process SVG paths, // stack transforms, process SVG paths,
// any type of post processing the component needs // any type of post processing the component needs
export default {} export default {};

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