* 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

55
dist/polyfill.js vendored
View file

@ -1,6 +1,6 @@
/*! /*!
* 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";
@ -21,7 +21,8 @@ if (!Array.from) {
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) {
return function from(arrayLike/*, mapFn, thisArg */) {
var C = this, items = Object(arrayLike); var C = this, items = Object(arrayLike);
if (arrayLike == null) { if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined'); throw new TypeError('Array.from requires an array-like object - not null or undefined');
@ -31,12 +32,14 @@ if (!Array.from) {
if (!isCallable(mapFn)) { if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function'); throw new TypeError('Array.from: when provided, the second argument must be a function');
} }
if (arguments.length > 2) { if (arguments.length > 2) {
T = arguments[2]; T = arguments[2];
} }
} }
var len = toLength(items.length); var len = toLength(items.length);
var A = isCallable(C) ? Object(new C(len)) : new Array(len); var A = isCallable(C) ? Object(new C(len)) : new Array(len);
var k = 0; var k = 0;
var kValue; var kValue;
while (k < len) { while (k < len) {
@ -54,8 +57,30 @@ if (!Array.from) {
}()); }());
} }
// https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat () {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);
return depth ? Array.prototype.reduce.call(this, function (acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}
return acc;
}, []) : Array.prototype.slice.call(this);
},
writable: true
});
}
if (!Array.prototype.includes) { if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement ) { Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
var O = Object(this); var O = Object(this);
var len = parseInt(O.length) || 0; var len = parseInt(O.length) || 0;
if (len === 0) { if (len === 0) {
@ -91,3 +116,25 @@ if (!String.prototype.includes) {
return this.indexOf(search, start) !== -1; 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,14 +1,14 @@
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
@ -16,101 +16,120 @@ import Interpolate from '../objects/interpolate.js'
// * 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
const ComponentName = Component.component
// const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = { prepareProperty, prepareStart, onStart, onComplete, crossCheck }
const Category = Component.category
const Property = Component.property
const Length = Component.properties && Component.properties.length || Component.subProperties && Component.subProperties.length
// {property,defaultvalue,defaultOptions,Interpolate,functions} // single property setComponent(Component) {
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions} // category colors, boxModel, borderRadius const propertyInfo = this;
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg transform, filter const ComponentName = Component.component;
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} // property with multiple sub properties. Eg attr // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util }
const Functions = {
prepareProperty, prepareStart, onStart, onComplete, crossCheck,
};
const Category = Component.category;
const Property = Component.property;
const Length = (Component.properties && Component.properties.length)
|| (Component.subProperties && Component.subProperties.length);
// single property
// {property,defaultvalue,defaultOptions,Interpolate,functions}
// category colors, boxModel, borderRadius
// {category,properties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg transform, filter
// {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// property with multiple sub properties. Eg htmlAttributes
// {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions}
// set supported category/property // set supported category/property
supportedProperties[ComponentName] = Component.properties || Component.subProperties || Component.property supportedProperties[ComponentName] = Component.properties
|| Component.subProperties || Component.property;
// set defaultValues // set defaultValues
if ('defaultValue' in Component){ // value 0 will invalidate if ('defaultValue' in Component) { // value 0 will invalidate
defaultValues[ Property ] = Component.defaultValue defaultValues[Property] = Component.defaultValue;
// minimal info // minimal info
propertyInfo.supports = `${Property} property` propertyInfo.supports = `${Property} property`;
} else if (Component.defaultValues) { } else if (Component.defaultValues) {
for (const dv in Component.defaultValues) { Object.keys(Component.defaultValues).forEach((dv) => {
defaultValues[dv] = Component.defaultValues[dv] defaultValues[dv] = Component.defaultValues[dv];
} });
// minimal info // minimal info
propertyInfo.supports = `${Length||Property} ${Property||Category} properties` propertyInfo.supports = `${Length || Property} ${Property || Category} properties`;
} }
// set additional options // set additional options
if (Component.defaultOptions) { if (Component.defaultOptions) {
for (const op in Component.defaultOptions) { Object.keys(Component.defaultOptions).forEach((op) => {
defaultOptions[op] = Component.defaultOptions[op] defaultOptions[op] = Component.defaultOptions[op];
} });
} }
// set functions // set functions
if (Component.functions) { if (Component.functions) {
for (const fn in Functions) { Object.keys(Functions).forEach((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][ Category||Property ] && (Functions[fn][ Category||Property ] = Component.functions[fn]) // if (!Functions[fn][ Category||Property ]) {
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {}) // Functions[fn][ Category||Property ] = Component.functions[fn];
!Functions[fn][ComponentName][ Category||Property ] && (Functions[fn][ComponentName][ Category||Property ] = Component.functions[fn]) // }
} else { if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
for ( const ofn in Component.functions[fn] ){ if (!Functions[fn][ComponentName][Category || Property]) {
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn]) Functions[fn][ComponentName][Category || Property] = Component.functions[fn];
!Functions[fn][ComponentName] && (Functions[fn][ComponentName] = {})
!Functions[fn][ComponentName][ofn] && (Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn])
} }
} else {
Object.keys(Component.functions[fn]).forEach((ofn) => {
// !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn])
if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {};
if (!Functions[fn][ComponentName][ofn]) {
Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn];
}
});
} }
} }
} });
} }
// set component interpolate // set component interpolate
if (Component.Interpolate) { if (Component.Interpolate) {
for (const fni in Component.Interpolate) { Object.keys(Component.Interpolate).forEach((fni) => {
const compIntObj = Component.Interpolate[fni] const 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 ( const sfn in compIntObj ) { Object.keys(compIntObj).forEach((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 // set component util
if (Component.Util) { if (Component.Util) {
for (const fnu in Component.Util){ Object.keys(Component.Util).forEach((fnu) => {
!Util[fnu] && (Util[fnu] = Component.Util[fnu]) if (!Util[fnu]) Util[fnu] = Component.Util[fnu];
} });
} }
return propertyInfo return propertyInfo;
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -1,27 +1,34 @@
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'
// const borderRadius = { category : 'borderRadius', properties : [..], defaultValues: {..}, interpolation: {units} } /* borderRadius = {
category: 'borderRadius',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties // Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'] const radiusProps = ['borderRadius',
const radiusValues = {} 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
radiusProps.map(x => radiusValues[x] = 0); const radiusValues = {};
radiusProps.forEach((x) => { radiusValues[x] = 0; });
// Component Functions // Component Functions
const radiusOnStart = {} const radiusOnStart = {};
radiusProps.forEach(tweenProp => { radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn radiusOnStart[tweenProp] = radiusOnStartFn;
}); });
export function getRadius(tweenProp){
return getStyleForProperty(this.element,tweenProp) || defaultValues[tweenProp]; export function getRadius(tweenProp) {
return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp];
} }
export function prepareRadius(tweenProp,value){
export function prepareRadius(tweenProp, value) {
return trueDimension(value); return trueDimension(value);
} }
@ -29,8 +36,8 @@ export function prepareRadius(tweenProp,value){
export const radiusFunctions = { export const radiusFunctions = {
prepareStart: getRadius, prepareStart: getRadius,
prepareProperty: prepareRadius, prepareProperty: prepareRadius,
onStart: radiusOnStart onStart: radiusOnStart,
} };
// Full Component // Full Component
const BorderRadius = { const BorderRadius = {
@ -38,11 +45,9 @@ const BorderRadius = {
category: 'borderRadius', category: 'borderRadius',
properties: radiusProps, properties: radiusProps,
defaultValues: radiusValues, defaultValues: radiusValues,
Interpolate: {units}, Interpolate: { units },
functions: radiusFunctions, functions: radiusFunctions,
Util: {trueDimension} Util: { trueDimension },
} };
export default BorderRadius export default BorderRadius;
Components.BorderRadiusProperties = 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',
properties : [..],
defaultValues: {..},
interpolation: {units}
} */
// Component Properties // Component Properties
const radiusProps = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'] const radiusProps = ['borderRadius',
'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'];
// Component Functions // Component Functions
export function radiusOnStartFn(tweenProp){ export function radiusOnStartFn(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] = units(a.v,b.v,b.u,v); elem.style[tweenProp] = units(a.v, b.v, b.u, v);
} };
} }
} }
const radiusOnStart = {} const radiusOnStart = {};
radiusProps.forEach(tweenProp => { radiusProps.forEach((tweenProp) => {
radiusOnStart[tweenProp] = radiusOnStartFn radiusOnStart[tweenProp] = radiusOnStartFn;
}); });
// Base Component // Base Component
const baseBorderRadius = { const baseBorderRadius = {
component: 'baseBorderRadius', component: 'baseBorderRadius',
category: 'borderRadius', category: 'borderRadius',
Interpolate: {units}, Interpolate: { units },
functions: {onStart: radiusOnStart} functions: { onStart: radiusOnStart },
} };
export default baseBorderRadius export default baseBorderRadius;

View file

@ -1,35 +1,36 @@
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 = {}
boxModelProperties.map(x => boxModelValues[x] = 0); const boxModelValues = {};
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 = {} const boxPropsOnStart = {};
boxModelProperties.map(x => boxPropsOnStart[x] = boxModelOnStart ); boxModelProperties.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; });
// All Component Functions // All Component Functions
const boxModelFunctions = { const boxModelFunctions = {
prepareStart: getBoxModel, prepareStart: getBoxModel,
prepareProperty: prepareBoxModel, prepareProperty: prepareBoxModel,
onStart: boxPropsOnStart onStart: boxPropsOnStart,
} };
// Component Full Component // Component Full Component
const boxModel = { const boxModel = {
@ -37,10 +38,8 @@ const boxModel = {
category: 'boxModel', category: 'boxModel',
properties: boxModelProperties, properties: boxModelProperties,
defaultValues: boxModelValues, defaultValues: boxModelValues,
Interpolate: {numbers}, Interpolate: { numbers },
functions: boxModelFunctions 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 // Component Base Props
const baseBoxProps = ['top','left','width','height'] const baseBoxProps = ['top', 'left', 'width', 'height'];
const baseBoxOnStart = {} const baseBoxOnStart = {};
baseBoxProps.map(x=>baseBoxOnStart[x] = boxModelOnStart) baseBoxProps.forEach((x) => { baseBoxOnStart[x] = boxModelOnStart; });
// Component Base // Component Base
const baseBoxModel = { const baseBoxModel = {
component: 'baseBoxModel', component: 'baseBoxModel',
category: 'boxModel', category: 'boxModel',
properties: baseBoxProps, properties: baseBoxProps,
Interpolate: {numbers}, Interpolate: { numbers },
functions: {onStart: baseBoxOnStart} functions: { onStart: baseBoxOnStart },
} };
export default baseBoxModel export default baseBoxModel;

View file

@ -1,32 +1,34 @@
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 // 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);
return boxValue.u === '%' ? boxValue.v * this.element[offsetProp] / 100 : boxValue.v; const offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth';
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 = {top:0,left:0,width:0,height:0} const essentialBoxPropsValues = {
const essentialBoxOnStart = {} top: 0, left: 0, width: 0, height: 0,
essentialBoxProps.map(x=>essentialBoxOnStart[x] = boxModelOnStart) };
const essentialBoxOnStart = {};
essentialBoxProps.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; });
// All Component Functions // All Component Functions
const essentialBoxModelFunctions = { const essentialBoxModelFunctions = {
prepareStart: getBoxModel, prepareStart: getBoxModel,
prepareProperty: prepareBoxModel, prepareProperty: prepareBoxModel,
onStart: essentialBoxOnStart onStart: essentialBoxOnStart,
} };
// Component Essential // Component Essential
const essentialBoxModel = { const essentialBoxModel = {
@ -34,11 +36,9 @@ const essentialBoxModel = {
category: 'boxModel', category: 'boxModel',
properties: essentialBoxProps, properties: essentialBoxProps,
defaultValues: essentialBoxPropsValues, defaultValues: essentialBoxPropsValues,
Interpolate: {numbers}, Interpolate: { numbers },
functions: essentialBoxModelFunctions, functions: essentialBoxModelFunctions,
Util:{trueDimension} Util: { trueDimension },
} };
export default essentialBoxModel export default essentialBoxModel;
Components.BoxModelEssential = 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,v){ function getClip(tweenProp/* , value */) {
const currentClip = getStyleForProperty(this.element,tweenProp), const currentClip = getStyleForProperty(this.element, tweenProp);
width = getStyleForProperty(this.element,'width'), const width = getStyleForProperty(this.element, 'width');
height = getStyleForProperty(this.element,'height'); const 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 [ trueDimension(value[0]), trueDimension(value[1]), trueDimension(value[2]), trueDimension(value[3]) ]; return value.map((x) => trueDimension(x));
} else {
var clipValue = value.replace(/rect|\(|\)/g,'');
clipValue = /\,/g.test(clipValue) ? clipValue.split(/\,/g) : clipValue.split(/\s/g);
return [ trueDimension(clipValue[0]), trueDimension(clipValue[1]), trueDimension(clipValue[2]), trueDimension(clipValue[3]) ];
} }
let clipValue = value.replace(/rect|\(|\)/g, '');
clipValue = /,/g.test(clipValue) ? clipValue.split(',') : clipValue.split(/\s/);
return clipValue.map((x) => trueDimension(x));
} }
// All Component Functions // All Component Functions
const clipFunctions = { const clipFunctions = {
prepareStart: getClip, prepareStart: getClip,
prepareProperty: prepareClip, prepareProperty: prepareClip,
onStart: onStartClip onStart: onStartClip,
} };
// Component Full // Component Full
const clipProperty = { const clipProperty = {
component: 'clipProperty', component: 'clipProperty',
property: 'clip', property: 'clip',
defaultValue: [0,0,0,0], defaultValue: [0, 0, 0, 0],
Interpolate: {numbers}, Interpolate: { numbers },
functions: clipFunctions, functions: clipFunctions,
Util: {trueDimension} Util: { trueDimension },
} };
export default clipProperty export default clipProperty;
Components.ClipProperty = clipProperty

View file

@ -1,17 +1,19 @@
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';
cl[h] = ((numbers(c1, c2, v) * 100 >> 0) / 100) + cu;
} }
elem.style.clip = `rect(${cl})`; elem.style.clip = `rect(${cl})`;
} };
} }
} }
@ -20,8 +22,8 @@ const baseClip = {
component: 'baseClip', component: 'baseClip',
property: 'clip', property: 'clip',
// defaultValue: [0,0,0,0], // defaultValue: [0,0,0,0],
Interpolate: {numbers}, Interpolate: { numbers },
functions: {onStart:onStartClip} functions: { onStart: onStartClip },
} };
export default baseClip export default baseClip;

View file

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

View file

@ -1,26 +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';
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', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'] const supportedColors = ['color', 'backgroundColor', 'borderColor',
'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 // Component Base
export const baseColors = { export const baseColors = {
@ -28,8 +29,8 @@ export const baseColors = {
category: 'colors', category: 'colors',
// properties: supportedColors, // properties: supportedColors,
// defaultValues: defaultColors, // defaultValues: defaultColors,
Interpolate: {numbers,colors}, Interpolate: { numbers, colors },
functions: {onStart:colorsOnStart} functions: { onStart: colorsOnStart },
} };
export default baseColors export default baseColors;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,21 +1,26 @@
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',
defaultValue,
Interpolate: {numbers} },
functions = { prepareStart, prepareProperty, onStart }
} */
// Component Functions // Component Functions
export function onStartDraw(tweenProp){ export function onStartDraw(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) => {
let pathLength = (a.l*100>>0)/100, const pathLength = (a.l * 100 >> 0) / 100;
start = (numbers(a.s,b.s,v)*100>>0)/100, const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100;
end = (numbers(a.e,b.e,v)*100>>0)/100, const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100;
offset = 0 - start, const offset = 0 - start;
dashOne = end+offset; const dashOne = end + offset;
elem.style.strokeDashoffset = `${offset}px`; elem.style.strokeDashoffset = `${offset}px`;
elem.style.strokeDasharray = `${((dashOne <1 ? 0 : dashOne)*100>>0)/100}px, ${pathLength}px`; elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`;
} };
} }
} }
@ -23,8 +28,8 @@ export function onStartDraw(tweenProp){
const baseSVGDraw = { const baseSVGDraw = {
component: 'baseSVGDraw', component: 'baseSVGDraw',
property: 'draw', property: 'draw',
Interpolate: {numbers}, Interpolate: { numbers },
functions: {onStart:onStartDraw} functions: { onStart: onStartDraw },
} };
export default baseSVGDraw export default baseSVGDraw;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,22 +1,28 @@
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',
defaultValues: [],
interpolators: {units},
functions = { prepareStart, prepareProperty, onStart:{}
} */
// Component Properties // Component Properties
const textProperties = ['fontSize','lineHeight','letterSpacing','wordSpacing'] const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing'];
const textOnStart = {} const textOnStart = {};
export function textPropOnStart(tweenProp){ export function textPropOnStart(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] = units(a.v,b.v,b.u,v); elem.style[tweenProp] = units(a.v, b.v, b.u, v);
} };
} }
} }
textProperties.forEach(tweenProp => {
textOnStart[tweenProp] = textPropOnStart textProperties.forEach((tweenProp) => {
}) textOnStart[tweenProp] = textPropOnStart;
});
// Component Base // Component Base
const baseTextProperties = { const baseTextProperties = {
@ -24,8 +30,8 @@ const baseTextProperties = {
category: 'textProps', category: 'textProps',
// properties: textProperties, // properties: textProperties,
// defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0}, // defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},
Interpolate: {units}, Interpolate: { units },
functions: {onStart:textOnStart} functions: { onStart: textOnStart },
} };
export default baseTextProperties 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 ) {
let elementInnerHTML = el.innerHTML
textWriteWrapper = document.createElement('SPAN')
textWriteWrapper.className = classNAME
textWriteWrapper.innerHTML = elementInnerHTML
el.appendChild(textWriteWrapper)
el.innerHTML = textWriteWrapper.outerHTML
} else if (el.children.length && el.children[0].className === classNAME){
textWriteWrapper = el.children[0]
} }
return textWriteWrapper if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) {
const elementInnerHTML = el.innerHTML;
textWriteWrapper = document.createElement('SPAN');
textWriteWrapper.className = classNAME;
textWriteWrapper.innerHTML = elementInnerHTML;
el.appendChild(textWriteWrapper);
el.innerHTML = textWriteWrapper.outerHTML;
} else if (el.children.length && el.children[0].className === classNAME) {
[textWriteWrapper] = el.children;
}
return textWriteWrapper;
} }
function getTextPartsArray(el,classNAME){ function getTextPartsArray(el, classNAME) {
let elementsArray = [] let elementsArray = [];
if (el.children.length) { const len = el.children.length;
let textParts = []; if (len) {
const textParts = [];
let remainingMarkup = el.innerHTML; let remainingMarkup = el.innerHTML;
let wrapperParts; 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') {
options.duration = 'auto';
} else if (Number.isFinite(ops.duration * 1)) {
options.duration = ops.duration * 1;
}
const TweenContructor = connect.tween;
const segs = setSegments(target, newText);
const oldTargetSegs = segs[0]; const oldTargetSegs = segs[0];
const newTargetSegs = segs[1]; const newTargetSegs = segs[1];
let oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse();
let newTargets = [].slice.call(target.getElementsByClassName('newText')); const newTargets = [].slice.call(target.getElementsByClassName('newText'));
let textTween = [], totalDelay = 0 let textTween = [];
let totalDelay = 0;
textTween = textTween.concat(oldTargets.map((el,i) => { textTween = textTween.concat(oldTargets.map((el, i) => {
options.duration = options.duration === 'auto' ? oldTargetSegs[i].innerHTML.length * 75 : options.duration; options.duration = options.duration === 'auto'
? oldTargetSegs[i].innerHTML.length * 75
: options.duration;
options.delay = totalDelay; options.delay = totalDelay;
options.onComplete = null options.onComplete = null;
totalDelay += options.duration totalDelay += options.duration;
return new connect.tween(el, {text:el.innerHTML}, {text:''}, options ); return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options);
})); }));
textTween = textTween.concat(newTargets.map((el,i)=> { textTween = textTween.concat(newTargets.map((el, i) => {
const onComplete = () => {target.innerHTML = newText, target.playing = false}; function onComplete() {
target.innerHTML = newText;
target.playing = false;
}
options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration;
options.delay = totalDelay; options.delay = totalDelay;
options.onComplete = i === newTargetSegs.length-1 ? onComplete : null options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null;
totalDelay += options.duration totalDelay += options.duration;
return new connect.tween(el, {text:''}, {text:newTargetSegs[i].innerHTML}, options ); return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options);
})); }));
textTween.start = function(){ textTween.start = function startTweens() {
!target.playing && textTween.map(tw=>tw.start()) && (target.playing = true) if (!target.playing) {
} textTween.forEach((tw) => tw.start());
target.playing = true;
}
};
return textTween return textTween;
} }
// Component Functions // Component Functions
function getWrite(tweenProp,value){ function getWrite(/* tweenProp, value */) {
return this.element.innerHTML; return this.element.innerHTML;
} }
function prepareText(tweenProp,value) {
if( tweenProp === 'number' ) { function prepareText(tweenProp, value) {
return parseFloat(value) if (tweenProp === 'number') {
} else { return parseFloat(value);
// empty strings crash the update function
return value === '' ? ' ' : value
} }
// empty strings crash the update function
return value === '' ? ' ' : value;
} }
// All Component Functions // All Component Functions
export const textWriteFunctions = { export const textWriteFunctions = {
prepareStart: getWrite, prepareStart: getWrite,
prepareProperty: prepareText, prepareProperty: prepareText,
onStart: onStartWrite onStart: onStartWrite,
} };
// const textWrite = { category : 'textWrite', defaultValues: {}, interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart } /* textWrite = {
category: 'textWrite',
defaultValues: {},
interpolators: {numbers},
functions = { prepareStart, prepareProperty, onStart }
} */
// Full Component // Full Component
export const textWrite = { export const textWrite = {
component: 'textWriteProperties', component: 'textWriteProperties',
category: 'textWrite', category: 'textWrite',
properties: ['text','number'], properties: ['text', 'number'],
defaultValues: {text: ' ',numbers:'0'}, defaultValues: { text: ' ', numbers: '0' },
defaultOptions: { textChars: 'alpha' }, defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers}, Interpolate: { numbers },
functions: textWriteFunctions, functions: textWriteFunctions,
// export to global for faster execution // export to global for faster execution
Util: { charSet, createTextTweens } Util: { charSet, createTextTweens },
} };
export default textWrite export default textWrite;
Components.TextWriteProperties = textWrite

View file

@ -1,66 +1,74 @@
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 charsets = charSet[defaultOptions.textChars];
let chars = this._textChars, if (chars in charSet) {
charsets = chars in charSet ? charSet[chars] charsets = charSet[chars];
: chars && chars.length ? chars } else if (chars && chars.length) {
: charSet[defaultOptions.textChars] charsets = chars;
}
KUTE[tweenProp] = function(elem,a,b,v) { KUTE[tweenProp] = (elem, a, b, v) => {
let initialText = '';
let initialText = '', let endText = '';
endText = '', const finalText = b === '' ? ' ' : b;
firstLetterA = a.substring(0), const firstLetterA = a.substring(0);
firstLetterB = b.substring(0), const firstLetterB = b.substring(0);
pointer = charsets[(Math.random() * charsets.length)>>0]; const pointer = charsets[(Math.random() * charsets.length) >> 0];
if (a === ' ') { if (a === ' ') {
endText = firstLetterB.substring(Math.min(v * firstLetterB.length, firstLetterB.length)>>0, 0 ); endText = firstLetterB
elem.innerHTML = v < 1 ? ( ( endText + pointer ) ) : (b === '' ? ' ' : b); .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0);
elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText;
} else if (b === ' ') { } else if (b === ' ') {
initialText = firstLetterA.substring(0, Math.min((1-v) * firstLetterA.length, firstLetterA.length)>>0 ); initialText = firstLetterA
elem.innerHTML = v < 1 ? ( ( initialText + pointer ) ) : (b === '' ? ' ' : b); .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0);
elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText;
} else { } else {
initialText = firstLetterA.substring(firstLetterA.length, Math.min(v * firstLetterA.length, firstLetterA.length)>>0 ); initialText = firstLetterA
endText = firstLetterB.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length)>>0 ); .substring(firstLetterA.length,
elem.innerHTML = v < 1 ? ( (endText + pointer + initialText) ) : (b === '' ? ' ' : b); Math.min(v * firstLetterA.length, firstLetterA.length) >> 0);
endText = firstLetterB
.substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0);
elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText;
} }
} };
} }
}, },
number: function(tweenProp) { number(tweenProp) {
if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0 if (tweenProp in this.valuesEnd && !KUTE[tweenProp]) { // numbers can be 0
KUTE[tweenProp] = (elem, a, b, v) => { KUTE[tweenProp] = (elem, a, b, v) => {
elem.innerHTML = numbers(a, b, v)>>0; elem.innerHTML = numbers(a, b, v) >> 0;
} };
} }
} },
} };
// Base Component // Base Component
export const baseTextWrite = { export const baseTextWrite = {
@ -69,10 +77,10 @@ export const baseTextWrite = {
// properties: ['text','number'], // properties: ['text','number'],
// defaultValues: {text: ' ',numbers:'0'}, // defaultValues: {text: ' ',numbers:'0'},
defaultOptions: { textChars: 'alpha' }, defaultOptions: { textChars: 'alpha' },
Interpolate: {numbers}, Interpolate: { numbers },
functions: {onStart:onStartWrite}, functions: { onStart: onStartWrite },
// export to global for faster execution // export to global for faster execution
Util: { charSet } Util: { charSet },
} };
export default baseTextWrite export default baseTextWrite;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,6 @@
import Tweens from '../objects/tweens.js' import Tweens from '../objects/tweens.js';
export default (tw) => { export default (tw) => {
let i = Tweens.indexOf(tw) const i = Tweens.indexOf(tw);
i !== -1 && Tweens.splice(i, 1) 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,31 +1,28 @@
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 || {};
Time.now = that.performance.now.bind(that.performance);
const Time = {} let Tick = 0;
Time.now = self.performance.now.bind(self.performance) export { Tick };
// export {Time}
let Tick = 0 const Ticker = (time) => {
export {Tick}
let Ticker = (time) => {
let i = 0; let 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);
} };
export {Ticker} export { Ticker };
// stop requesting animation frame // stop requesting animation frame
export function stop() { export function stop() {
@ -33,29 +30,33 @@ export function stop() {
if (!Tweens.length && Tick) { if (!Tweens.length && Tick) {
cancelAnimationFrame(Tick); cancelAnimationFrame(Tick);
Tick = null; Tick = null;
for (let obj in onStart) { Object.keys(onStart).forEach((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 (let prop in onStart[obj]) { Object.keys(onStart[obj]).forEach((prop) => {
KUTE[prop] && (delete KUTE[prop]) if (KUTE[prop]) delete KUTE[prop];
} });
} }
} });
for (let i in Interpolate) {
KUTE[i] && (delete KUTE[i]) Object.keys(Interpolate).forEach((i) => {
} if (KUTE[i]) delete KUTE[i];
});
} }
},64) }, 64);
} }
// KUTE.js render update functions // KUTE.js render update functions
// =============================== // ===============================
const Render = {Tick,Ticker,Tweens,Time} const Render = {
for ( const blob in Render ) { Tick, Ticker, Tweens, Time,
};
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
// updated for ESLint
const Easing = { const Easing = {
linear : (t) => t, linear: (t) => t,
easingQuadraticIn : (t) => t*t, easingQuadraticIn: (t) => t * t,
easingQuadraticOut : (t) => t*(2-t), easingQuadraticOut: (t) => t * (2 - t),
easingQuadraticInOut : (t) => t<.5 ? 2*t*t : -1+(4-2*t)*t, easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
easingCubicIn : (t) => t*t*t, easingCubicIn: (t) => t * t * t,
easingCubicOut : (t) => (--t)*t*t+1, easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; },
easingCubicInOut : (t) => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1, easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
easingCircularIn : (t) => -(Math.sqrt(1 - (t * t)) - 1), easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1),
easingCircularOut : (t) => Math.sqrt(1 - (t = t - 1) * t), easingCircularOut: (t0) => { const t = t0 - 1; Math.sqrt(1 - t * t); },
easingCircularInOut : (t) => ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1), easingCircularInOut: (t0) => {
easingBackIn : (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s) }, let t = t0 * 2;
easingBackOut : (t) => { const s = 1.70158; return --t * t * ((s + 1) * t + s) + 1 }, if (t < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1);
easingBackInOut : (t) => { t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1);
},
easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); },
easingBackOut: (t0) => {
const s = 1.70158;
const t = t0 - 1;
return t * t * ((s + 1) * t + s) + 1;
},
easingBackInOut: (t0) => {
const s = 1.70158 * 1.525; const s = 1.70158 * 1.525;
if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s)) let 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]; // regular Robert Penner Easing Functions return Easing[fn]; // regular Robert Penner Easing Functions
} else {
return Easing.linear
} }
return Easing.linear;
} }
connect.processEasing = processEasing connect.processEasing = processEasing;
export default Easing export default Easing;

View file

@ -1,57 +1,56 @@
import connect from '../objects/connect.js' import CubicBezier from 'cubic-bezier-easing';
import CubicBezier from 'cubic-bezier-easing' import connect from '../objects/connect.js';
const Easing = { 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) ) {
console.warn(`KUTE.js - CubicBezier doesn't support ${fn} easing.`)
}
return Easing.linear
} }
// if (/elastic|bounce/i.test(fn)) {
// throw TypeError(`KUTE.js - CubicBezier doesn't support ${fn} easing.`);
// }
return Easing.linear;
} }
connect.processEasing = processBezierEasing connect.processEasing = processBezierEasing;
export default Easing export default Easing;

View file

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

View file

@ -1,29 +1,29 @@
import {version as Version} from './../package.json' import { 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
@ -46,5 +46,5 @@ export default {
Interpolate, Interpolate,
Internals, Internals,
Selector, Selector,
Version Version,
} };

View file

@ -1,49 +1,67 @@
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';
for (let component in Components) { const Components = {
let compOps = Components[component] BackgroundPosition,
Components[component] = new Animation(compOps) BorderRadius,
} BoxModel,
ClipProperty,
ColorProperties,
FilterEffects,
HTMLAttributes,
OpacityProperty,
SVGDraw,
SVGCubicMorph,
SVGTransform,
ScrollProperty,
ShadowProperties,
TextProperties,
TextWriteProperties,
MatrixTransform,
};
Object.keys(Components).forEach((component) => {
const compOps = Components[component];
Components[component] = new Animation(compOps);
});
export default { export default {
Animation, Animation,
@ -69,5 +87,5 @@ export default {
Process, Process,
Internals, Internals,
Selector, Selector,
Version Version,
} };

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

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

View file

@ -1,52 +1,51 @@
import {version as Version} from './../package.json' import 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 {default as Animation} from './animation/animationDevelopment.js' import Animation from './animation/animation.js';
import Animation from './animation/animation.js'
// components // components
// import EssentialBoxModel from './components/boxModelEssential.js' import EssentialBoxModel from './components/boxModelEssential.js';
// import ColorsProperties from './components/colorProperties.js' import ColorsProperties from './components/colorProperties.js';
// 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 TextWrite from './components/textWrite.js' import TextWrite from './components/textWrite.js';
// import TransformFunctions from './components/transformFunctions.js' import TransformFunctions from './components/transformFunctions.js';
// // import TransformFunctions from './components/transformLegacy.js' import SVGDraw from './components/svgDraw.js';
// import SVGDraw from './components/svgDraw.js' import SVGMorph from './components/svgMorph.js';
// import SVGMorph from './components/svgMorph.js'
import './components/boxModelEssential.js' const Components = {
import './components/colorProperties.js' EssentialBoxModel,
import './components/htmlAttributes.js' ColorsProperties,
import './components/opacityProperty.js' HTMLAttributes,
import './components/textWrite.js' OpacityProperty,
import './components/transformFunctions.js' TextWrite,
// import './components/transformLegacy.js' TransformFunctions,
import './components/svgDraw.js' SVGDraw,
import './components/svgMorph.js' SVGMorph,
};
// init components // init components
for (let component in Components) { Object.keys(Components).forEach((component) => {
let compOps = Components[component] const compOps = Components[component];
Components[component] = new Animation(compOps) Components[component] = new Animation(compOps);
} });
export default { export default {
Animation, Animation,
@ -71,5 +70,5 @@ export default {
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(';
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; } Object.keys(b).forEach((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; // _c[c] = c !== 'a' ? (numbers(a[c], b[c], v) >> 0 || 0) : (a[c] && b[c])
// ? (numbers(a[c], b[c], v) * 100 >> 0) / 100 : null;
if (c !== 'a') {
_c[c] = numbers(a[c], b[c], v) >> 0 || 0;
} else if (a[c] && b[c]) {
_c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100;
}
});
return !_c.a
? rgb + _c.r + cm + _c.g + cm + _c.b + ep
: rgba + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep;
} }

View file

@ -1,9 +1,9 @@
export default function(a, b, l, v) { export default function coords(a, b, l, v) {
const points = []; 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

@ -2,4 +2,4 @@
// 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