diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 31039dd..0000000 --- a/.eslintrc +++ /dev/null @@ -1,41 +0,0 @@ -{ - "extends": [ - // Extend the airbnb eslint config - "airbnb-base" - // Vue - // "plugin:vue/vue3-recommended" - ], - // "parser": "vue-eslint-parser", - // "parser": "eslint-plugin-vue", - "parserOptions": { - "sourceType": "module" - }, - // ESLint will not look in parent folders for eslint configs - "root": false, - // An environment defines global variables that are predefined. - "env": { - "browser": true, - "es6": true, - "node": true - }, - // Rule overrides - "rules": { - // Disable no-restricted-globals for global objects - "no-restricted-globals": 0, - // Disable no-params-reassign for properties - // "no-param-reassign": ["error", { "props": false }], - // Allow strict mode (we are not dealing with modules) - // "strict": [0], - // Allow use of "private methods" - impossible to satisfy - "no-underscore-dangle": 0 - // Disable alert rule till we have a CE in place - // "no-alert": 0 - // Allow extensions on imports - // "import/extensions": 0, - // Allow exporting mutable 'let' binding - // "import/no-mutable-exports": 0, - // Allow no named as default / member - // "import/no-named-as-default": 0, - // "import/no-named-as-default-member": 0 - } -} diff --git a/.gitignore b/.gitignore index b6d5063..68b9e27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ node_modules/ -experiments/ -.npmignore -package-lock.json \ No newline at end of file +bower_components/ diff --git a/.npmignore b/.npmignore deleted file mode 100644 index de05e63..0000000 --- a/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -demo/ -experiments/ -package-lock.json -.gitignore \ No newline at end of file diff --git a/ES6-kute.js b/ES6-kute.js new file mode 100644 index 0000000..77be8ac --- /dev/null +++ b/ES6-kute.js @@ -0,0 +1,837 @@ +/* KUTE.js - The Light Tweening Engine + * by dnp_theme + * Licensed under MIT-License + */ +(((root, factory) => { + if (typeof define === 'function' && define.amd) { + define([], factory); // AMD. Register as an anonymous module. + } else if (typeof exports == 'object') { + module.exports = factory(); // Node, not strict CommonJS + } else { + root.KUTE = factory(); + } +})(this, () => { + // set a custom scope for KUTE.js + const g = typeof global !== 'undefined' ? global : window; // tick must be null!! + + const time = g.performance; + let tweens = []; + let tick = null; + + //supported properties + const // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0) + _colors = ['color', 'backgroundColor']; //all properties default values + + const // dimensions / box model + _boxModel = ['top', 'left', 'width', 'height']; + + const // transform + _transform = ['translate3d', 'translateX', 'translateY', 'translateZ', 'rotate', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scale']; + + const //scroll, it has no default value, it's calculated on tween start + _scroll = ['scroll']; + + const // opacity + _opacity = ['opacity']; + + const _all = _colors.concat( _opacity, _boxModel, _transform); + const al = _all.length; + const _defaults = {}; + + //populate default values object + for ( let i=0; i { + //returns browser prefix + let div = document.createElement('div'); + + var i = 0; + const pf = ['Moz', 'moz', 'Webkit', 'webkit', 'O', 'o', 'Ms', 'ms']; + const s = ['MozTransform', 'mozTransform', 'WebkitTransform', 'webkitTransform', 'OTransform', 'oTransform', 'MsTransform', 'msTransform']; + for (const i = 0, pl = pf.length; i < pl; i++) { if (s[i] in div.style) { return pf[i]; } } + div = null; + }; + + const property = p => { // returns prefixed property | property + const r = (!(p in document.body.style)) ? true : false, f = getPrefix(); // is prefix required for property | prefix + return r ? f + (p.charAt(0).toUpperCase() + p.slice(1)) : p; + }; + + const selector = (el, multi) => { // a public selector utility + let nl; + if (multi){ + nl = el instanceof Object || typeof el === 'object' ? el : document.querySelectorAll(el); + } else { + nl = typeof el === 'object' ? el + : /^#/.test(el) ? document.getElementById(el.replace('#','')) : document.querySelector(el); + } + if (nl === null && el !== 'window') throw new TypeError(`Element not found or incorrect selector: ${el}`); + return nl; + }; + + const radToDeg = a => a*180/Math.PI; + + const trueDimension = (d, p) => { + //true dimension returns { v = value, u = unit } + const x = parseInt(d) || 0; + + const mu = ['px','%','deg','rad','em','rem','vh','vw']; + let y; + for (let i=0, l = mu.length; i { // replace transparent and transform any color to rgba()/rgb() + if (/rgb|rgba/.test(v)) { // first check if it's a rgb string + const vrgb = v.replace(/\s|\)/,'').split('(')[1].split(','), y = vrgb[3] ? vrgb[3] : null; + if (!y) { + return { r: parseInt(vrgb[0]), g: parseInt(vrgb[1]), b: parseInt(vrgb[2]) }; + } else { + return { r: parseInt(vrgb[0]), g: parseInt(vrgb[1]), b: parseInt(vrgb[2]), a: parseFloat(y) }; + } + } else if (/^#/.test(v)) { + const fromHex = hexToRGB(v); return { r: fromHex.r, g: fromHex.g, b: fromHex.b }; + } else if (/transparent|none|initial|inherit/.test(v)) { + return { r: 0, g: 0, b: 0, a: 0 }; + } else if (!/^#|^rgb/.test(v) ) { // maybe we can check for web safe colors + const h = document.getElementsByTagName('head')[0]; h.style.color = v; + let webColor = g.getComputedStyle(h,null).color; webColor = /rgb/.test(webColor) ? webColor.replace(/[^\d,]/g, '').split(',') : [0,0,0]; + h.style.color = ''; return { r: parseInt(webColor[0]), g: parseInt(webColor[1]), b: parseInt(webColor[2]) }; + } + }; + + const rgbToHex = (r, g, b) => // transform rgb to hex or vice-versa | webkit browsers ignore HEX, always use RGB/RGBA + `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`; + + const hexToRGB = hex => { + const shr = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") + hex = hex.replace(shr, (m, r, g, b) => r + r + g + g + b + b); + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; + }; + + const getInlineStyle = (el, p) => { // get transform style for element from cssText for .to() method, the sp is for transform property + if (!el) return; // if the scroll applies to `window` it returns as it has no styling + const //the cssText + css = el.style.cssText.replace(/\s/g,'').split(';'), + trsf = {}; //the transform object + // if we have any inline style in the cssText attribute, usually it has higher priority + for ( let i=0, csl = css.length; i { // get computed style property for element for .to() method + const styleAttribute = el.style, + computedStyle = g.getComputedStyle(el,null) || el.currentStyle, + //the computed style | prefixed property + pp = property(p), + styleValue = styleAttribute[p] && !/auto|initial|none|unset/.test(styleAttribute[p]) ? styleAttribute[p] : computedStyle[pp]; // s the property style value + if ( p !== 'transform' && (pp in computedStyle || pp in styleAttribute) ) { + if ( styleValue ){ + if (pp==='filter') { // handle IE8 opacity + const filterValue = parseInt(styleValue.split('=')[1].replace(')','')); + return parseFloat(filterValue/100); + } else { + return styleValue; + } + } else { + return _defaults[p]; + } + } + }; + + const //more internals + getAll = () => tweens; + + const removeAll = () => { tweens = []; }; + const add = tw => { tweens.push(tw); }; + const remove = tw => { const i = tweens.indexOf(tw); if (i !== -1) { tweens.splice(i, 1); }}; + const stop = () => { if (tick) { _cancelAnimationFrame(tick); tick = null; } }; + + const // support Touch? + canTouch = ('ontouchstart' in g || navigator && navigator.msMaxTouchPoints) || false; + + const touchOrWheel = canTouch ? 'touchstart' : 'mousewheel'; + + const //events to prevent on scroll + mouseEnter = 'mouseenter'; + + const _requestAnimationFrame = g.requestAnimationFrame || g.webkitRequestAnimationFrame || (c => setTimeout(c, 16)); + const _cancelAnimationFrame = g.cancelAnimationFrame || g.webkitCancelRequestAnimationFrame || (c => clearTimeout(c)); + const transformProperty = property('transform'); + + const //true scroll container + body = document.body; + + const html = document.getElementsByTagName('HTML')[0]; + const scrollContainer = navigator && /webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? body : html; + const isIE = navigator && (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null) ? parseFloat( RegExp.$1 ) : false; + + const // check IE8/IE + isIE8 = isIE === 8; + + const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); + + // KUTE.js INTERPOLATORS + const interpolate = g.Interpolate = {}; + + // core easing functions + + const number = interpolate.number = (a, b, v) => { // number1, number2, progress + a = +a; b -= a; return a + b * v; + }; + + const unit = interpolate.unit = (a, b, u, v) => { // number1, number2, unit, progress + a = +a; b -= a; return ( a + b * v ) + u; + }; + + const color = interpolate.color = (a, b, v, h) => { + // rgba1, rgba2, progress, convertToHex(true/false) + const _c = {}; + + let c; + const n = number; + const ep = ')'; + const cm =','; + const r = 'rgb('; + const ra = 'rgba('; + for (c in b) { _c[c] = c !== 'a' ? (number(a[c],b[c],v)>>0 || 0) : (a[c] && b[c]) ? (number(a[c],b[c],v) * 100 >> 0 )/100 : null; } + return h ? rgbToHex( _c.r, _c.g, _c.b ) : !_c.a ? r + _c.r + cm + _c.g + cm + _c.b + ep : ra + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep; + }; + + const translate = interpolate.translate = isMobile ? (a, b, u, v) => { + const translation = {}; + for (const ax in b){ + translation[ax] = ( a[ax]===b[ax] ? b[ax] : (a[ax] + ( b[ax] - a[ax] ) * v ) >> 0 ) + u; + } + return translation.x||translation.y ? `translate(${translation.x},${translation.y})` : + `translate3d(${translation.translateX},${translation.translateY},${translation.translateZ})`; + } : (a, b, u, v) => { + const translation = {}; + for (const ax in b){ + translation[ax] = ( a[ax]===b[ax] ? b[ax] : ( (a[ax] + ( b[ax] - a[ax] ) * v ) * 100 >> 0 ) / 100 ) + u; + } + return translation.x||translation.y ? `translate(${translation.x},${translation.y})` : + `translate3d(${translation.translateX},${translation.translateY},${translation.translateZ})`; + }; + + const rotate = interpolate.rotate = (a, b, u, v) => { + const rotation = {}; + for ( const rx in b ){ + rotation[rx] = rx === 'z' ? (`rotate(${((a[rx] + (b[rx] - a[rx]) * v) * 100 >> 0 ) / 100}${u})`) + : (`${rx}(${((a[rx] + (b[rx] - a[rx]) * v) * 100 >> 0 ) / 100}${u})`); + } + return rotation.z ? rotation.z : (rotation.rotateX||'') + (rotation.rotateY||'') + (rotation.rotateZ||''); + }; + + const skew = interpolate.skew = (a, b, u, v) => { + const skewProp = {}; + for ( const sx in b ){ + skewProp[sx] = `${sx}(${((a[sx] + (b[sx] - a[sx]) * v) * 10 >> 0) / 10}${u})`; + } + return (skewProp.skewX||'') + (skewProp.skewY||''); + }; + + const scale = interpolate.scale = (a, b, v) => `scale(${((a + (b - a) * v) * 1000 >> 0 ) / 1000})`; + + const // KUTE.js DOM update functions + DOM = {}; + + const ticker = t => { + let i = 0; + while ( i < tweens.length ) { + if ( update.call(tweens[i],t) ) { + i++; + } else { + tweens.splice(i, 1); + } + } + tick = _requestAnimationFrame(ticker); + }; + + const update = function(t=time.now()) { + if ( t < this._startTime && this.playing ) { return true; } + + const elapsed = Math.min(( t - this._startTime ) / this.options.duration, 1), progress = this.options.easing(elapsed); // calculate progress + + for (const p in this.valuesEnd){ DOM[p](this.element,p,this.valuesStart[p],this.valuesEnd[p],progress,this.options); } //render the CSS update + + if (this.options.update) { this.options.update.call(); } // fire the updateCallback + + if (elapsed === 1) { + if (this.options.repeat > 0) { + if ( isFinite(this.options.repeat ) ) { this.options.repeat--; } + + if (this.options.yoyo) { // handle yoyo + this.reversed = !this.reversed; + reverse.call(this); + } + + this._startTime = (this.options.yoyo && !this.reversed) ? t + this.options.repeatDelay : t; //set the right time for delay + return true; + } else { + + if (this.options.complete) { this.options.complete.call(); } + + scrollOut.call(this); // unbind preventing scroll when scroll tween finished + + for (let i = 0, ctl = this.options.chain.length; i < ctl; i++) { // start animating chained tweens + this.options.chain[i].start(); + } + + //stop ticking when finished + close.call(this); + } + return false; + } + return true; + }; + + const // applies the transform origin and perspective + perspective = function () { + const el = this.element, ops = this.options; + if ( ops.perspective !== undefined && transformProperty in this.valuesEnd ) { // element perspective + this.valuesStart[transformProperty]['perspective'] = this.valuesEnd[transformProperty]['perspective']; + } + // element transform origin / we filter it out for svgTransform to fix the Firefox transformOrigin bug https://bugzilla.mozilla.org/show_bug.cgi?id=923193 + if ( ops.transformOrigin !== undefined && (!('svgTransform' in this.valuesEnd)) ) { el.style[property('transformOrigin')] = ops.transformOrigin; } // set transformOrigin for CSS3 transforms only + if ( ops.perspectiveOrigin !== undefined ) { el.style[property('perspectiveOrigin')] = ops.perspectiveOrigin; } // element perspective origin + if ( ops.parentPerspective !== undefined ) { el.parentNode.style[property('perspective')] = `${ops.parentPerspective}px`; } // parent perspective + if ( ops.parentPerspectiveOrigin !== undefined ) { el.parentNode.style[property('perspectiveOrigin')] = ops.parentPerspectiveOrigin; } // parent perspective origin + }; + + const // plugin connector objects + // check current property value when .to() method is used + prepareStart = {}; + + const // checks for differences between start and end value, try to make sure start unit and end unit are same as well as consistent, stack transforms, process SVG paths + crossCheck = {}; + + const // parse properties object + // string parsing and property specific value processing + parseProperty = { // we already start working on core supported properties + boxModel(p, v) { + if (!(p in DOM)){ + DOM[p] = (l, p, a, b, v) => { + l.style[p] = `${v > 0.99 || v < 0.01 ? ((number(a,b,v)*10)>>0)/10 : (number(a,b,v) ) >> 0}px`; + } + } + const boxValue = trueDimension(v); + return boxValue.u === '%' ? boxValue.v * this.element.offsetWidth / 100 : boxValue.v; + }, + transform(p, v) { + if (!(transformProperty in DOM)) { + DOM[transformProperty] = (l, p, a, b, v, o) => { + l.style[p] = (a.perspective||'') + + ('translate' in a ? translate(a.translate,b.translate,'px',v):'') + + ('rotate' in a ? rotate(a.rotate,b.rotate,'deg',v):'') + + ('skew' in a ? skew(a.skew,b.skew,'deg',v):'') + + ('scale' in a ? scale(a.scale,b.scale,v):''); + } + } + + // process each transform property + if (/translate/.test(p)) { + if (p === 'translate3d') { + const t3d = v.split(','), t3d0 = trueDimension(t3d[0]), t3d1 = trueDimension(t3d[1], t3d2 = trueDimension(t3d[2])); + return { + translateX : t3d0.u === '%' ? (t3d0.v * this.element.offsetWidth / 100) : t3d0.v, + translateY : t3d1.u === '%' ? (t3d1.v * this.element.offsetHeight / 100) : t3d1.v, + translateZ : t3d2.u === '%' ? (t3d2.v * (this.element.offsetHeight + this.element.offsetWidth) / 200) : t3d2.v // to be changed with something like element and/or parent perspective + }; + } else if (/^translate(?:[XYZ])$/.test(p)) { + const t1d = trueDimension(v), percentOffset = /X/.test(p) ? this.element.offsetWidth / 100 : /Y/.test(p) ? this.element.offsetHeight / 100 : (this.element.offsetWidth+this.element.offsetHeight) / 200; + + return t1d.u === '%' ? (t1d.v * percentOffset) : t1d.v; + } else if (p === 'translate') { + const tv = typeof v === 'string' ? v.split(',') : v; + const t2d = {}; + let t2dv; + const t2d0 = trueDimension(tv[0]); + const t2d1 = tv.length ? trueDimension(tv[1]) : {v: 0, u: 'px'}; + if (tv instanceof Array) { + t2d.x = t2d0.u === '%' ? (t2d0.v * this.element.offsetWidth / 100) : t2d0.v, + t2d.y = t2d1.u === '%' ? (t2d1.v * this.element.offsetHeight / 100) : t2d1.v + } else { + t2dv = trueDimension(tv); + t2d.x = t2dv.u === '%' ? (t2dv.v * this.element.offsetWidth / 100) : t2dv.v, + t2d.y = 0 + } + + return t2d; + } + } else if (/rotate|skew/.test(p)) { + if (/^rotate(?:[XYZ])$|skew(?:[XY])$/.test(p)) { + const r3d = trueDimension(v,true); + return r3d.u === 'rad' ? radToDeg(r3d.v) : r3d.v; + } else if (p === 'rotate') { + const r2d = {}, r2dv = trueDimension(v,true); + r2d.z = r2dv.u === 'rad' ? radToDeg(r2dv.v) : r2dv.v; + return r2d; + } + } else if (p === 'scale') { + return parseFloat(v); // this must be parseFloat(v) + } + }, + unitless(p, v) { // scroll | opacity + if (/scroll/.test(p) && !(p in DOM) ){ + DOM[p] = (l, p, a, b, v) => { + l.scrollTop = (number(a,b,v))>>0; + }; + } else if (p === 'opacity') { + if (!(p in DOM)) { + if (isIE8) { + DOM[p] = (l, p, a, b, v) => { + const st = "alpha(opacity=", ep = ')'; + l.style.filter = st + ((number(a,b,v) * 100)>>0) + ep; + }; + } else { + DOM[p] = (l, p, a, b, v) => { + l.style.opacity = ((number(a,b,v) * 100)>>0)/100; + }; + } + } + } + return parseFloat(v); + }, + colors(p, v) { // colors + if (!(p in DOM)) { + DOM[p] = (l, p, a, b, v, o) => { + l.style[p] = color(a,b,v,o.keepHex); + }; + } + return trueColor(v); + } + }; + + const // process properties for endValues and startValues or one of them + preparePropertiesObject = function(obj, fn) { // this, props object, type: start/end + const element = this.element, propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd, skewObject = {}, rotateObject = {}, translateObject = {}, transformObject = {}; + + for (const x in obj) { + if (_transform.includes(x)) { // transform object gets built here + if ( /^translate(?:[XYZ]|3d)$/.test(x) ) { //process translate3d + const ta = ['X', 'Y', 'Z']; //coordinates // translate[x] = pp(x, obj[x]); + + for (let f = 0; f < 3; f++) { + const a = ta[f]; + if ( /3d/.test(x) ) { + translateObject[`translate${a}`] = parseProperty.transform.call(this,`translate${a}`, obj[x][f]); + } else { + translateObject[`translate${a}`] = (`translate${a}` in obj) ? parseProperty.transform.call(this,`translate${a}`, obj[`translate${a}`]) : 0; + } + } + transformObject['translate'] = translateObject; + } else if ( /^rotate(?:[XYZ])$|^skew(?:[XY])$/.test(x) ) { //process rotation/skew + const ap = /rotate/.test(x) ? 'rotate' : 'skew', ra = ['X', 'Y', 'Z'], rtp = ap === 'rotate' ? rotateObject : skewObject; + for (let r = 0; r < 3; r++) { + const v = ra[r]; + if ( obj[ap+v] !== undefined && x !== 'skewZ' ) { + rtp[ap+v] = parseProperty.transform.call(this,ap+v, obj[ap+v]); + } + } + transformObject[ap] = rtp; + } else if ( /(rotate|translate|scale)$/.test(x) ) { //process 2d translation / rotation + transformObject[x] = parseProperty.transform.call(this, x, obj[x]); + } + propertiesObject[transformProperty] = transformObject; + } else { + if ( _boxModel.includes(x) ) { + propertiesObject[x] = parseProperty.boxModel.call(this,x,obj[x]); + } else if (_opacity.includes(x) || x === 'scroll') { + propertiesObject[x] = parseProperty.unitless.call(this,x,obj[x]); + } else if (_colors.includes(x)) { + propertiesObject[x] = parseProperty.colors.call(this,x,obj[x]); + } else if (x in parseProperty) { // or any other property from css/ attr / svg / third party plugins + propertiesObject[x] = parseProperty[x].call(this,x,obj[x]); + } + } + } + }; + + const reverse = function () { + if (this.options.yoyo) { + for (const p in this.valuesEnd) { + const tmp = this.valuesRepeat[p]; + this.valuesRepeat[p] = this.valuesEnd[p]; + this.valuesEnd[p] = tmp; + this.valuesStart[p] = this.valuesRepeat[p]; + } + } + }; + + const close = function () { // when animation is finished reset repeat, yoyo&reversed tweens + if (this.repeat > 0) { this.options.repeat = this.repeat; } + if (this.options.yoyo && this.reversed===true) { reverse.call(this); this.reversed = false; } + this.playing = false; + + setTimeout(() => { if (!tweens.length) { stop(); } }, 48); // when all animations are finished, stop ticking after ~3 frames + }; + + const preventScroll = e => { // prevent mousewheel or touch events while tweening scroll + const data = document.body.getAttribute('data-tweening'); + if (data && data === 'scroll') { e.preventDefault(); } + }; + + const scrollOut = function(){ //prevent scroll when tweening scroll + if ( 'scroll' in this.valuesEnd && document.body.getAttribute('data-tweening')) { + document.removeEventListener(touchOrWheel, preventScroll, false); + document.removeEventListener(mouseEnter, preventScroll, false); + document.body.removeAttribute('data-tweening'); + } + }; + + const scrollIn = function(){ + if ( 'scroll' in this.valuesEnd && !document.body.getAttribute('data-tweening')) { + document.addEventListener(touchOrWheel, preventScroll, false); + document.addEventListener(mouseEnter, preventScroll, false); + document.body.setAttribute('data-tweening', 'scroll'); + } + }; + + const processEasing = fn => { //process easing function + if ( typeof fn === 'function') { + return fn; + } else if ( typeof fn === 'string' ) { + return easing[fn]; // regular Robert Penner Easing Functions + } + }; + + const getStartValues = function () { // stack transform props for .to() chains + const startValues = {}, currentStyle = getInlineStyle(this.element,'transform'), deg = ['rotate','skew'], ax = ['X','Y','Z']; + + for (var p in this.valuesStart){ + if ( _transform.includes(p) ) { + const r2d = (/(rotate|translate|scale)$/.test(p)); + if ( /translate/.test(p) && p !== 'translate' ) { + startValues['translate3d'] = currentStyle['translate3d'] || _defaults[p]; + } else if ( r2d ) { // 2d transforms + startValues[p] = currentStyle[p] || _defaults[p]; + } else if ( !r2d && /rotate|skew/.test(p) ) { // all angles + for (var d=0; d<2; d++) { + for (let a = 0; a<3; a++) { + const s = deg[d]+ax[a]; + if (_transform.includes(s) && (s in this.valuesStart) ) { startValues[s] = currentStyle[s] || _defaults[s]; } + } + } + } + } else { + if ( p !== 'scroll' ) { + if (p === 'opacity' && isIE8 ) { // handle IE8 opacity + const currentOpacity = getCurrentStyle(this.element,'filter'); + startValues['opacity'] = typeof currentOpacity === 'number' ? currentOpacity : _defaults['opacity']; + } else { + if ( _all.includes(p) ) { + startValues[p] = getCurrentStyle(this.element,p) || d[p]; + } else { // plugins register here + startValues[p] = p in prepareStart ? prepareStart[p].call(this,p,this.valuesStart[p]) : 0; + } + } + } else { + startValues[p] = this.element === scrollContainer ? (g.pageYOffset || scrollContainer.scrollTop) : this.element.scrollTop; + } + } + } + for ( var p in currentStyle ){ // also add to startValues values from previous tweens + if ( _transform.includes(p) && (!( p in this.valuesStart )) ) { + startValues[p] = currentStyle[p] || _defaults[p]; + } + } + + this.valuesStart = {}; + preparePropertiesObject.call(this,startValues,'start'); + + if ( transformProperty in this.valuesEnd ) { // let's stack transform + for ( const sp in this.valuesStart[transformProperty]) { // sp is the object corresponding to the transform function objects translate / rotate / skew / scale + if ( sp !== 'perspective') { + if ( typeof this.valuesStart[transformProperty][sp] === 'object' ) { + for ( const spp in this.valuesStart[transformProperty][sp] ) { // 3rd level + if ( typeof this.valuesEnd[transformProperty][sp] === 'undefined' ) { this.valuesEnd[transformProperty][sp] = {}; } + if ( typeof this.valuesStart[transformProperty][sp][spp] === 'number' && typeof this.valuesEnd[transformProperty][sp][spp] === 'undefined' ) { + this.valuesEnd[transformProperty][sp][spp] = this.valuesStart[transformProperty][sp][spp]; + } + } + } else if ( typeof this.valuesStart[transformProperty][sp] === 'number' ) { + if ( typeof this.valuesEnd[transformProperty][sp] === 'undefined' ) { // scale + this.valuesEnd[transformProperty][sp] = this.valuesStart[transformProperty][sp]; + } + } + } + } + } + }; + + var easing = g.Easing = {}; + easing.linear = t => t; + easing.easingSinusoidalIn = t => -Math.cos(t * Math.PI / 2) + 1; + easing.easingSinusoidalOut = t => Math.sin(t * Math.PI / 2); + easing.easingSinusoidalInOut = t => -0.5 * (Math.cos(Math.PI * t) - 1); + easing.easingQuadraticIn = t => t*t; + easing.easingQuadraticOut = t => t*(2-t); + easing.easingQuadraticInOut = t => t<.5 ? 2*t*t : -1+(4-2*t)*t; + easing.easingCubicIn = t => t*t*t; + easing.easingCubicOut = t => (--t)*t*t+1; + easing.easingCubicInOut = t => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; + easing.easingQuarticIn = t => t*t*t*t; + easing.easingQuarticOut = t => 1-(--t)*t*t*t; + easing.easingQuarticInOut = t => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t; + easing.easingQuinticIn = t => t*t*t*t*t; + easing.easingQuinticOut = t => 1+(--t)*t*t*t*t; + easing.easingQuinticInOut = t => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t; + easing.easingCircularIn = t => -(Math.sqrt(1 - (t * t)) - 1); + easing.easingCircularOut = t => Math.sqrt(1 - (t = t - 1) * t); + easing.easingCircularInOut = t => ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); + easing.easingExponentialIn = t => 2 ** (10 * (t - 1)) - 0.001; + easing.easingExponentialOut = t => 1 - 2 ** (-10 * t); + easing.easingExponentialInOut = t => (t *= 2) < 1 ? 0.5 * (2 ** (10 * (t - 1))) : 0.5 * (2 - 2 ** (-10 * (t - 1))); + easing.easingBackIn = t => { const s = 1.70158; return t * t * ((s + 1) * t - s); }; + easing.easingBackOut = t => { const s = 1.70158; return --t * t * ((s + 1) * t + s) + 1; }; + easing.easingBackInOut = t => { const s = 1.70158 * 1.525; if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s)); return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2); }; + easing.easingElasticIn = t => { + let s; + let _kea = 0.1; + const _kep = 0.4; + if ( t === 0 ) return 0;if ( t === 1 ) return 1; + if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2; + return - ( _kea * (2 ** (10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) ); + }; + easing.easingElasticOut = t => { + let s; + let _kea = 0.1; + const _kep = 0.4; + if ( t === 0 ) return 0;if ( t === 1 ) return 1; + if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2 ; + return ( _kea * (2 ** (- 10 * t)) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) + 1 ); + }; + easing.easingElasticInOut = t => { + let s; + let _kea = 0.1; + const _kep = 0.4; + if ( t === 0 ) return 0;if ( t === 1 ) return 1; + if ( !_kea || _kea < 1 ) { _kea = 1; s = _kep / 4; } else s = _kep * Math.asin( 1 / _kea ) / Math.PI * 2 ; + if ( ( t *= 2 ) < 1 ) return - 0.5 * ( _kea * (2 ** (10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) ); + return _kea * (2 ** (-10 * (t -= 1))) * Math.sin( ( t - s ) * Math.PI * 2 / _kep ) * 0.5 + 1; + }; + easing.easingBounceIn = t => 1 - easing.easingBounceOut( 1 - t ); + easing.easingBounceOut = t => { + if ( t < ( 1 / 2.75 ) ) { return 7.5625 * t * t; } + else if ( t < ( 2 / 2.75 ) ) { return 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + 0.75; } + else if ( t < ( 2.5 / 2.75 ) ) { return 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + 0.9375; } + else {return 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + 0.984375; } + }; + easing.easingBounceInOut = t => { if ( t < 0.5 ) return easing.easingBounceIn( t * 2 ) * 0.5; return easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5;}; + + // single Tween object construct + const Tween = function (targetElement, startObject, endObject, options) { + this.element = 'scroll' in endObject && (targetElement === undefined || targetElement === null) ? scrollContainer : targetElement; // element animation is applied to + + this.playing = false; + this.reversed = false; + this.paused = false; + + this._startTime = null; + this._pauseTime = null; + + this._startFired = false; + this.options = {}; for (const o in options) { this.options[o] = options[o]; } + this.options.rpr = options.rpr || false; // internal option to process inline/computed style at start instead of init true/false + + this.valuesRepeat = {}; // internal valuesRepeat + this.valuesEnd = {}; // valuesEnd + this.valuesStart = {}; // valuesStart + + preparePropertiesObject.call(this,endObject,'end'); // valuesEnd + if ( this.options.rpr ) { this.valuesStart = startObject; } else { preparePropertiesObject.call(this,startObject,'start'); } // valuesStart + + if ( this.options.perspective !== undefined && transformProperty in this.valuesEnd ) { // element transform perspective + const perspectiveString = `perspective(${parseInt(this.options.perspective)}px)`; + this.valuesEnd[transformProperty].perspective = perspectiveString; + } + + for ( const e in this.valuesEnd ) { + if (e in crossCheck && !this.options.rpr) crossCheck[e].call(this); // this is where we do the valuesStart and valuesEnd check for fromTo() method + } + + this.options.chain = []; // chained Tweens + this.options.easing = options.easing && typeof processEasing(options.easing) === 'function' ? processEasing(options.easing) : easing[defaultOptions.easing]; // you can only set a core easing function as default + this.options.repeat = options.repeat || defaultOptions.repeat; + this.options.repeatDelay = options.repeatDelay || defaultOptions.repeatDelay; + this.options.yoyo = options.yoyo || defaultOptions.yoyo; + this.options.duration = options.duration || defaultOptions.duration; // duration option | default + this.options.delay = options.delay || defaultOptions.delay; // delay option | default + + this.repeat = this.options.repeat; // we cache the number of repeats to be able to put it back after all cycles finish + }; + + const // tween control and chain + TweenProto = Tween.prototype = { + // queue tween object to main frame update + start(t) { // move functions that use the ticker outside the prototype to be in the same scope with it + scrollIn.call(this); + + if ( this.options.rpr ) { getStartValues.apply(this); } // on start we reprocess the valuesStart for TO() method + perspective.apply(this); // apply the perspective and transform origin + + for ( const e in this.valuesEnd ) { + if (e in crossCheck && this.options.rpr) crossCheck[e].call(this); // this is where we do the valuesStart and valuesEnd check for to() method + this.valuesRepeat[e] = this.valuesStart[e]; + } + + // now it's a good time to start + tweens.push(this); + this.playing = true; + this.paused = false; + this._startFired = false; + this._startTime = t || time.now(); + this._startTime += this.options.delay; + + if (!this._startFired) { + if (this.options.start) { this.options.start.call(); } + this._startFired = true; + } + !tick && ticker(); + return this; + }, + play() { + if (this.paused && this.playing) { + this.paused = false; + if (this.options.resume) { this.options.resume.call(); } + this._startTime += time.now() - this._pauseTime; + add(this); + !tick && ticker(); // restart ticking if stopped + } + return this; + }, + resume() { return this.play(); }, + pause() { + if (!this.paused && this.playing) { + remove(this); + this.paused = true; + this._pauseTime = time.now(); + if (this.options.pause) { this.options.pause.call(); } + } + return this; + }, + stop() { + if (!this.paused && this.playing) { + remove(this); + this.playing = false; + this.paused = false; + scrollOut.call(this); + + if (this.options.stop) { this.options.stop.call(); } + this.stopChainedTweens(); + close.call(this); + } + return this; + }, + chain() { this.options.chain = arguments; return this; }, + stopChainedTweens() { + for (let i = 0, ctl = this.options.chain.length; i < ctl; i++) { + this.options.chain[i].stop(); + } + } + }; + + const // the multi elements Tween constructs + TweensTO = function (els, vE, o) { // .to + this.tweens = []; const options = []; + for ( let i = 0, tl = els.length; i < tl; i++ ) { + options[i] = o || {}; o.delay = o.delay || defaultOptions.delay; + options[i].delay = i>0 ? o.delay + (o.offset||defaultOptions.offset) : o.delay; + this.tweens.push( to(els[i], vE, options[i]) ); + } + }; + + const TweensFT = function (els, vS, vE, o) { // .fromTo + this.tweens = []; const options = []; + for ( let i = 0, l = els.length; i < l; i++ ) { + options[i] = o || {}; o.delay = o.delay || defaultOptions.delay; + options[i].delay = i>0 ? o.delay + (o.offset||defaultOptions.offset) : o.delay; + this.tweens.push( fromTo(els[i], vS, vE, options[i]) ); + } + }; + + const ws = TweensTO.prototype = TweensFT.prototype = { + start(t=time.now()) { + for ( let i = 0, tl = this.tweens.length; i < tl; i++ ) { + this.tweens[i].start(t); + } + return this; + }, + stop() { for ( let i = 0, tl = this.tweens.length; i < tl; i++ ) { this.tweens[i].stop(); } return this; }, + pause() { for ( let i = 0, tl = this.tweens.length; i < tl; i++ ) { this.tweens[i].pause(); } return this; }, + chain() { this.tweens[this.tweens.length-1].options.chain = arguments; return this; }, + play() { for ( let i = 0, tl = this.tweens.length; i < tl; i++ ) { this.tweens[i].play(); } return this; }, + resume() {return this.play()} + }; + + const // main methods + to = (element, endObject, options) => { + options = options || {}; options.rpr = true; + return new Tween(selector(element), endObject, endObject, options); + }; + + const fromTo = (element, startObject, endObject, options) => { + options = options || {}; + return new Tween(selector(element), startObject, endObject, options); + }; + + const // multiple elements tweening + allTo = (elements, endObject, options) => new TweensTO(selector(elements,true), endObject, options); + + const allFromTo = (elements, f, endObject, options) => new TweensFT(selector(elements,true), f, endObject, options); + + return { // export core methods to public for plugins + property, getPrefix, selector, processEasing, // utils + defaultOptions, // default tween options since 1.6.1 + to, fromTo, allTo, allFromTo, // main methods + ticker, tick, tweens, update, dom : DOM, // update + parseProperty, prepareStart, crossCheck, Tween, // property parsing & preparation | Tween | crossCheck + truD: trueDimension, truC: trueColor, rth: rgbToHex, htr: hexToRGB, getCurrentStyle, // property parsing + }; +})); diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0de8c9e..0000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 thednp - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/README.md b/README.md deleted file mode 100644 index 90c2187..0000000 --- a/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# KUTE.js - -A modern JavaScript animation engine built on ES6+ standards with strong TypeScript definitions and most essential features for the web with easy to use methods to set up high performance, cross-browser animations. The focus is code quality, flexibility, performance and size. - -[![NPM Version](https://img.shields.io/npm/v/kute.js.svg?style=flat-square)](https://www.npmjs.com/package/kute.js) -[![NPM Downloads](https://img.shields.io/npm/dm/kute.js.svg?style=flat-square)](http://npm-stat.com/charts.html?package=kute.js) -[![jsDeliver](https://data.jsdelivr.com/v1/package/npm/kute.js/badge)](https://www.jsdelivr.com/package/npm/kute.js) -[![CDNJS](https://img.shields.io/cdnjs/v/kute.js.svg?style=flat-square)](https://cdnjs.com/libraries/kute.js) - -KUTE.js packs a series of components for presentation attributes, SVG transform, draw SVG strokes and path morphing, text string write up or number countdowns, plus additional CSS properties like colors, border-radius or typographic properties. - -For components documentation, examples and other cool tips, check the [demo](http://thednp.github.io/kute.js/). - - -# Components -KUTE.js includes 18 components, but not all of them are bundled with the default distribution package: - -* [backgroundPosition](http://thednp.github.io/kute.js/backgroundPosition.html) - enables the animation for the `backgroundPosition` CSS property -* [borderRadius](http://thednp.github.io/kute.js/borderRadius.html) - enables the animation for all the **borderRadius** properties -* [boxModel](http://thednp.github.io/kute.js/boxModel.html) - enables the animation for the **boxModel** properties like `top` , `left`, `width`, etc -* [clipProperty](http://thednp.github.io/kute.js/clipProperty.html) - enables the animation for the `clip` property -* [colorProperties](http://thednp.github.io/kute.js/colorProperties.html) - enables the animation for the **color** properties like `color`, `backgroundColor` -* [filterEffects](http://thednp.github.io/kute.js/filterEffects.html) - enables the animation for the `filter` property -* [htmlAttributes](http://thednp.github.io/kute.js/htmlAttributes.html) - enables the animation for any numeric as well as some color based **HTML Attributes** -* [opacityProperty](http://thednp.github.io/kute.js/opacityProperty.html) - enables the animation for the `opacity` property -* [scrollProperty](http://thednp.github.io/kute.js/scrollProperty.html) - enables the animation for the window/Element `scrollTop` Object property -* [shadowProperties](http://thednp.github.io/kute.js/shadowProperties.html) - enables the animation for the **shadowProperties** properties: `textShadow` & `boxShadow` -* [svgCubicMorph](http://thednp.github.io/kute.js/svgCubicMorph.html) - enables the animation for the `d` Presentation Attribute of the `` SVGElement targets; this implements some [Raphael.js](https://dmitrybaranovskiy.github.io/raphael/) functionality -* [svgMorph](http://thednp.github.io/kute.js/svgMorph.html) - enables the animation for the `d` Presentation Attribute of the `` SVGElement targets; this component implements some [D3.js](https://github.com/d3/d3) and [flubber](https://github.com/veltman/flubber) functionality -* [svgDraw](http://thednp.github.io/kute.js/svgDraw.html) - enables the animation for the `strokeDasharray` and `strokeDashoffset` CSS properties specific to `` SVGElement -* [svgTransform](http://thednp.github.io/kute.js/svgTransform.html) - enables the animation for the `transform` presentation attribute -* [textProperties](http://thednp.github.io/kute.js/textProperties.html) - enables the animation for numeric `HTMLTextElement` related CSS properties like `fontSize` or `letterSpacing` -* [textWrite](http://thednp.github.io/kute.js/textWrite.html) - enables the animation for the content of various strings -* [transformFunctions](http://thednp.github.io/kute.js/transformFunctions.html) - enables the animation for the `transform` CSS3 property, the default component bundled with the official build -* transformLegacy - enables the animation for the `transform` CSS3 property on legacy browsers IE9+, not included with the official build, but can be used in your custom builds -* [transformMatrix](http://thednp.github.io/kute.js/transformMatrix.html) - enables the animation for the `transform` CSS3 property; this component implements `DOMMatrix()` API and is super light - -All above mentioned components have a BASE version which doesn't include value processing, and their purpose is to provide a way to ship your super light version of your application. - - -# Wiki -For a complete developer guide, usage and stuff like npm, visit [the wiki](https://github.com/thednp/kute.js/wiki). - - -# 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 polyfills. - - -# Special Thanks -* [Mike Bostock](https://bost.ocks.org/mike/) for his awesome [D3.js](https://github.com/d3/d3), one of the sources for our reworked [SVGMorph](http://thednp.github.io/kute.js/svgMorph.html) component. -* [Noah Veltman](https://github.com/veltman) for his awesome [flubber](https://github.com/veltman/flubber), another one of the sources for the SVGMorph component. -* [Andrew Willems](https://stackoverflow.com/users/5218951/andrew-willems) for his awesome [Stackoverflow answer](https://stackoverflow.com/questions/35560989/javascript-how-to-determine-a-svg-path-draw-direction) resulting in the creation of our [SVGCubicMorph](http://thednp.github.io/kute.js/svgCubicMorph.html) component. -* [Dmitry Baranovskiy](https://dmitry.baranovskiy.com/) for his awesome [Raphael.js](https://dmitrybaranovskiy.github.io/raphael/), another source for our SVGCubicMorph component. -* [@dalisoft](https://github.com/dalisoft) contributed a great deal to the performance and functionality of previous versions of KUTE.js. - - -# Contributions -* [Contributors & Collaborators](https://github.com/thednp/kute.js/graphs/contributors) - - -# License -[MIT License](https://github.com/thednp/kute.js/blob/master/LICENSE) diff --git a/coffeeScript.js b/coffeeScript.js new file mode 100644 index 0000000..ff4da49 --- /dev/null +++ b/coffeeScript.js @@ -0,0 +1,1063 @@ +### KUTE.js - The Light Tweening Engine +# by dnp_theme +# Licensed under MIT-License +### + +((root, factory) -> + if typeof define == 'function' and define.amd + define [], factory + # AMD. Register as an anonymous module. + else if typeof exports == 'object' + module.exports = factory() + # Node, not strict CommonJS + else + root.KUTE = factory() + return +) this, -> + 'use strict' + # set a custom scope for KUTE.js + g = if typeof global != 'undefined' then global else window + time = g.performance + tweens = [] + tick = null + # tick must be null!! + #supported properties + _colors = [ + 'color' + 'backgroundColor' + ] + _boxModel = [ + 'top' + 'left' + 'width' + 'height' + ] + _transform = [ + 'translate3d' + 'translateX' + 'translateY' + 'translateZ' + 'rotate' + 'translate' + 'rotateX' + 'rotateY' + 'rotateZ' + 'skewX' + 'skewY' + 'scale' + ] + _scroll = [ 'scroll' ] + _opacity = [ 'opacity' ] + _all = _colors.concat(_opacity, _boxModel, _transform) + al = _all.length + _defaults = {} + #all properties default values + #populate default values object + i = 0 + while i < al + p = _all[i] + if _colors.indexOf(p) != -1 + _defaults[p] = 'rgba(0,0,0,0)' + # _defaults[p] = {r:0,g:0,b:0,a:1}; // no unit/suffix + else if _boxModel.indexOf(p) != -1 + _defaults[p] = 0 + else if p == 'translate3d' + # px + _defaults[p] = [ + 0 + 0 + 0 + ] + else if p == 'translate' + # px + _defaults[p] = [ + 0 + 0 + ] + else if p == 'rotate' or /X|Y|Z/.test(p) + # deg + _defaults[p] = 0 + else if p == 'scale' or p == 'opacity' + # unitless + _defaults[p] = 1 + p = null + i++ + # default tween options, since 1.6.1 + defaultOptions = + duration: 700 + delay: 0 + offset: 0 + repeat: 0 + repeatDelay: 0 + yoyo: false + easing: 'linear' + keepHex: false + + getPrefix = -> + `var i` + `var i` + #returns browser prefix + div = document.createElement('div') + i = 0 + pf = [ + 'Moz' + 'moz' + 'Webkit' + 'webkit' + 'O' + 'o' + 'Ms' + 'ms' + ] + s = [ + 'MozTransform' + 'mozTransform' + 'WebkitTransform' + 'webkitTransform' + 'OTransform' + 'oTransform' + 'MsTransform' + 'msTransform' + ] + i = 0 + pl = pf.length + while i < pl + if s[i] of div.style + return pf[i] + i++ + div = null + return + + property = (p) -> + # returns prefixed property | property + r = if !(p of document.body.style) then true else false + f = getPrefix() + # is prefix required for property | prefix + if r then f + p.charAt(0).toUpperCase() + p.slice(1) else p + + selector = (el, multi) -> + # a public selector utility + nl = undefined + if multi + nl = if el instanceof Object or typeof el == 'object' then el else document.querySelectorAll(el) + else + nl = if typeof el == 'object' then el else if /^#/.test(el) then document.getElementById(el.replace('#', '')) else document.querySelector(el) + if nl == null and el != 'window' + throw new TypeError('Element not found or incorrect selector: ' + el) + nl + + radToDeg = (a) -> + a * 180 / Math.PI + + trueDimension = (d, p) -> + `var i` + #true dimension returns { v = value, u = unit } + x = parseInt(d) or 0 + mu = [ + 'px' + '%' + 'deg' + 'rad' + 'em' + 'rem' + 'vh' + 'vw' + ] + y = undefined + i = 0 + l = mu.length + while i < l + if typeof d == 'string' and d.indexOf(mu[i]) != -1 + y = mu[i] + break + i++ + y = if y != undefined then y else if p then 'deg' else 'px' + { + v: x + u: y + } + + trueColor = (v) -> + # replace transparent and transform any color to rgba()/rgb() + if /rgb|rgba/.test(v) + # first check if it's a rgb string + vrgb = v.replace(/\s|\)/, '').split('(')[1].split(',') + y = if vrgb[3] then vrgb[3] else null + if !y + return { + r: parseInt(vrgb[0]) + g: parseInt(vrgb[1]) + b: parseInt(vrgb[2]) + } + else + return { + r: parseInt(vrgb[0]) + g: parseInt(vrgb[1]) + b: parseInt(vrgb[2]) + a: parseFloat(y) + } + else if /^#/.test(v) + fromHex = hexToRGB(v) + return { + r: fromHex.r + g: fromHex.g + b: fromHex.b + } + else if /transparent|none|initial|inherit/.test(v) + return { + r: 0 + g: 0 + b: 0 + a: 0 + } + else if !/^#|^rgb/.test(v) + # maybe we can check for web safe colors + h = document.getElementsByTagName('head')[0] + h.style.color = v + webColor = g.getComputedStyle(h, null).color + webColor = if /rgb/.test(webColor) then webColor.replace(/[^\d,]/g, '').split(',') else [ + 0 + 0 + 0 + ] + h.style.color = '' + return { + r: parseInt(webColor[0]) + g: parseInt(webColor[1]) + b: parseInt(webColor[2]) + } + return + rgbToHex = (r, g, b) -> + # transform rgb to hex or vice-versa | webkit browsers ignore HEX, always use RGB/RGBA + '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1) + hexToRGB = (hex) -> + shr = /^#?([a-f\d])([a-f\d])([a-f\d])$/i + # Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") + hex = hex.replace(shr, (m, r, g, b) -> + r + r + g + g + b + b + ) + result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + if result then + r: parseInt(result[1], 16) + g: parseInt(result[2], 16) + b: parseInt(result[3], 16) else null + getInlineStyle = (el, p) -> + `var i` + # get transform style for element from cssText for .to() method, the sp is for transform property + if !el + return + # if the scroll applies to `window` it returns as it has no styling + css = el.style.cssText.replace(/\s/g, '').split(';') + trsf = {} + #the transform object + # if we have any inline style in the cssText attribute, usually it has higher priority + i = 0 + csl = css.length + while i < csl + if /transform/i.test(css[i]) + tps = css[i].split(':')[1].split(')') + #all transform properties + k = 0 + tpl = tps.length - 1 + while k < tpl + tpv = tps[k].split('(') + tp = tpv[0] + tv = tpv[1] + #each transform property + if _transform.indexOf(tp) != -1 + trsf[tp] = if /translate3d/.test(tp) then tv.split(',') else tv + k++ + i++ + trsf + getCurrentStyle = (el, p) -> + # get computed style property for element for .to() method + styleAttribute = el.style + computedStyle = g.getComputedStyle(el, null) or el.currentStyle + pp = property(p) + styleValue = if styleAttribute[p] and !/auto|initial|none|unset/.test(styleAttribute[p]) then styleAttribute[p] else computedStyle[pp] + # s the property style value + if p != 'transform' and (pp of computedStyle or pp of styleAttribute) + if styleValue + if pp == 'filter' + # handle IE8 opacity + filterValue = parseInt(styleValue.split('=')[1].replace(')', '')) + return parseFloat(filterValue / 100) + else + return styleValue + else + return _defaults[p] + return + getAll = -> + tweens + removeAll = -> + tweens = [] + return + add = (tw) -> + tweens.push tw + return + remove = (tw) -> + `var i` + i = tweens.indexOf(tw) + if i != -1 + tweens.splice i, 1 + return + stop = -> + if tick + _cancelAnimationFrame tick + tick = null + return + canTouch = 'ontouchstart' of g or navigator and navigator.msMaxTouchPoints or false + touchOrWheel = if canTouch then 'touchstart' else 'mousewheel' + mouseEnter = 'mouseenter' + _requestAnimationFrame = g.requestAnimationFrame or g.webkitRequestAnimationFrame or (c) -> + setTimeout c, 16 + _cancelAnimationFrame = g.cancelAnimationFrame or g.webkitCancelRequestAnimationFrame or (c) -> + clearTimeout c + transformProperty = property('transform') + body = document.body + html = document.getElementsByTagName('HTML')[0] + scrollContainer = if navigator and /webkit/i.test(navigator.userAgent) or document.compatMode == 'BackCompat' then body else html + isIE = if navigator and new RegExp('MSIE ([0-9]{1,}[.0-9]{0,})').exec(navigator.userAgent) != null then parseFloat(RegExp.$1) else false + isIE8 = isIE == 8 + isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) + # we optimize morph depending on device type + # KUTE.js INTERPOLATORS + interpolate = g.Interpolate = {} + number = + interpolate.number = (a, b, v) -> + # number1, number2, progress + a = +a + b -= a + a + b * v + unit = + interpolate.unit = (a, b, u, v) -> + # number1, number2, unit, progress + a = +a + b -= a + a + b * v + u + color = + interpolate.color = (a, b, v, h) -> + # rgba1, rgba2, progress, convertToHex(true/false) + _c = {} + c = undefined + n = number + ep = ')' + cm = ',' + r = 'rgb(' + ra = 'rgba(' + for c of b + `c = c` + _c[c] = if c != 'a' then number(a[c], b[c], v) >> 0 or 0 else if a[c] and b[c] then (number(a[c], b[c], v) * 100 >> 0) / 100 else null + if h then rgbToHex(_c.r, _c.g, _c.b) else if !_c.a then r + _c.r + cm + _c.g + cm + _c.b + ep else ra + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep + translate = interpolate.translate = if isMobile then ((a, b, u, v) -> + translation = {} + for ax of b + translation[ax] = (if a[ax] == b[ax] then b[ax] else a[ax] + (b[ax] - (a[ax])) * v >> 0) + u + if translation.x or translation.y then 'translate(' + translation.x + ',' + translation.y + ')' else 'translate3d(' + translation.translateX + ',' + translation.translateY + ',' + translation.translateZ + ')' + ) else ((a, b, u, v) -> + translation = {} + for ax of b + translation[ax] = (if a[ax] == b[ax] then b[ax] else ((a[ax] + (b[ax] - (a[ax])) * v) * 100 >> 0) / 100) + u + if translation.x or translation.y then 'translate(' + translation.x + ',' + translation.y + ')' else 'translate3d(' + translation.translateX + ',' + translation.translateY + ',' + translation.translateZ + ')' + ) + rotate = + interpolate.rotate = (a, b, u, v) -> + rotation = {} + for rx of b + rotation[rx] = if rx == 'z' then 'rotate(' + ((a[rx] + (b[rx] - (a[rx])) * v) * 100 >> 0) / 100 + u + ')' else rx + '(' + ((a[rx] + (b[rx] - (a[rx])) * v) * 100 >> 0) / 100 + u + ')' + if rotation.z then rotation.z else (rotation.rotateX or '') + (rotation.rotateY or '') + (rotation.rotateZ or '') + skew = + interpolate.skew = (a, b, u, v) -> + skewProp = {} + for sx of b + skewProp[sx] = sx + '(' + ((a[sx] + (b[sx] - (a[sx])) * v) * 10 >> 0) / 10 + u + ')' + (skewProp.skewX or '') + (skewProp.skewY or '') + scale = + interpolate.scale = (a, b, v) -> + 'scale(' + ((a + (b - a) * v) * 1000 >> 0) / 1000 + ')' + DOM = {} + ticker = (t) -> + `var i` + i = 0 + while i < tweens.length + if update.call(tweens[i], t) + i++ + else + tweens.splice i, 1 + tick = _requestAnimationFrame(ticker) + return + update = (t) -> + `var p` + `var i` + t = t or time.now() + if t < @_startTime and @playing + return true + elapsed = Math.min((t - (@_startTime)) / @options.duration, 1) + progress = @options.easing(elapsed) + # calculate progress + for p of @valuesEnd + DOM[p] @element, p, @valuesStart[p], @valuesEnd[p], progress, @options + #render the CSS update + if @options.update + @options.update.call() + # fire the updateCallback + if elapsed == 1 + if @options.repeat > 0 + if isFinite(@options.repeat) + @options.repeat-- + if @options.yoyo + # handle yoyo + @reversed = !@reversed + reverse.call this + @_startTime = if @options.yoyo and !@reversed then t + @options.repeatDelay else t + #set the right time for delay + return true + else + if @options.complete + @options.complete.call() + scrollOut.call this + # unbind preventing scroll when scroll tween finished + i = 0 + ctl = @options.chain.length + while i < ctl + # start animating chained tweens + @options.chain[i].start() + i++ + #stop ticking when finished + close.call this + return false + true + perspective = -> + el = @element + ops = @options + if ops.perspective != undefined and transformProperty of @valuesEnd + # element perspective + @valuesStart[transformProperty]['perspective'] = @valuesEnd[transformProperty]['perspective'] + # element transform origin / we filter it out for svgTransform to fix the Firefox transformOrigin bug https://bugzilla.mozilla.org/show_bug.cgi?id=923193 + if ops.transformOrigin != undefined and !('svgTransform' of @valuesEnd) + el.style[property('transformOrigin')] = ops.transformOrigin + # set transformOrigin for CSS3 transforms only + if ops.perspectiveOrigin != undefined + el.style[property('perspectiveOrigin')] = ops.perspectiveOrigin + # element perspective origin + if ops.parentPerspective != undefined + el.parentNode.style[property('perspective')] = ops.parentPerspective + 'px' + # parent perspective + if ops.parentPerspectiveOrigin != undefined + el.parentNode.style[property('perspectiveOrigin')] = ops.parentPerspectiveOrigin + # parent perspective origin + return + prepareStart = {} + crossCheck = {} + parseProperty = + boxModel: (p, v) -> + if !(p of DOM) + DOM[p] = (l, p, a, b, v) -> + l.style[p] = (if v > 0.99 or v < 0.01 then (number(a, b, v) * 10 >> 0) / 10 else number(a, b, v) >> 0) + 'px' + return + boxValue = trueDimension(v) + if boxValue.u == '%' then boxValue.v * @element.offsetWidth / 100 else boxValue.v + transform: (p, v) -> + if !(transformProperty of DOM) + DOM[transformProperty] = (l, p, a, b, v, o) -> + l.style[p] = (a.perspective or '') + (if 'translate' of a then translate(a.translate, b.translate, 'px', v) else '') + (if 'rotate' of a then rotate(a.rotate, b.rotate, 'deg', v) else '') + (if 'skew' of a then skew(a.skew, b.skew, 'deg', v) else '') + (if 'scale' of a then scale(a.scale, b.scale, v) else '') + return + # process each transform property + if /translate/.test(p) + if p == 'translate3d' + t3d = v.split(',') + t3d0 = trueDimension(t3d[0]) + t3d1 = trueDimension(t3d[1], t3d2 = trueDimension(t3d[2])) + return { + translateX: if t3d0.u == '%' then t3d0.v * @element.offsetWidth / 100 else t3d0.v + translateY: if t3d1.u == '%' then t3d1.v * @element.offsetHeight / 100 else t3d1.v + translateZ: if t3d2.u == '%' then t3d2.v * (@element.offsetHeight + @element.offsetWidth) / 200 else t3d2.v + } + else if /^translate(?:[XYZ])$/.test(p) + t1d = trueDimension(v) + percentOffset = if /X/.test(p) then @element.offsetWidth / 100 else if /Y/.test(p) then @element.offsetHeight / 100 else (@element.offsetWidth + @element.offsetHeight) / 200 + return if t1d.u == '%' then t1d.v * percentOffset else t1d.v + else if p == 'translate' + tv = if typeof v == 'string' then v.split(',') else v + t2d = {} + t2dv = undefined + t2d0 = trueDimension(tv[0]) + t2d1 = if tv.length then trueDimension(tv[1]) else + v: 0 + u: 'px' + if tv instanceof Array + t2d.x = if t2d0.u == '%' then t2d0.v * @element.offsetWidth / 100 else t2d0.v + t2d.y = if t2d1.u == '%' then t2d1.v * @element.offsetHeight / 100 else t2d1.v + else + t2dv = trueDimension(tv) + t2d.x = if t2dv.u == '%' then t2dv.v * @element.offsetWidth / 100 else t2dv.v + t2d.y = 0 + return t2d + else if /rotate|skew/.test(p) + if /^rotate(?:[XYZ])$|skew(?:[XY])$/.test(p) + r3d = trueDimension(v, true) + return if r3d.u == 'rad' then radToDeg(r3d.v) else r3d.v + else if p == 'rotate' + r2d = {} + r2dv = trueDimension(v, true) + r2d.z = if r2dv.u == 'rad' then radToDeg(r2dv.v) else r2dv.v + return r2d + else if p == 'scale' + return parseFloat(v) + # this must be parseFloat(v) + return + unitless: (p, v) -> + # scroll | opacity + if /scroll/.test(p) and !(p of DOM) + DOM[p] = (l, p, a, b, v) -> + l.scrollTop = number(a, b, v) >> 0 + return + else if p == 'opacity' + if !(p of DOM) + if isIE8 + DOM[p] = (l, p, a, b, v) -> + st = 'alpha(opacity=' + ep = ')' + l.style.filter = st + (number(a, b, v) * 100 >> 0) + ep + return + else + DOM[p] = (l, p, a, b, v) -> + l.style.opacity = (number(a, b, v) * 100 >> 0) / 100 + return + parseFloat v + colors: (p, v) -> + # colors + if !(p of DOM) + DOM[p] = (l, p, a, b, v, o) -> + l.style[p] = color(a, b, v, o.keepHex) + return + trueColor v + preparePropertiesObject = (obj, fn) -> + # this, props object, type: start/end + element = @element + propertiesObject = if fn == 'start' then @valuesStart else @valuesEnd + skewObject = {} + rotateObject = {} + translateObject = {} + transformObject = {} + for x of obj + if _transform.indexOf(x) != -1 + # transform object gets built here + if /^translate(?:[XYZ]|3d)$/.test(x) + #process translate3d + ta = [ + 'X' + 'Y' + 'Z' + ] + #coordinates // translate[x] = pp(x, obj[x]); + f = 0 + while f < 3 + a = ta[f] + if /3d/.test(x) + translateObject['translate' + a] = parseProperty.transform.call(this, 'translate' + a, obj[x][f]) + else + translateObject['translate' + a] = if 'translate' + a of obj then parseProperty.transform.call(this, 'translate' + a, obj['translate' + a]) else 0 + f++ + transformObject['translate'] = translateObject + else if /^rotate(?:[XYZ])$|^skew(?:[XY])$/.test(x) + #process rotation/skew + ap = if /rotate/.test(x) then 'rotate' else 'skew' + ra = [ + 'X' + 'Y' + 'Z' + ] + rtp = if ap == 'rotate' then rotateObject else skewObject + r = 0 + while r < 3 + v = ra[r] + if obj[ap + v] != undefined and x != 'skewZ' + rtp[ap + v] = parseProperty.transform.call(this, ap + v, obj[ap + v]) + r++ + transformObject[ap] = rtp + else if /(rotate|translate|scale)$/.test(x) + #process 2d translation / rotation + transformObject[x] = parseProperty.transform.call(this, x, obj[x]) + propertiesObject[transformProperty] = transformObject + else + if _boxModel.indexOf(x) != -1 + propertiesObject[x] = parseProperty.boxModel.call(this, x, obj[x]) + else if _opacity.indexOf(x) != -1 or x == 'scroll' + propertiesObject[x] = parseProperty.unitless.call(this, x, obj[x]) + else if _colors.indexOf(x) != -1 + propertiesObject[x] = parseProperty.colors.call(this, x, obj[x]) + else if x of parseProperty + # or any other property from css/ attr / svg / third party plugins + propertiesObject[x] = parseProperty[x].call(this, x, obj[x]) + return + reverse = -> + `var p` + if @options.yoyo + for p of @valuesEnd + tmp = @valuesRepeat[p] + @valuesRepeat[p] = @valuesEnd[p] + @valuesEnd[p] = tmp + @valuesStart[p] = @valuesRepeat[p] + return + close = -> + # when animation is finished reset repeat, yoyo&reversed tweens + if @repeat > 0 + @options.repeat = @repeat + if @options.yoyo and @reversed == true + reverse.call this + @reversed = false + @playing = false + setTimeout (-> + if !tweens.length + stop() + return + ), 48 + # when all animations are finished, stop ticking after ~3 frames + return + preventScroll = (e) -> + # prevent mousewheel or touch events while tweening scroll + data = document.body.getAttribute('data-tweening') + if data and data == 'scroll' + e.preventDefault() + return + scrollOut = -> + #prevent scroll when tweening scroll + if 'scroll' of @valuesEnd and document.body.getAttribute('data-tweening') + document.removeEventListener touchOrWheel, preventScroll, false + document.removeEventListener mouseEnter, preventScroll, false + document.body.removeAttribute 'data-tweening' + return + scrollIn = -> + if 'scroll' of @valuesEnd and !document.body.getAttribute('data-tweening') + document.addEventListener touchOrWheel, preventScroll, false + document.addEventListener mouseEnter, preventScroll, false + document.body.setAttribute 'data-tweening', 'scroll' + return + processEasing = (fn) -> + #process easing function + if typeof fn == 'function' + return fn + else if typeof fn == 'string' + return easing[fn] + # regular Robert Penner Easing Functions + return + + getStartValues = -> + `var p` + `var p` + # stack transform props for .to() chains + startValues = {} + currentStyle = getInlineStyle(@element, 'transform') + deg = [ + 'rotate' + 'skew' + ] + ax = [ + 'X' + 'Y' + 'Z' + ] + for p of @valuesStart + if _transform.indexOf(p) != -1 + r2d = /(rotate|translate|scale)$/.test(p) + if /translate/.test(p) and p != 'translate' + startValues['translate3d'] = currentStyle['translate3d'] or _defaults[p] + else if r2d + # 2d transforms + startValues[p] = currentStyle[p] or _defaults[p] + else if !r2d and /rotate|skew/.test(p) + # all angles + d = 0 + while d < 2 + a = 0 + while a < 3 + s = deg[d] + ax[a] + if _transform.indexOf(s) != -1 and s of @valuesStart + startValues[s] = currentStyle[s] or _defaults[s] + a++ + d++ + else + if p != 'scroll' + if p == 'opacity' and isIE8 + # handle IE8 opacity + currentOpacity = getCurrentStyle(@element, 'filter') + startValues['opacity'] = if typeof currentOpacity == 'number' then currentOpacity else _defaults['opacity'] + else + if _all.indexOf(p) != -1 + startValues[p] = getCurrentStyle(@element, p) or d[p] + else + # plugins register here + startValues[p] = if p of prepareStart then prepareStart[p].call(this, p, @valuesStart[p]) else 0 + else + startValues[p] = if @element == scrollContainer then g.pageYOffset or scrollContainer.scrollTop else @element.scrollTop + for p of currentStyle + # also add to startValues values from previous tweens + if _transform.indexOf(p) != -1 and !(p of @valuesStart) + startValues[p] = currentStyle[p] or _defaults[p] + @valuesStart = {} + preparePropertiesObject.call this, startValues, 'start' + if transformProperty of @valuesEnd + # let's stack transform + for sp of @valuesStart[transformProperty] + # sp is the object corresponding to the transform function objects translate / rotate / skew / scale + if sp != 'perspective' + if typeof @valuesStart[transformProperty][sp] == 'object' + for spp of @valuesStart[transformProperty][sp] + # 3rd level + if typeof @valuesEnd[transformProperty][sp] == 'undefined' + @valuesEnd[transformProperty][sp] = {} + if typeof @valuesStart[transformProperty][sp][spp] == 'number' and typeof @valuesEnd[transformProperty][sp][spp] == 'undefined' + @valuesEnd[transformProperty][sp][spp] = @valuesStart[transformProperty][sp][spp] + else if typeof @valuesStart[transformProperty][sp] == 'number' + if typeof @valuesEnd[transformProperty][sp] == 'undefined' + # scale + @valuesEnd[transformProperty][sp] = @valuesStart[transformProperty][sp] + return + # core easing functions + easing = g.Easing = {} + easing.linear = (t) -> + t + easing.easingSinusoidalIn = (t) -> + -Math.cos(t * Math.PI / 2) + 1 + easing.easingSinusoidalOut = (t) -> + Math.sin t * Math.PI / 2 + easing.easingSinusoidalInOut = (t) -> + -0.5 * (Math.cos(Math.PI * t) - 1) + easing.easingQuadraticIn = (t) -> + t * t + easing.easingQuadraticOut = (t) -> + t * (2 - t) + easing.easingQuadraticInOut = (t) -> + if t < .5 then 2 * t * t else -1 + (4 - (2 * t)) * t + easing.easingCubicIn = (t) -> + t * t * t + easing.easingCubicOut = (t) -> + --t * t * t + 1 + easing.easingCubicInOut = (t) -> + if t < .5 then 4 * t * t * t else (t - 1) * (2 * t - 2) * (2 * t - 2) + 1 + easing.easingQuarticIn = (t) -> + t * t * t * t + easing.easingQuarticOut = (t) -> + 1 - (--t * t * t * t) + easing.easingQuarticInOut = (t) -> + if t < .5 then 8 * t * t * t * t else 1 - (8 * --t * t * t * t) + easing.easingQuinticIn = (t) -> + t * t * t * t * t + easing.easingQuinticOut = (t) -> + 1 + --t * t * t * t * t + easing.easingQuinticInOut = (t) -> + if t < .5 then 16 * t * t * t * t * t else 1 + 16 * --t * t * t * t * t + easing.easingCircularIn = (t) -> + -(Math.sqrt(1 - (t * t)) - 1) + easing.easingCircularOut = (t) -> + Math.sqrt 1 - ((t = t - 1) * t) + easing.easingCircularInOut = (t) -> + if (t *= 2) < 1 then -0.5 * (Math.sqrt(1 - (t * t)) - 1) else 0.5 * (Math.sqrt(1 - ((t -= 2) * t)) + 1) + easing.easingExponentialIn = (t) -> + 2 ** (10 * (t - 1)) - 0.001 + easing.easingExponentialOut = (t) -> + 1 - 2 ** (-10 * t) + easing.easingExponentialInOut = (t) -> + if (t *= 2) < 1 then 0.5 * 2 ** (10 * (t - 1)) else 0.5 * (2 - 2 ** (-10 * (t - 1))) + easing.easingBackIn = (t) -> + s = 1.70158 + t * t * ((s + 1) * t - s) + easing.easingBackOut = (t) -> + s = 1.70158 + --t * t * ((s + 1) * t + s) + 1 + easing.easingBackInOut = (t) -> + s = 1.70158 * 1.525 + if (t *= 2) < 1 + return 0.5 * t * t * ((s + 1) * t - s) + 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2) + easing.easingElasticIn = (t) -> + s = undefined + _kea = 0.1 + _kep = 0.4 + if t == 0 + return 0 + if t == 1 + return 1 + if !_kea or _kea < 1 + _kea = 1 + s = _kep / 4 + else + s = _kep * Math.asin(1 / _kea) / Math.PI * 2 + -(_kea * 2 ** (10 * (t -= 1)) * Math.sin((t - s) * Math.PI * 2 / _kep)) + easing.easingElasticOut = (t) -> + s = undefined + _kea = 0.1 + _kep = 0.4 + if t == 0 + return 0 + if t == 1 + return 1 + if !_kea or _kea < 1 + _kea = 1 + s = _kep / 4 + else + s = _kep * Math.asin(1 / _kea) / Math.PI * 2 + _kea * 2 ** (-10 * t) * Math.sin((t - s) * Math.PI * 2 / _kep) + 1 + easing.easingElasticInOut = (t) -> + s = undefined + _kea = 0.1 + _kep = 0.4 + if t == 0 + return 0 + if t == 1 + return 1 + if !_kea or _kea < 1 + _kea = 1 + s = _kep / 4 + else + s = _kep * Math.asin(1 / _kea) / Math.PI * 2 + if (t *= 2) < 1 + return -0.5 * _kea * 2 ** (10 * (t -= 1)) * Math.sin((t - s) * Math.PI * 2 / _kep) + _kea * 2 ** (-10 * (t -= 1)) * Math.sin((t - s) * Math.PI * 2 / _kep) * 0.5 + 1 + easing.easingBounceIn = (t) -> + 1 - easing.easingBounceOut(1 - t) + easing.easingBounceOut = (t) -> + if t < 1 / 2.75 + 7.5625 * t * t + else if t < 2 / 2.75 + 7.5625 * (t -= 1.5 / 2.75) * t + 0.75 + else if t < 2.5 / 2.75 + 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375 + else + 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375 + easing.easingBounceInOut = (t) -> + if t < 0.5 + return easing.easingBounceIn(t * 2) * 0.5 + easing.easingBounceOut(t * 2 - 1) * 0.5 + 0.5 + # single Tween object construct + Tween = (targetElement, startObject, endObject, options) -> + @element = if 'scroll' of endObject and (targetElement == undefined or targetElement == null) then scrollContainer else targetElement + # element animation is applied to + @playing = false + @reversed = false + @paused = false + @_startTime = null + @_pauseTime = null + @_startFired = false + @options = {} + for o of options + @options[o] = options[o] + @options.rpr = options.rpr or false + # internal option to process inline/computed style at start instead of init true/false + @valuesRepeat = {} + # internal valuesRepeat + @valuesEnd = {} + # valuesEnd + @valuesStart = {} + # valuesStart + preparePropertiesObject.call this, endObject, 'end' + # valuesEnd + if @options.rpr + @valuesStart = startObject + else + preparePropertiesObject.call this, startObject, 'start' + # valuesStart + if @options.perspective != undefined and transformProperty of @valuesEnd + # element transform perspective + perspectiveString = 'perspective(' + parseInt(@options.perspective) + 'px)' + @valuesEnd[transformProperty].perspective = perspectiveString + for e of @valuesEnd + if e of crossCheck and !@options.rpr + crossCheck[e].call this + # this is where we do the valuesStart and valuesEnd check for fromTo() method + @options.chain = [] + # chained Tweens + @options.easing = if options.easing and typeof processEasing(options.easing) == 'function' then processEasing(options.easing) else easing[defaultOptions.easing] + # you can only set a core easing function as default + @options.repeat = options.repeat or defaultOptions.repeat + @options.repeatDelay = options.repeatDelay or defaultOptions.repeatDelay + @options.yoyo = options.yoyo or defaultOptions.yoyo + @options.duration = options.duration or defaultOptions.duration + # duration option | default + @options.delay = options.delay or defaultOptions.delay + # delay option | default + @repeat = @options.repeat + # we cache the number of repeats to be able to put it back after all cycles finish + return + + TweenProto = Tween.prototype = + start: (t) -> + # move functions that use the ticker outside the prototype to be in the same scope with it + scrollIn.call this + if @options.rpr + getStartValues.apply this + # on start we reprocess the valuesStart for TO() method + perspective.apply this + # apply the perspective and transform origin + for e of @valuesEnd + if e of crossCheck and @options.rpr + crossCheck[e].call this + # this is where we do the valuesStart and valuesEnd check for to() method + @valuesRepeat[e] = @valuesStart[e] + # now it's a good time to start + tweens.push this + @playing = true + @paused = false + @_startFired = false + @_startTime = t or time.now() + @_startTime += @options.delay + if !@_startFired + if @options.start + @options.start.call() + @_startFired = true + !tick and ticker() + this + play: -> + if @paused and @playing + @paused = false + if @options.resume + @options.resume.call() + @_startTime += time.now() - (@_pauseTime) + add this + !tick and ticker() + # restart ticking if stopped + this + resume: -> + @play() + pause: -> + if !@paused and @playing + remove this + @paused = true + @_pauseTime = time.now() + if @options.pause + @options.pause.call() + this + stop: -> + if !@paused and @playing + remove this + @playing = false + @paused = false + scrollOut.call this + if @options.stop + @options.stop.call() + @stopChainedTweens() + close.call this + this + chain: -> + @options.chain = arguments + this + stopChainedTweens: -> + `var i` + i = 0 + ctl = @options.chain.length + while i < ctl + @options.chain[i].stop() + i++ + return + + TweensTO = (els, vE, o) -> + `var i` + # .to + @tweens = [] + options = [] + i = 0 + tl = els.length + while i < tl + options[i] = o or {} + o.delay = o.delay or defaultOptions.delay + options[i].delay = if i > 0 then o.delay + (o.offset or defaultOptions.offset) else o.delay + @tweens.push to(els[i], vE, options[i]) + i++ + return + + TweensFT = (els, vS, vE, o) -> + `var i` + # .fromTo + @tweens = [] + options = [] + i = 0 + l = els.length + while i < l + options[i] = o or {} + o.delay = o.delay or defaultOptions.delay + options[i].delay = if i > 0 then o.delay + (o.offset or defaultOptions.offset) else o.delay + @tweens.push fromTo(els[i], vS, vE, options[i]) + i++ + return + + ws = TweensTO.prototype = TweensFT.prototype = + start: (t) -> + `var i` + t = t or time.now() + i = 0 + tl = @tweens.length + while i < tl + @tweens[i].start t + i++ + this + stop: -> + `var i` + i = 0 + tl = @tweens.length + while i < tl + @tweens[i].stop() + i++ + this + pause: -> + `var i` + i = 0 + tl = @tweens.length + while i < tl + @tweens[i].pause() + i++ + this + chain: -> + @tweens[@tweens.length - 1].options.chain = arguments + this + play: -> + `var i` + i = 0 + tl = @tweens.length + while i < tl + @tweens[i].play() + i++ + this + resume: -> + @play() + + to = (element, endObject, options) -> + options = options or {} + options.rpr = true + new Tween(selector(element), endObject, endObject, options) + + fromTo = (element, startObject, endObject, options) -> + options = options or {} + new Tween(selector(element), startObject, endObject, options) + + allTo = (elements, endObject, options) -> + new TweensTO(selector(elements, true), endObject, options) + + allFromTo = (elements, f, endObject, options) -> + new TweensFT(selector(elements, true), f, endObject, options) + + { + property: property + getPrefix: getPrefix + selector: selector + processEasing: processEasing + defaultOptions: defaultOptions + to: to + fromTo: fromTo + allTo: allTo + allFromTo: allFromTo + ticker: ticker + tick: tick + tweens: tweens + update: update + dom: DOM + parseProperty: parseProperty + prepareStart: prepareStart + crossCheck: crossCheck + Tween: Tween + truD: trueDimension + truC: trueColor + rth: rgbToHex + htr: hexToRGB + getCurrentStyle: getCurrentStyle + } diff --git a/demo/assets/css/kute.css b/demo/assets/css/kute.css deleted file mode 100644 index 25b4ca5..0000000 --- a/demo/assets/css/kute.css +++ /dev/null @@ -1,1223 +0,0 @@ -/*! - * KUTE.js | https://github.com/thednp/kute.js/ - * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) - */ - -/* GLOBAL STYLES --------------------------------------------------- */ -body { - color: #ccc; - background-color: #08263d; - position: relative -} - -.condensed { - font-family: "Roboto Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: normal !important -} - -/* smooth scroll */ -html { - scroll-behavior: smooth; -} - -/* WRAPPER STYLES --------------------------------------------------- */ -.content-wrap { max-width: 80%; position: relative; margin: 0 auto; clear: both; } - -@media (min-width: 1020px){ - .content-wrap { max-width: 100%; width: 980px; } -} - -/* check div consistency -div { background-color: rgba(0,0,0,0.2) }*/ - -/* TYPO STYLES --------------------------------------------------- */ -p, ul, ol { margin: 0 0 12px } -h1, h2, h3, h4, strong {color: #fff} -h1, h2, h3, h4, h5 { margin: 24px 0; font-weight: bold; } -h1 { font-size: 54px; letter-spacing:-2px; line-height: 48px; } -h2 { font-size: 46px; letter-spacing:-1px; line-height: 48px; } -h3 { font-size: 32px; letter-spacing:-1px; line-height: 36px; } -h4 { font-size: 24px; letter-spacing: 0px; } -/* h1, h3, [class*="col"] > h4 {margin: 0 0 20px} */ - -h1.border, -h2.border, -h3.border, -.lead.border { - padding-bottom: 24px; - margin-bottom: 24px; - border-bottom: 1px solid rgba(150,150,150,0.5) -} - -.text-right { text-align: right } -.text-center { text-align: center } -.text-left { text-align: left } - -.float-left {float:left} -.float-right {float:right} - -.margin-bottom { margin-bottom: 24px !important; } - -.lead { font-size: 18px; color: #fff } - -.nomargin { margin: 0px !important } -@media (min-width: 768px){ - .nomarginlarge { margin: 0 !important } -} - -b,strong {font-weight: 600;color:white} - -footer { - clear: both; overflow: hidden; margin-top: 60px -} - -footer .content-wrap { - padding-top: 5px; - border-top: 1px solid rgb(120,120,120); - border-top: 1px solid rgba(255,255,255,0.2); -} - -footer p {margin: 0 0 10px} - -/* site-wrapper */ -.site-wrapper { position: relative; overflow: hidden; } - -.head-title { margin-top: 60px } - -/* navbar */ -.navbar { - display: flex; - /* justify-content: space-evenly; */ - flex-direction: column; -} - -@media (min-width:768px) { - .navbar { - align-items: center; - flex-direction: row; - } -} - -.nav-wrapper { - flex-basis: 100% -} -.navbar-wrapper { position: relative; clear: both; background: rgba(0,0,0,0.7); padding-bottom: 20px; } -.navbar-wrapper .content-wrap { padding: 20px 0 0; } - -.navbar-wrapper h1 { - color: #fff; - font-size: 32px; line-height: 24px; letter-spacing: 0px; - float: left; padding-right: 24px; margin-right: 24px; margin-top:0; margin-bottom: 0; - border-right: 1px solid rgba(255,255,255,0.2) -} -.navbar-wrapper h1 span { font-size: 24px; color: #555; letter-spacing: -1px; } -.navbar-wrapper h1.active span { color: #ffd626 } -.navbar-wrapper .nav { padding: 0; margin: 0; display: flex; flex-direction: row; } -.nav > li { display: block; line-height: 25px; list-style: none } -.nav > li:not(:last-child) { margin-right: 12px } -.nav li.active > a { color: #ffd626 } -.nav li a { color: #ccc } -.nav li a:hover, .nav li a:focus { text-decoration: none } - -/* share */ -#share { display: flex; flex-direction: row; margin: 0; padding: 0 } -#share li { list-style: none } -#share a { text-decoration: none; } -#share .icon {width:26px; height:26px; vertical-align: middle;} -#share path { fill: none; stroke: currentColor; stroke-width: 50; } -#share li:not(:last-child) { margin-right: 10px; } -#share li:hover path { fill: currentColor; } -#share li:hover a.facebook-link { color: #3578E5} -#share li:hover a.twitter-link { color: #1da1f2 } - - -@media (max-width: 768px){ - .navbar-wrapper h1 {border: 0} - .navbar-wrapper .nav, - .navbar-wrapper h1 { float: none; } -} - - - -/* featurettes */ -.featurettes { - background: #fff; - padding: 60px 0; - width: 100%; - clear: both; - margin: 60px 0; - float: left; - color: #777; -} -/*.featurettes.dark {background: #222}*/ -.featurettes h1, -.featurettes h2, -.featurettes h3, -.featurettes h4, -.featurettes b, -.featurettes .lead, -.featurettes strong {color: #222;} -.featurettes a {color: #2196F3} - -.content-wrap .featurettes { margin: 0 0 20px; padding: 20px 0 0 20px; display: inline-block; border-radius: 10px; position: relative } - -/* example box */ -.example-box { - font-size: 40px; line-height: 150px; text-align:center; font-weight: bold; - float: left; position:relative; - width: 150px; height: 150px; - border-radius: 5px; margin: 0 20px 20px 0; - color: white -} -/*.example-box-model { - font-size: 40px; text-align:center; font-weight: bold; - float: left; position:relative; - border-radius: 5px; margin: 0 20px 20px 0; -} - -svg.example-box { width: auto; height: auto; }*/ - -.easing-example {float: none; font-size: 24px; width: 320px} -.example-buttons {position: absolute; top: 18px; right:0} -.example-buttons + .example-buttons { top: auto; bottom: 18px} - -/* text properties example */ -h1.example-item { - font-size: 50px; - line-height:50px; - color: #333; - /* opacity: 0; */ -} - -h1.example-item span { - line-height: inherit; - display: inline; - vertical-align: top; -} - - - -/* UTILITY STYLES --------------------------------------------------- */ -.clearfix:before, -.clearfix:after { - content: " "; - display: table; -} -.clearfix:after { - clear: both; -} -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.text-olive { color: #9C27B0;} -.text-indigo { color: #673AB7;} -.text-green { color: #4CAF50;} -.text-red { color: #e91b1f;} -.text-yellow { color: #ffd626;} -.text-blue { color: #2196F3;} -.text-pink { color: #E91E63;} -.text-orange { color: #FF5722;} -.text-lime { color: #CDDC39;} -.text-teal { color: #009688;} -.text-strong { font-weight: bold } - -.hidden { - display: none !important; - visibility: hidden !important; -} - -.hiddenoverflow { overflow: hidden } - -.media {float: left; margin: 5px 20px 0 0; height: auto; font-size: 64px; line-height: 64px; width: 64px; text-align: center} - -/* COLUMN STYLES --------------------------------------------------- */ -.columns { position: relative; width: 100%; margin: 0 -20px; display:flex; flex-wrap: wrap; } -.columns > [class*="col"] { padding: 0 20px; position: relative } -.columns.welcome {min-height:330px} - -@media (min-width: 768px){ - .columns { flex-direction: row; flex-wrap: wrap } - .columns.welcome {min-height:none} - - - .col2 { max-width: 50%; flex: 0 0 50% } - .col3 { max-width: 33.33%; flex: 0 0 33.33% } - .col4 { max-width: 25%; flex: 0 0 25% } - .col8 { max-width: 75%; flex: 0 0 75% } - .col9 { max-width: 66.65%; flex: 0 0 66.65% } -} - -.table { display: table; height: 480px } -.cell { display: table-cell; vertical-align: middle } - -@media (max-width: 479px){ - .table { height: 320px } -} -@media (min-width: 480px) { - [class*="col"].border:not(:first-child) { - border-left: 1px solid rgba(150,150,150,0.5); - } -} - - -/* STYLING CONTENT --------------------------------------------------- */ -/* images */ -img { max-width: 100% } -img.circle { border-radius: 50% } - -/* links */ -a { - color: #ffd626; - text-decoration: none; -} -a:hover, -a:focus { - color: #4CAF50; - text-decoration: underline; -} -a:focus { - outline: none; -} - -hr { - border: 1px solid #444; - margin: 10px 0; -} - -/* buttons */ -.btns { - display: inline-flex; - flex: 1 1 auto; - justify-content: center; - text-align: center; -} -.btns .btn { display:inline; line-height: 1; margin: 0 3px 3px 0;} -.btn { padding: 12px 15px; color:#fff; border:0; background-color: #999; line-height: 44px; } -.bg-gray { color:#fff; background-color: #555; fill: #555 } -.btn.active { background-color: #2196F3 } -.featurettes .btn, .featurettes .btn:hover, .featurettes .btn:active, .featurettes .btn:focus, -.btn:hover, .btn:active, .btn:focus { color: #fff; } -.btn:hover, .btn:active, .btn:focus { text-decoration: none; background-color: #777} -.btn-olive, .bg-olive {background-color: #9C27B0; color: #fff; fill: #9C27B0} .btn-olive:hover, .btn-olive:active, .btn-olive:focus { background-color: #FF5722 } -.btn-indigo, .bg-indigo { background-color: #673AB7; color: #fff; fill: #673AB7} .btn-indigo:hover, .btn-indigo:active, .btn-indigo:focus { background-color: #ffd626; color:#000 } -.btn-green, .bg-green { background-color: #4CAF50; color: #fff; fill: #4CAF50} .btn-green:hover, .btn-green:active, .btn-green:focus { background-color: #9C27B0 } -.btn-red, .bg-red { background-color: #e91b1f; color: #fff; fill: #e91b1f} .btn-red:hover, .btn-red:active, .btn-red:focus { background-color: #4CAF50 } -.btn-yellow, .bg-yellow { background-color: #ffd626; color:#000 !important; fill: #ffd626} .btn-yellow:hover, .btn-yellow:active, .btn-yellow:focus { background-color: #4CAF50; color: #fff !important } -.btn-blue, .bg-blue { background-color: #2196F3; color: #fff; fill: #2196F3} .btn-blue:hover, .btn-blue:active, .btn-blue:focus { background-color: #e91b1f } -.btn-pink, .bg-pink { background-color: #E91E63; color: #fff; fill: #E91E63} .btn-pink:hover, .btn-pink:active, .btn-pink:focus { background-color: #2196F3 } -.btn-orange, .bg-orange { background-color: #FF5722; color: #fff; fill: #FF5722} .btn-orange:hover, .btn-orange:active, .btn-orange:focus { background-color: #4CAF50 } -.btn-lime, .bg-lime { background-color: #CDDC39; color: #000; fill: #CDDC39} .btn-lime:hover, .btn-lime:active, .btn-lime:focus { background-color: #e91b1f } -.btn-teal, .bg-teal { background-color: #009688; color: #fff; fill: #009688} .btn-teal:hover, .btn-teal:active, .btn-teal:focus { background-color: #9C27B0 } - -.bg-light {background-color: #fff; color: #777; fill: #fff} - -.icon-large { font-size: 78px; line-height: 0.64; text-shadow: 2px 2px 0 #FFF,3px 3px 0px #ccc;} -.icon-large.fa-cogs:before { color: #4CAF50 } -.icon-large.fa-rocket:before { color: #673AB7 } -.icon-large.fa-code-fork:before { color: #9C27B0 } - -.btn span { - font-size: 150%; - vertical-align: middle; -} - -.btn span.right { margin: 0 0 0 10px } -.btn span.left { margin: 0 10px 0 0 } - -.btn-group { position: relative; display: inline-block } -.btn-group ul { - background: #555; width: 200px; color: #ccc; - position: absolute; bottom: -9999em; left: 0; list-style: none; - overflow: auto; padding: 0; z-index: 5 -} -.btn-group ul li { padding: 5px 15px; cursor: pointer; display: block } -.btn-group ul.subnav li { padding: 0; } -.btn-group ul.subnav li > a { padding: 5px 15px; display: block } -.btn-group ul li.titlef { font-weight: bold; } -.btn-group ul li:hover { - background: #333; -} - -.btn-group.open ul { - bottom: 26px; -} -.nav .btn-group ul {bottom: auto; top: -999em} -.nav .btn-group.open ul { - top: 36px; -} -@media (max-width: 768px){ - .nav .btn-group.open ul { - top: 30px; - } - #easings {left: auto; right: 0} -} - -/* Style the scrolBar for modern browsers */ -.btn-group ul::-webkit-scrollbar { - width: 7px; -} -.btn-group ul::-webkit-scrollbar-thumb { - -webkit-border-radius: 3px; - border-radius: 3px; - background: rgba(92,92,92,0.8); - box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5); -} -.btn-group ul::-webkit-scrollbar-thumb:window-inactive { - background: rgba(255,255,255,0.4); -} - -/* caret */ -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px dashed; - border-top: 4px solid\9; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} - -/* STYLE CODE WRAPPING --------------------------------------------------- */ -code, kbd, pre { - font-family: Menlo,Monaco,Consolas,"Courier New",monospace; -} -pre { - display: block; - padding: 10px 15px !important; - margin: 0 0 20px !important; - line-height: 2.08; - color: #999; - word-break: break-all; - background-color: rgb(33,33,33); - background-color: rgba(11,11,11,0.5); - /*border: 1px solid rgb(22,22,22); - border: 1px solid rgba(11,11,11,0.8);*/ - border-radius: 4px; - text-align: left; - position: relative; - font-size: 15px; -} -pre.language-javascript:after, -pre.language-clike:after, -pre.language-markup:after { - position: absolute; top:0; right:0; padding: 2px 5px; - background: #000; - border-radius: 0px 0px 0px 5px; - font-family: Helvetica, Arial, sans-serif; - font-size: 12px; color: #999; -} - -pre.language-javascript:after {content: 'JavaScript';} -pre.language-clike:after {content: 'node';} -pre.language-markup:after {content: 'HTML';} -pre code {background: none;padding: 0; font-weight: normal; font-size: 100%;} -code { - padding: 2px 4px; - font-size: 90%; - color: #999; - background-color: #111; - border-radius: 4px; - white-space: pre; - font-weight: bold -} - -kbd { - padding: 2px 4px; - font-size: 90%; - color: #333; - background-color: #eee; - border-radius: 3px; - font-weight: bold -} - -#rectangle {transform-origin: 50% 50%;} - -.w-20{ - width:20% !important -} -.w-25{ - width:25% !important -} -.w-33{ - width:33.33% !important -} -.w-50{ - width:50% !important -} -.w-66{ - width:66.67% !important -} -.w-75{ - width:75% !important -} -.w-80{ - width:80% !important -} -.w-100{ - width:100% !important -} -.w-auto{ - width:auto !important -} -.h-20vh{ - height:20vh !important -} -.h-25vh{ - height:25vh !important -} -.h-33vh{ - height:33.33vh !important -} -.h-50vh{ - height:50vh !important -} -.h-66vh{ - height:66.67vh !important -} -.h-75vh{ - height:75vh !important -} -.h-80vh{ - height:80vh !important -} -.h-100{ - height:100% !important -} -.h-auto{ - height:auto !important -} -@media(min-width: 768px){ - .w-md-20{ - width:20% !important - } - .w-md-25{ - width:25% !important - } - .w-md-33{ - width:33.33% !important - } - .w-md-50{ - width:50% !important - } - .w-md-66{ - width:66.67% !important - } - .w-md-75{ - width:75% !important - } - .w-md-80{ - width:80% !important - } - .w-md-100{ - width:100% !important - } - .w-md-auto{ - width:auto !important - } - .h-md-20vh{ - height:20vh !important - } - .h-md-25vh{ - height:25vh !important - } - .h-md-33vh{ - height:33.33vh !important - } - .h-md-50vh{ - height:50vh !important - } - .h-md-66vh{ - height:66.67vh !important - } - .h-md-75vh{ - height:75vh !important - } - .h-md-80vh{ - height:80vh !important - } - .h-md-100{ - height:100% !important - } - .h-md-auto{ - height:auto !important - } -} -.d-none{ - display:none -} -.d-inline{ - display:inline -} -.d-flex{ - display:flex -} -.d-block{ - display:block -} -@media(min-width: 768px){ - .d-md-none{ - display:none - } - .d-md-inline{ - display:inline - } - .d-md-flex{ - display:flex - } - .d-md-block{ - display:block - } -} -.flex-row{ - flex-direction:row -} -.flex-row-reverse{ - flex-direction:row-reverse -} -.flex-column{ - flex-direction:column -} -.flex-column-reverse{ - flex-direction:column-reverse -} -.align-items-start{ - align-items:flex-start -} -.align-items-end{ - align-items:flex-end -} -.align-items-center{ - align-items:center -} -.align-items-baseline{ - align-items:baseline -} -.align-items-stretch{ - align-items:stretch -} -.align-self-start{ - align-self:flex-start -} -.align-self-end{ - align-self:flex-end -} -.align-self-center{ - align-self:center -} -.align-self-baseline{ - align-self:baseline -} -.align-self-stretch{ - align-self:stretch -} -.justify-content-start{ - justify-content:flex-start -} -.justify-content-end{ - justify-content:flex-end -} -.justify-content-center{ - justify-content:center -} -.justify-content-between{ - justify-content:space-between -} -.justify-content-around{ - justify-content:space-around -} -.align-content-start{ - align-content:flex-start -} -.align-content-end{ - align-content:flex-end -} -.align-content-center{ - align-content:center -} -.align-content-around{ - align-content:space-around -} -.align-content-stretch{ - align-content:stretch -} -.flex-fill{ - flex:1 1 auto !important -} -.flex-grow-1{ - flex-grow:1 -} -.flex-grow-0{ - flex-grow:0 -} -.flex-shrink-1{ - flex-shrink:1 -} -.flex-shrink-0{ - flex-shrink:0 -} -.flex-nowrap{ - flex-wrap:nowrap -} -.flex-wrap{ - flex-wrap:wrap -} -.flex-wrap-reverse{ - flex-wrap:wrap-reverse -} -@media(min-width: 768px){ - .flex-md-row{ - flex-direction:row - } - .flex-md-row-reverse{ - flex-direction:row-reverse - } - .flex-md-column{ - flex-direction:column - } - .flex-md-column-reverse{ - flex-direction:column-reverse - } - .align-items-md-start{ - align-items:flex-start - } - .align-items-md-end{ - align-items:flex-end - } - .align-items-md-center{ - align-items:center - } - .align-items-md-baseline{ - align-items:baseline - } - .align-items-md-stretch{ - align-items:stretch - } - .align-self-md-start{ - align-self:flex-start - } - .align-self-md-end{ - align-self:flex-end - } - .align-self-md-center{ - align-self:center - } - .align-self-md-baseline{ - align-self:baseline - } - .align-self-md-stretch{ - align-self:stretch - } - .justify-content-md-start{ - justify-content:flex-start - } - .justify-content-md-end{ - justify-content:flex-end - } - .justify-content-md-center{ - justify-content:center - } - .justify-content-md-between{ - justify-content:space-between - } - .justify-content-md-around{ - justify-content:space-around - } - .flex-md-fill{ - flex:1 1 auto !important - } - .flex-md-grow-1{ - flex-grow:1 - } - .flex-md-grow-0{ - flex-grow:0 - } - .flex-md-shrink-1{ - flex-shrink:1 - } - .flex-md-shrink-0{ - flex-shrink:0 - } - .flex-md-nowrap{ - flex-wrap:nowrap - } - .flex-md-wrap{ - flex-wrap:wrap - } - .flex-md-wrap-reverse{ - flex-wrap:wrap-reverse - } -} - -.overflow-visible{ - overflow:visible -} -.overflow-hidden{ - overflow:hidden -} -.perspective{ - perspective:500px; - backface-visibility:hidden -} -.perspective-1000{ - perspective:1000px; - backface-visibility:hidden -} -.perspective-1500{ - perspective:1500px; - backface-visibility:hidden -} -.m-0{ - margin:0 !important -} -.m-1{ - margin:.25rem !important -} -.m-2{ - margin:.5rem !important -} -.m-3{ - margin:1rem !important -} -.m-4{ - margin:1.5rem !important -} -.m-5{ - margin:3rem !important -} -.m-auto{ - margin:auto !important -} -.mx-0{ - margin-right:0 !important; - margin-left:0 !important -} -.mx-1{ - margin-right:.25rem !important; - margin-left:.25rem !important -} -.mx-2{ - margin-right:.5rem !important; - margin-left:.5rem !important -} -.mx-3{ - margin-right:1rem !important; - margin-left:1rem !important -} -.mx-4{ - margin-right:1.5rem !important; - margin-left:1.5rem !important -} -.mx-5{ - margin-right:3rem !important; - margin-left:3rem !important -} -.mx-auto{ - margin-right:auto !important; - margin-left:auto !important -} -.my-0{ - margin-top:0 !important; - margin-bottom:0 !important -} -.my-1{ - margin-top:.25rem !important; - margin-bottom:.25rem !important -} -.my-2{ - margin-top:.5rem !important; - margin-bottom:.5rem !important -} -.my-3{ - margin-top:1rem !important; - margin-bottom:1rem !important -} -.my-4{ - margin-top:1.5rem !important; - margin-bottom:1.5rem !important -} -.my-5{ - margin-top:3rem !important; - margin-bottom:3rem !important -} -.my-auto{ - margin-top:auto !important; - margin-bottom:auto !important -} -.mt-0{ - margin-top:0 !important -} -.mt-1{ - margin-top:.25rem !important -} -.mt-2{ - margin-top:.5rem !important -} -.mt-3{ - margin-top:1rem !important -} -.mt-4{ - margin-top:1.5rem !important -} -.mt-5{ - margin-top:3rem !important -} -.mt-auto{ - margin-top:auto !important -} -.mr-0{ - margin-right:0 !important -} -.mr-1{ - margin-right:.25rem !important -} -.mr-2{ - margin-right:.5rem !important -} -.mr-3{ - margin-right:1rem !important -} -.mr-4{ - margin-right:1.5rem !important -} -.mr-5{ - margin-right:3rem !important -} -.mr-auto{ - margin-right:auto !important -} -.mb-0{ - margin-bottom:0 !important -} -.mb-1{ - margin-bottom:.25rem !important -} -.mb-2{ - margin-bottom:.5rem !important -} -.mb-3{ - margin-bottom:1rem !important -} -.mb-4{ - margin-bottom:1.5rem !important -} -.mb-5{ - margin-bottom:3rem !important -} -.mb-auto{ - margin-bottom:auto !important -} -.ml-0{ - margin-left:0 !important -} -.ml-1{ - margin-left:.25rem !important -} -.ml-2{ - margin-left:.5rem !important -} -.ml-3{ - margin-left:1rem !important -} -.ml-4{ - margin-left:1.5rem !important -} -.ml-5{ - margin-left:3rem !important -} -.ml-auto{ - margin-left:auto !important -} -.p-0{ - padding:0 !important -} -.p-1{ - padding:.25rem !important -} -.p-2{ - padding:.5rem !important -} -.p-3{ - padding:1rem !important -} -.p-4{ - padding:1.5rem !important -} -.p-5{ - padding:3rem !important -} -.px-0{ - padding-right:0 !important; - padding-left:0 !important -} -.px-1{ - padding-right:.25rem !important; - padding-left:.25rem !important -} -.px-2{ - padding-right:.5rem !important; - padding-left:.5rem !important -} -.px-3{ - padding-right:1rem !important; - padding-left:1rem !important -} -.px-4{ - padding-right:1.5rem !important; - padding-left:1.5rem !important -} -.px-5{ - padding-right:3rem !important; - padding-left:3rem !important -} -.py-0{ - padding-top:0 !important; - padding-bottom:0 !important -} -.py-1{ - padding-top:.25rem !important; - padding-bottom:.25rem !important -} -.py-2{ - padding-top:.5rem !important; - padding-bottom:.5rem !important -} -.py-3{ - padding-top:1rem !important; - padding-bottom:1rem !important -} -.py-4{ - padding-top:1.5rem !important; - padding-bottom:1.5rem !important -} -.py-5{ - padding-top:3rem !important; - padding-bottom:3rem !important -} -.pt-0{ - padding-top:0 !important -} -.pt-1{ - padding-top:.25rem !important -} -.pt-2{ - padding-top:.5rem !important -} -.pt-3{ - padding-top:1rem !important -} -.pt-4{ - padding-top:1.5rem !important -} -.pt-5{ - padding-top:3rem !important -} -.pr-0{ - padding-right:0 !important -} -.pr-1{ - padding-right:.25rem !important -} -.pr-2{ - padding-right:.5rem !important -} -.pr-3{ - padding-right:1rem !important -} -.pr-4{ - padding-right:1.5rem !important -} -.pr-5{ - padding-right:3rem !important -} -.pb-0{ - padding-bottom:0 !important -} -.pb-1{ - padding-bottom:.25rem !important -} -.pb-2{ - padding-bottom:.5rem !important -} -.pb-3{ - padding-bottom:1rem !important -} -.pb-4{ - padding-bottom:1.5rem !important -} -.pb-5{ - padding-bottom:3rem !important -} -.pl-0{ - padding-left:0 !important -} -.pl-1{ - padding-left:.25rem !important -} -.pl-2{ - padding-left:.5rem !important -} -.pl-3{ - padding-left:1rem !important -} -.pl-4{ - padding-left:1.5rem !important -} -.pl-5{ - padding-left:3rem !important -} -.vertical-align-top{ - vertical-align:top -} -.vertical-align-middle{ - vertical-align:middle -} -.vertical-align-bottom{ - vertical-align:bottom -} -.vertical-align-baseline{ - vertical-align:baseline -} -.vertical-align-text-top{ - vertical-align:text-top -} -.vertical-align-text-bottom{ - vertical-align:text-bottom -} -@media(min-width: 768px){ - .vertical-align-md-top{ - vertical-align:top - } - .vertical-align-md-middle{ - vertical-align:middle - } - .vertical-align-md-bottom{ - vertical-align:bottom - } - .vertical-align-md-baseline{ - vertical-align:baseline - } - .vertical-align-md-text-top{ - vertical-align:text-top - } - .vertical-align-md-text-bottom{ - vertical-align:text-bottom - } -} -.b-position-center-top{ - background-position:center top !important -} -.b-position-center{ - background-position:center center !important -} -.b-position-center-bottom{ - background-position:center bottom !important -} -.b-position-left-top{ - background-position:left top !important -} -.b-position-left-center{ - background-position:left center !important -} -.b-position-left-bottom{ - background-position:left bottom !important -} -.b-position-right-top{ - background-position:right top !important -} -.b-position-right-center{ - background-position:right center !important -} -.b-position-right-bottom{ - background-position:right bottom !important -} -@media screen and (-ms-high-contrast: active),(-ms-high-contrast: none){ - .h-20vh{ - height:216px !important - } - .h-25vh{ - height:270px !important - } - .h-33vh{ - height:359.964px !important - } - .h-50vh{ - height:540px !important - } - .h-66vh{ - height:720.036px !important - } - .h-75vh{ - height:810px !important - } - .h-80vh{ - height:864px !important - } - .h-100{ - height:100% !important - } - .h-auto{ - height:auto !important - } -} -@media screen and (-ms-high-contrast: active)and (min-width: 768px),(-ms-high-contrast: none)and (min-width: 768px){ - .h-md-20vh{ - height:216px !important - } - .h-md-25vh{ - height:270px !important - } - .h-md-33vh{ - height:359.964px !important - } - .h-md-50vh{ - height:540px !important - } - .h-md-66vh{ - height:720.036px !important - } - .h-md-75vh{ - height:810px !important - } - .h-md-80vh{ - height:864px !important - } - .h-md-100{ - height:100% !important - } - .h-md-auto{ - height:auto !important - } -} diff --git a/demo/assets/css/prism.css b/demo/assets/css/prism.css deleted file mode 100644 index b6092ab..0000000 --- a/demo/assets/css/prism.css +++ /dev/null @@ -1,226 +0,0 @@ -/* PrismJS 1.20.0 -https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+scss&plugins=line-highlight+line-numbers */ -/** - * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML - * Based on https://github.com/chriskempson/tomorrow-theme - * @author Rose Pritchard - */ - -code[class*="language-"], -pre[class*="language-"] { - color: #ccc; - background: none; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - font-size: 1em; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #051725; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; -} - -.token.comment, -.token.block-comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: #999; -} - -.token.punctuation { - color: #ccc; -} - -.token.tag, -.token.attr-name, -.token.namespace, -.token.deleted { - color: #e2777a; -} - -.token.function-name { - color: #6196cc; -} - -.token.boolean, -.token.number, -.token.function { - color: #f08d49; -} - -.token.property, -.token.class-name, -.token.constant, -.token.symbol { - color: #f8c555; -} - -.token.selector, -.token.important, -.token.atrule, -.token.keyword, -.token.builtin { - color: #cc99cd; -} - -.token.string, -.token.char, -.token.attr-value, -.token.regex, -.token.variable { - color: #7ec699; -} - -.token.operator, -.token.entity, -.token.url { - color: #67cdcc; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - -.token.inserted { - color: green; -} - -pre[data-line] { - position: relative; - padding: 1em 0 1em 3em; -} - -.line-highlight { - position: absolute; - left: 0; - right: 0; - padding: inherit 0; - margin-top: 1em; /* Same as .prism’s padding-top */ - - background: hsla(24, 20%, 50%,.08); - background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0)); - - pointer-events: none; - - line-height: inherit; - white-space: pre; -} - - .line-highlight:before, - .line-highlight[data-end]:after { - content: attr(data-start); - position: absolute; - top: .4em; - left: .6em; - min-width: 1em; - padding: 0 .5em; - background-color: hsla(24, 20%, 50%,.4); - color: hsl(24, 20%, 95%); - font: bold 65%/1.5 sans-serif; - text-align: center; - vertical-align: .3em; - border-radius: 999px; - text-shadow: none; - box-shadow: 0 1px white; - } - - .line-highlight[data-end]:after { - content: attr(data-end); - top: auto; - bottom: .4em; - } - -.line-numbers .line-highlight:before, -.line-numbers .line-highlight:after { - content: none; -} - -pre[id].linkable-line-numbers span.line-numbers-rows { - pointer-events: all; -} -pre[id].linkable-line-numbers span.line-numbers-rows > span:before { - cursor: pointer; -} -pre[id].linkable-line-numbers span.line-numbers-rows > span:hover:before { - background-color: rgba(128, 128, 128, .2); -} - -pre[class*="language-"].line-numbers { - position: relative; - padding-left: 3.8em; - counter-reset: linenumber; -} - -pre[class*="language-"].line-numbers > code { - position: relative; - white-space: inherit; -} - -.line-numbers .line-numbers-rows { - position: absolute; - pointer-events: none; - top: 0; - font-size: 100%; - left: -3.8em; - width: 3em; /* works for line-numbers below 1000 lines */ - letter-spacing: -1px; - border-right: 1px solid #999; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -} - - .line-numbers-rows > span { - display: block; - counter-increment: linenumber; - } - - .line-numbers-rows > span:before { - content: counter(linenumber); - color: #999; - display: block; - padding-right: 0.8em; - text-align: right; - } - diff --git a/demo/assets/css/reset.css b/demo/assets/css/reset.css deleted file mode 100644 index 789f37e..0000000 --- a/demo/assets/css/reset.css +++ /dev/null @@ -1,305 +0,0 @@ -*,*::before,*::after{ - box-sizing:border-box -} -body{ - margin:0; - font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; - font-size:1rem; - font-weight:400; - line-height:1.5; - color:#212529; - background-color:#fff; - -webkit-text-size-adjust:100%; - -webkit-tap-highlight-color:rgba(0,0,0,0) -} -[tabindex="-1"]:focus:not(:focus-visible){ - outline:0 !important -} -hr{ - margin:1rem 0; - color:inherit; - background-color:currentColor; - border:0; - opacity:.25 -} -hr:not([size]){ - height:1px -} -h1,h2,h3,h4,h5,h6{ - margin-top:0; - font-weight:500; - line-height:1.2 -} -h1{ - font-size:calc(1.375rem + 1.5vw) -} -@media(min-width: 1200px){ - h1{ - font-size:2.5rem - } -} -h2{ - font-size:calc(1.325rem + 0.9vw) -} -@media(min-width: 1200px){ - h2{ - font-size:2rem - } -} -h3{ - font-size:calc(1.3rem + 0.6vw) -} -@media(min-width: 1200px){ - h3{ - font-size:1.75rem - } -} -h4{ - font-size:calc(1.275rem + 0.3vw) -} -@media(min-width: 1200px){ - h4{ - font-size:1.5rem - } -} -h5{ - font-size:1.25rem -} -h6{ - font-size:1rem -} -p{ - margin-top:0; - margin-bottom:1rem -} -abbr[title],abbr[data-original-title]{ - text-decoration:underline; - -webkit-text-decoration:underline dotted; - text-decoration:underline dotted; - cursor:help; - -webkit-text-decoration-skip-ink:none; - text-decoration-skip-ink:none -} -address{ - margin-bottom:1rem; - font-style:normal; - line-height:inherit -} -ol,ul{ - padding-left:2rem -} -ol,ul,dl{ - margin-top:0; - margin-bottom:1rem -} -ol ol,ul ul,ol ul,ul ol{ - margin-bottom:0 -} -dt{ - font-weight:700 -} -dd{ - margin-bottom:.5rem; - margin-left:0 -} -blockquote{ - margin:0 0 1rem -} -b,strong{ - font-weight:bolder -} -small{ - font-size:.875em -} -mark{ - padding:.2em; - background-color:#fcf8e3 -} -sub,sup{ - position:relative; - font-size:.75em; - line-height:0; - vertical-align:baseline -} -sub{ - bottom:-0.25em -} -sup{ - top:-0.5em -} -a{ - color:#0d6efd; - text-decoration:underline -} -a:hover{ - color:#024dbc -} -a:not([href]):not([class]),a:not([href]):not([class]):hover{ - color:inherit; - text-decoration:none -} -pre,code,kbd,samp{ - font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; - font-size:1em -} -pre{ - display:block; - margin-top:0; - margin-bottom:1rem; - overflow:auto; - font-size:.875em; - -ms-overflow-style:scrollbar -} -pre code{ - font-size:inherit; - color:inherit; - word-break:normal -} -code{ - font-size:.875em; - color:#d63384; - word-wrap:break-word -} -a>code{ - color:inherit -} -kbd{ - padding:.2rem .4rem; - font-size:.875em; - color:#fff; - background-color:#212529; - border-radius:.2rem -} -kbd kbd{ - padding:0; - font-size:1em; - font-weight:700 -} -figure{ - margin:0 0 1rem -} -img,svg{ - vertical-align:middle -} -table{ - caption-side:bottom; - border-collapse:collapse -} -caption{ - padding-top:.5rem; - padding-bottom:.5rem; - color:#6c757d; - text-align:left -} -th{ - text-align:inherit; - text-align:-webkit-match-parent -} -thead,tbody,tfoot,tr,td,th{ - border-color:inherit; - border-style:solid; - border-width:0 -} -label{ - display:inline-block -} -button{ - border-radius:0 -} -button:focus{ - outline:1px dotted; - outline:5px auto -webkit-focus-ring-color -} -input,button,select,optgroup,textarea{ - margin:0; - font-family:inherit; - font-size:inherit; - line-height:inherit -} -button,input{ - overflow:visible -} -button,select{ - text-transform:none -} -[role=button]{ - cursor:pointer -} -select{ - word-wrap:normal -} -[list]::-webkit-calendar-picker-indicator{ - display:none -} -button,[type=button],[type=reset],[type=submit]{ - -webkit-appearance:button -} -button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){ - cursor:pointer -} -::-moz-focus-inner{ - padding:0; - border-style:none -} -textarea{ - resize:vertical -} -fieldset{ - min-width:0; - padding:0; - margin:0; - border:0 -} -legend{ - float:left; - width:100%; - padding:0; - margin-bottom:.5rem; - font-size:calc(1.275rem + 0.3vw); - line-height:inherit; - white-space:normal -} -@media(min-width: 1200px){ - legend{ - font-size:1.5rem - } -} -legend+*{ - clear:left -} -::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{ - padding:0 -} -::-webkit-inner-spin-button{ - height:auto -} -[type=search]{ - outline-offset:-2px; - -webkit-appearance:textfield -} -::-webkit-search-decoration{ - -webkit-appearance:none -} -::-webkit-color-swatch-wrapper{ - padding:0 -} -::-webkit-file-upload-button{ - font:inherit; - -webkit-appearance:button -} -output{ - display:inline-block -} -iframe{ - border:0 -} -summary{ - display:list-item; - cursor:pointer -} -progress{ - vertical-align:baseline -} -[hidden]{ - display:none !important -} \ No newline at end of file diff --git a/demo/assets/css/spicr-theme.css b/demo/assets/css/spicr-theme.css deleted file mode 100644 index a92055f..0000000 --- a/demo/assets/css/spicr-theme.css +++ /dev/null @@ -1,172 +0,0 @@ -/* Spicr theme | thednp © 2020 | MIT-License */ - -.text-left{ - text-align:left -} -.text-center{ - text-align:center -} -.text-right{ - text-align:right -} -@media(min-width: 768px){ - .text-md-left{ - text-align:left - } - .text-md-center{ - text-align:center - } - .text-md-right{ - text-align:right - } -} -.center-block{ - display:block; - margin-left:auto; - margin-right:auto -} -.float-right{ - float:right !important -} -.float-left{ - float:left !important -} -.float-none{ - float:none !important -} -.font-weight-normal{ - font-weight:normal -} -.font-weight-bold{ - font-weight:bold -} - -#SpicrDemo{ -height:600px -} -.spicr .lead{ - margin:0; - font-weight:bold; - text-transform:uppercase; - color:#fff -} -.overlay{ - background:rgba(0,0,0,.45); - position:absolute; - top:0; - right:0; - width:100%; - height:100% -} -.spicr-carousel-navigation>*{ - vertical-align:text-bottom -} -@media(min-width: 479px){ - .spicr-control.long-shadows{ - transition:opacity .3s ease-in - } - .spicr-control.long-shadows .arrow-prev{ - margin-left:-280px; - padding:0px 5px 0px 250px; - transform:translate(-100%) - } - .spicr-control.long-shadows .arrow-next{ - margin-right:-280px; - padding:0px 250px 0px 5px; - transform:translate(100%) - } - .spicr-control.long-shadows .arrow-prev,.spicr-control.long-shadows .arrow-next{ - transition:all 1s ease-in - } - .spicr:hover .spicr-control.long-shadows .arrow-prev,.spicr:hover .spicr-control.long-shadows .arrow-next{ - transition-duration:.3s; - transition-timing-function:ease-out - } - .spicr-control.long-shadows:focus .arrow-prev,.spicr-control.long-shadows:focus .arrow-next{ - transform:translate(0%) - } - .spicr:hover .spicr-control.long-shadows .arrow-prev{ - transform:translate(0%) - } - .spicr:hover .spicr-control.long-shadows .arrow-next{ - transform:translate(0%) - } - .spicr-control.long-shadows .spicr-icon{ - width:40px; - height:40px - } - .spicr-control.long-shadows .arrow-next,.spicr-control.long-shadows .arrow-prev{ - border-radius:40px; - margin-top:-20px - } - .spicr-control.long-shadows:focus .arrow-prev{ - transform:translate(0%) - } - .spicr-control.long-shadows:focus .arrow-next{ - transform:translate(0%) - } - .spicr-control.long-shadows .arrow-prev,.spicr-control.long-shadows .arrow-next{ - display:block; - width:auto; - height:auto; - background-color:#000; - background-color:rgba(0,0,0,.3) - } -} -.spicr-carousel h4{ - margin-top:0 -} -.spicr-slider{ - font-size:calc(0.5rem + 1.5vw); - line-height:calc(0.6rem + 1.5vw) -} -.spicr-slider h1{ - font-size:calc(1.375rem + 1.5vw); - letter-spacing:-1px; - margin:0 -} -.spicr-slider h2{ - font-size:calc(1.375rem + 0.9vw); - letter-spacing:0; - margin:0 -} -.features-carousel .spicr-pages{ - top:.5rem -} -.features-carousel .spicr-pages li{ - line-height:1.5rem; - padding:.5rem 1rem -} -@media(min-width: 768px){ - .featurette-heading span{ - font-size:24px; - line-height:1; - letter-spacing:-1px - } - .spicr-slider{ - font-size:1rem; - line-height:1.8rem - } - .spicr-slider h1{ - font-size:42px; - line-height:1; - letter-spacing:-2px; - margin:0 0 1.5rem - } - .spicr-slider h2{ - font-size:36px; - line-height:1; - letter-spacing:-1px; - margin:0 0 1.5rem - } -} - -.background-top-left { background-position: top left !important} -.background-top-center { background-position: top center !important} -.background-top-right { background-position: top center !important} -.background-center-left { background-position: center left !important} -.background-center-center { background-position: center center !important} -.background-center-right { background-position: center right !important} -.background-bottom-left { background-position: bottom left !important} -.background-bottom-center { background-position: bottom center !important} -.background-bottom-right { background-position: bottom right !important} \ No newline at end of file diff --git a/demo/assets/img/apple-touch-icon.png b/demo/assets/img/apple-touch-icon.png deleted file mode 100644 index ed1ba7e..0000000 Binary files a/demo/assets/img/apple-touch-icon.png and /dev/null differ diff --git a/demo/assets/img/favicon.ico b/demo/assets/img/favicon.ico deleted file mode 100644 index c7f98a7..0000000 Binary files a/demo/assets/img/favicon.ico and /dev/null differ diff --git a/demo/assets/img/home.svg b/demo/assets/img/home.svg deleted file mode 100644 index dfe389b..0000000 --- a/demo/assets/img/home.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/demo/assets/img/img-blank.gif b/demo/assets/img/img-blank.gif deleted file mode 100644 index 5891de4..0000000 Binary files a/demo/assets/img/img-blank.gif and /dev/null differ diff --git a/demo/assets/img/loader.gif b/demo/assets/img/loader.gif deleted file mode 100644 index 335e00c..0000000 Binary files a/demo/assets/img/loader.gif and /dev/null differ diff --git a/demo/assets/img/ms.svg b/demo/assets/img/ms.svg deleted file mode 100644 index 88df967..0000000 --- a/demo/assets/img/ms.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/demo/assets/img/rectangle.svg b/demo/assets/img/rectangle.svg deleted file mode 100644 index 9efd23e..0000000 --- a/demo/assets/img/rectangle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/demo/assets/img/social.svg b/demo/assets/img/social.svg deleted file mode 100644 index b9b079b..0000000 --- a/demo/assets/img/social.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - diff --git a/demo/assets/js/backgroundPosition.js b/demo/assets/js/backgroundPosition.js deleted file mode 100644 index ff08225..0000000 --- a/demo/assets/js/backgroundPosition.js +++ /dev/null @@ -1,11 +0,0 @@ -/* BACKGROUND POSITION EXAMPLE */ -var bgPos = document.getElementById('bgPos'), - bgBox = bgPos.querySelector('.example-box'), - bgb = bgPos.querySelector('.btn'), - bpTween = KUTE.to(bgBox, {backgroundPosition: ['0%','50%']}, { yoyo: true, repeat: 1, duration: 1500, easing: 'easingCubicOut'}); - -bgb.addEventListener('click', function(e){ - e.preventDefault(); - !bpTween.playing && bpTween.start(); -},false); -/* BACKGROUND POSITION EXAMPLE */ diff --git a/demo/assets/js/borderRadius.js b/demo/assets/js/borderRadius.js deleted file mode 100644 index 6aa183e..0000000 --- a/demo/assets/js/borderRadius.js +++ /dev/null @@ -1,12 +0,0 @@ - -/* RADIUS EXAMPLES */ -var radiusBtn = document.getElementById('radiusBtn'); -var allRadius = KUTE.to('#allRadius',{borderRadius:80},{duration: 1500, easing:'easingCubicOut', repeat: 1, yoyo: true}); -var tlRadius = KUTE.to('#tlRadius',{borderTopLeftRadius:150},{duration: 1500, easing:'easingCubicOut', repeat: 1, yoyo: true}); -var trRadius = KUTE.to('#trRadius',{borderTopRightRadius:150},{duration: 1500, easing:'easingCubicOut', repeat: 1, yoyo: true}); -var blRadius = KUTE.to('#blRadius',{borderBottomLeftRadius:150},{duration: 1500, easing:'easingCubicOut', repeat: 1, yoyo: true}); -var brRadius = KUTE.to('#brRadius',{borderBottomRightRadius:150},{duration: 1500, easing:'easingCubicOut', repeat: 1, yoyo: true}); -radiusBtn.addEventListener('click',function(){ - if (!allRadius.playing) { allRadius.start(); tlRadius.start(); trRadius.start(); blRadius.start(); brRadius.start(); } -}, false); -/* RADIUS EXAMPLES */ \ No newline at end of file diff --git a/demo/assets/js/boxModel.js b/demo/assets/js/boxModel.js deleted file mode 100644 index bf705d6..0000000 --- a/demo/assets/js/boxModel.js +++ /dev/null @@ -1,49 +0,0 @@ -/* BOX MODEL EXAMPLE */ -var boxModel = document.getElementById('boxModel'), - btb = boxModel.querySelector('.btn'), - box = boxModel.querySelector('.example-box-model'); - -// built the tween objects -var bm1 = KUTE.to(box,{width:250},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onWidth}); -var bm2 = KUTE.to(box,{height:250},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onHeight}); -var bm3 = KUTE.to(box,{left:250},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onLeft}); -var bm4 = KUTE.to(box,{top:-250},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onTop, onComplete: onComplete}); - -var bm5 = KUTE.to(box,{marginTop:50},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onMarginTop}); -var bm6 = KUTE.to(box,{marginBottom:50},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onMarginBottom}); -var bm7 = KUTE.to(box,{paddingTop:15},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onPadding}); -var bm8 = KUTE.to(box,{marginTop:50,marginLeft:50,marginBottom:70},{ yoyo: true, repeat: 1, duration: 1500, onUpdate: onMargin, onComplete: onComplete}); - -// chain the bms -try{ - bm1.chain(bm2); - bm2.chain(bm3); - bm3.chain(bm4); - bm4.chain(bm5); - bm5.chain(bm6); - bm6.chain(bm7); - bm7.chain(bm8); -}catch(e){ - console.error(e+". TweenBase doesn\'t support chain method") -} - -//callback functions -function onWidth() { box.innerHTML = 'WIDTH
'+parseInt(box.offsetWidth)+'px'; } -function onHeight() { box.innerHTML = 'HEIGHT
'+parseInt(box.offsetHeight)+'px'; } -function onLeft() { box.innerHTML = 'LEFT
'+parseInt(box.offsetLeft)+'px'; } -function onTop() { box.innerHTML = 'TOP
'+parseInt(box.offsetTop)+'px'; } - -function onMarginTop() { box.innerHTML = parseInt(box.style.marginTop)+'px'+'
MARGIN'; } -function onMarginBottom() { box.innerHTML = 'MARGIN
'+parseInt(box.style.marginBottom)+'px'; } -function onPadding() { box.innerHTML = parseInt(box.style.paddingTop)+'px
PADDING'; } -function onMargin() { box.innerHTML = 'MARGIN
'+parseInt(box.style.marginTop)+'px'; } - -function onComplete() { box.innerHTML = 'BOX
 MODEL '; } - -btb.addEventListener('click', function(e){ - e.preventDefault(); - !bm1.playing && !bm2.playing && !bm3.playing && !bm4.playing - !bm5.playing && !bm6.playing && !bm7.playing && !bm8.playing - && bm1.start(); -},false); -/* BOX MODEL EXAMPLE */ \ No newline at end of file diff --git a/demo/assets/js/clipProperty.js b/demo/assets/js/clipProperty.js deleted file mode 100644 index 1af3688..0000000 --- a/demo/assets/js/clipProperty.js +++ /dev/null @@ -1,25 +0,0 @@ - -/* CLIP EXAMPLE */ -var clipExample = document.getElementById('clip'), - clipElement = clipExample.querySelector('.example-box'), - clpbtn = clipExample.querySelector('.btn'); - -var clp1 = KUTE.to(clipElement, {clip: [0,20,150,0]}, {duration:500, easing: 'easingCubicOut'}); -var clp2 = KUTE.to(clipElement, {clip: [0,150,150,130]}, {duration:600, easing: 'easingCubicOut'}); -var clp3 = KUTE.to(clipElement, {clip: [0,150,20,0]}, {duration:800, easing: 'easingCubicOut'}); -var clp4 = KUTE.to(clipElement, {clip: [0,150,150,0]}, {duration:1200, easing: 'easingExponentialInOut'}); - -//chain some clps -try{ - clp1.chain(clp2); - clp2.chain(clp3); - clp3.chain(clp4); -}catch(e){ - console.error(e+". TweenBase doesn\'t support chain method") -} - -clpbtn.addEventListener('click', function(e){ - e.preventDefault(); - !clp1.playing && !clp2.playing && !clp3.playing && !clp4.playing && clp1.start(); -},false); -/* CLIP EXAMPLE */ diff --git a/demo/assets/js/colorProperties.js b/demo/assets/js/colorProperties.js deleted file mode 100644 index 225ed6b..0000000 --- a/demo/assets/js/colorProperties.js +++ /dev/null @@ -1,39 +0,0 @@ -/* COLORS EXAMPLE */ -var colBox = document.getElementById('colBox'), - colBoxElement = colBox.querySelector('.example-box'), - colbtn = colBox.querySelector('.btn'); - -var colTween1 = KUTE.to(colBoxElement, {color: '#9C27B0'}, {duration: 1000}); -var colTween2 = KUTE.to(colBoxElement, {backgroundColor: '#069'}, {duration: 1000}); -var colTween3 = KUTE.to(colBoxElement, {color: '#fff'}, {duration: 1000}); -var colTween4 = KUTE.to(colBoxElement, {backgroundColor: '#9C27B0'}, {duration: 1000}); -var colTween5 = KUTE.to(colBoxElement, {borderColor: '#069'}, {duration: 1000}); -var colTween6 = KUTE.to(colBoxElement, {borderTopColor: '#9C27B0'}, {duration: 1000}); -var colTween7 = KUTE.to(colBoxElement, {borderRightColor: '#9C27B0'}, {duration: 1000}); -var colTween8 = KUTE.to(colBoxElement, {borderBottomColor: '#9C27B0'}, {duration: 1000}); -var colTween9 = KUTE.to(colBoxElement, {borderLeftColor: '#9C27B0'}, {duration: 1000}); -var colTween10 = KUTE.to(colBoxElement, {outlineColor: '#9C27B0'}, {duration: 1000, repeat: 1, yoyo: true}); - - -try { - colTween1.chain(colTween2); - colTween2.chain(colTween3); - colTween3.chain(colTween4); - colTween4.chain(colTween5); - colTween5.chain(colTween6); - colTween6.chain(colTween7); - colTween7.chain(colTween8); - colTween8.chain(colTween9); - colTween9.chain(colTween10); -} catch(e){ - console.error(e+". TweenBase doesn\'t support chain method") -} - - -colbtn.addEventListener('click', function(e){ - e.preventDefault(); - !colTween1.playing && !colTween2.playing && !colTween3.playing && !colTween4.playing - !colTween5.playing && !colTween6.playing && !colTween7.playing && !colTween8.playing - !colTween9.playing && !colTween10.playing && colTween1.start(); -},false); -/* COLORS EXAMPLE */ \ No newline at end of file diff --git a/demo/assets/js/filterEffects.js b/demo/assets/js/filterEffects.js deleted file mode 100644 index bffb294..0000000 --- a/demo/assets/js/filterEffects.js +++ /dev/null @@ -1,18 +0,0 @@ - -/* FILTER EFFECTS EXAMPLES */ -var filterExamples = document.getElementById('filter-examples'), - filterBtn = filterExamples.querySelector('.btn'), - fe1 = filterExamples.getElementsByTagName('div')[0], - fe2 = filterExamples.getElementsByTagName('div')[1], - fe3 = filterExamples.getElementsByTagName('div')[2], - fe4 = filterExamples.getElementsByTagName('div')[3], - fe1Tween = KUTE.to(fe1, {filter :{ url: '#mySVGFilter', blur: 0.05, saturate: 10 }}, {easing: 'easingCubicOut', duration: 1500, repeat:1, yoyo: true}), - fe2Tween = KUTE.to(fe2, {filter :{ url: '#mySVGFilter', sepia: 50, invert: 80 }}, {easing: 'easingCubicOut', duration: 1500, repeat:1, yoyo: true}), - fe3Tween = KUTE.to(fe3, {filter :{ url: '#mySVGFilter', saturate: 150, brightness: 60 }}, {easing: 'easingCubicOut', duration: 1500, repeat:1, yoyo: true}), - fe4Tween = KUTE.to(fe4, {filter :{ url: '#mySVGFilter', opacity: 40, hueRotate: 45, dropShadow:[-10,-10,5,{r:0,g:0,b:0,a:1}] }}, {easing: 'easingCubicOut', duration: 1500, repeat:1, yoyo: true}); -filterBtn.addEventListener('click', function(){ - !fe1Tween.playing && fe1Tween.start(); - !fe2Tween.playing && fe2Tween.start(); - !fe3Tween.playing && fe3Tween.start(); - !fe4Tween.playing && fe4Tween.start(); -}, false); \ No newline at end of file diff --git a/demo/assets/js/home.js b/demo/assets/js/home.js deleted file mode 100644 index f13b12a..0000000 --- a/demo/assets/js/home.js +++ /dev/null @@ -1,14 +0,0 @@ -var SpicrMainDemo = document.getElementById('SpicrDemo'); - -function initMainSpicr(){ - new Spicr(SpicrMainDemo); -} - -function loadCarouselMedia(){ - new dll(SpicrMainDemo,initMainSpicr) -} - -document.addEventListener('DOMContentLoaded', function loadWrapper(){ - loadCarouselMedia(); - document.removeEventListener('DOMContentLoaded', loadWrapper, false) -}, false); \ No newline at end of file diff --git a/demo/assets/js/htmlAttributes.js b/demo/assets/js/htmlAttributes.js deleted file mode 100644 index 0f07c21..0000000 --- a/demo/assets/js/htmlAttributes.js +++ /dev/null @@ -1,49 +0,0 @@ -// radius attribute -// var radiusTween = KUTE.to('#circle', {attr: {r: '75px'} }, {repeat:1, yoyo: true, easing: 'easingCubicOut'}); -var radiusTween = KUTE.to('#circle', {attr: {r: '75%'} }, {repeat:1, yoyo: true, easing: 'easingCubicOut'}); - -// coordinates of the circle center -var coordinatesTween1 = KUTE.to('#circle', {attr: {cx:40,cy:40,fillOpacity:0.3}}, { duration: 300, easing: 'easingCubicOut'}); -var coordinatesTween2 = KUTE.to('#circle', {attr: {cx:110,cy:40}}, { duration: 400, easing: 'linear'}); -var coordinatesTween3 = KUTE.to('#circle', {attr: {cx:75,cy:75,fillOpacity:1}}, { easing: 'easingCubicOut'}); - -try{ - coordinatesTween1.chain(coordinatesTween2); - coordinatesTween2.chain(coordinatesTween3); - coordinatesTween3.chain(radiusTween); -}catch(e){ - console.error(e+". TweenBase doesn\'t support chain method") -} - - -var circleBtn = document.getElementById('circleBtn'); -circleBtn.addEventListener('click', function(){ - !coordinatesTween1.playing && !coordinatesTween2.playing && !coordinatesTween3.playing && !radiusTween.playing && coordinatesTween1.start(); -}); - - -// coordinates of gradient -var gradBtn = document.getElementById('gradBtn'); -var closingGradient = KUTE.to('#gradient',{attr: {x1:'49%', x2:'49%', y1:'49%', y2:'51%'}}, {easing: 'easingCubicInOut'}); -var rotatingGradient1 = KUTE.to('#gradient',{attr: {x1:'49%', x2:'51%', y1:'51%', y2:'51%'}}, {easing: 'easingCubicInOut'}); -var rotatingGradient2 = KUTE.to('#gradient',{attr: {x1:'0%', x2:'51%', y1:'100%', y2:'0%'}}, {easing: 'easingCubicInOut'}); -var openingGradient = KUTE.to('#gradient',{attr: {x1:'0%', x2:'0%', y1:'0%', y2:'100%'}}, {duration: 1500, easing: 'easingCubicInOut'}); - -try{ - closingGradient.chain(rotatingGradient1); - rotatingGradient1.chain(rotatingGradient2); - rotatingGradient2.chain(openingGradient); -}catch(e){ - console.error(e+". TweenBase doesn\'t support chain method") -} - -gradBtn.addEventListener('click', function(){ - !closingGradient.playing && !rotatingGradient1.playing && !rotatingGradient2.playing && !openingGradient.playing && closingGradient.start(); -}); - -// fill color -var fillBtn = document.getElementById('fillBtn'); -var fillAttribute = KUTE.to('#fill',{attr: {fill: 'red'}}, {duration: 1500, repeat: 1, yoyo: true }); -fillBtn.addEventListener('click', function(){ - !fillAttribute.playing && fillAttribute.start(); -}); \ No newline at end of file diff --git a/demo/assets/js/opacityProperty.js b/demo/assets/js/opacityProperty.js deleted file mode 100644 index 40b4555..0000000 --- a/demo/assets/js/opacityProperty.js +++ /dev/null @@ -1,23 +0,0 @@ -/* OPACITY EXAMPLE */ -var opacityProperty = document.getElementById('opacityProperty'), - button = opacityProperty.getElementsByClassName('btn')[0], - heart = opacityProperty.getElementsByClassName('example-box')[0], - // fade out - fadeOutTween = KUTE.to(heart,{opacity:0},{duration:2000}), - // fade in - fadeInTween = KUTE.to(heart,{opacity:1},{duration:2000}), - - isHidden = true; - -button.addEventListener('click', function(e){ - e.preventDefault(); - if ( !isHidden && !fadeOutTween.playing && !fadeInTween.playing ) { - fadeOutTween.start(); - isHidden = !isHidden; - - } else if ( isHidden && !fadeOutTween.playing && !fadeInTween.playing ) { - fadeInTween.start(); - isHidden = !isHidden; - } -},false); -/* OPACITY EXAMPLE */ diff --git a/demo/assets/js/perf-matrix.js b/demo/assets/js/perf-matrix.js deleted file mode 100644 index b4fcbb5..0000000 --- a/demo/assets/js/perf-matrix.js +++ /dev/null @@ -1,111 +0,0 @@ -// testing grounds -"use strict"; - -var mobileType = '', - isMobile = { - Windows: function() { - var checkW = /IEMobile|Windows Mobile/i.test(navigator.userAgent); - mobileType += checkW ? 'Windows Phones.' : ''; - return checkW; - }, - Android: function() { - var checkA = /Android/i.test(navigator.userAgent); - mobileType += checkA ? 'Android Phones.' : ''; - return checkA; - }, - BlackBerry: function() { - var checkB = /BlackBerry/i.test(navigator.userAgent); - mobileType += checkB ? 'BlackBerry.' : ''; - return checkB; - }, - iOS: function() { - var checkI = /iPhone|iPad|iPod/i.test(navigator.userAgent); - mobileType += checkI ? 'Apple iPhone, iPad or iPod.' : ''; - return checkI; - }, - any: function() { - return ( isMobile.Windows() || isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() ); - } - }, - checkMOBS = isMobile.any(); - -// protect phones, older / low end devices -if (document.body.offsetWidth < 1200 || checkMOBS) { - var explain = ''; - explain += checkMOBS && mobileType !== '' ? ('For safety reasons, this page does not work with ' + mobileType) : ''; - explain += !checkMOBS && document.body.offsetWidth < 1200 && mobileType === '' ? 'For safety reasons this page does not work on your machine because it might be very old. In other cases the browser window size is not enough for the animation to work properly, so if that\'s the case, maximize the window, refresh and proceed with the tests.' : ''; - var warning = '
'; - warning +='

Warning!

'; - warning +='

This web page is only for high-end desktop computers.

'; - warning +='

We do not take any responsibility and we are not liable for any damage caused through use of this website, be it indirect, special, incidental or consequential damages to your devices.

'; - warning +='

'+explain+'

'; - warning +='
'; - document.body.innerHTML = warning; - throw new Error('This page is only for high-end desktop computers. ' + explain); -} - -// the variables -var infoContainer = document.getElementById('info'); -var container = document.getElementById('container'); -var tws = []; - -for (var i=0; i<21; i++){ - container.innerHTML += - '
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' - +'
' -} - -var collection = document.getElementsByClassName('cube'); -var lastIdx = collection.length-1; - -function complete(){ - infoContainer.style.display = 'block'; - container.style.display = 'none'; -} - -var engine = document.getElementById('kute'), - fromCSS = { rotate3d: [ 0, 0,0 ], perspective:600 }, - fromMX = { transform: { rotate3d: [ 0, 0,0 ], perspective:600 }}, - toCSS = { rotate3d: [ 360,0,0 ], perspective:600 }, - toMX = { transform: { rotate3d: [ 0,360,0 ], perspective:600 }}, - ops = { duration: 2000, repeat: 5 } - -// since our engines don't do sync, we make it our own here -if (!engine.src.includes('extra')) { - [].slice.call(collection).map((el,i) => { i===lastIdx && (ops.onComplete = complete); tws.push ( KUTE.fromTo(el,fromCSS,toCSS,ops) ) }) -} -if (engine.src.includes('extra')) { - [].slice.call(collection).map((el,i) => { i===lastIdx && (ops.onComplete = complete); tws.push ( KUTE.fromTo(el,fromMX,toMX,ops) ) }) -} - - -function startTest(){ - infoContainer.style.display = 'none'; - container.style.display = 'block' - - tws.length && !tws[0].playing && startKUTE(); -} - - -function startKUTE() { - var now = window.performance.now(), count = tws.length; - tws.forEach((t) => t.start(now)); -} - -// the start button handle -document.getElementById('start').addEventListener('click', startTest, false); diff --git a/demo/assets/js/perf.js b/demo/assets/js/perf.js deleted file mode 100644 index af75360..0000000 --- a/demo/assets/js/perf.js +++ /dev/null @@ -1,213 +0,0 @@ -// testing grounds -"use strict"; - -var mobileType = '', - isMobile = { - Windows: function() { - var checkW = /IEMobile|Windows Mobile/i.test(navigator.userAgent); - mobileType += checkW ? 'Windows Phones.' : ''; - return checkW; - }, - Android: function() { - var checkA = /Android/i.test(navigator.userAgent); - mobileType += checkA ? 'Android Phones.' : ''; - return checkA; - }, - BlackBerry: function() { - var checkB = /BlackBerry/i.test(navigator.userAgent); - mobileType += checkB ? 'BlackBerry.' : ''; - return checkB; - }, - iOS: function() { - var checkI = /iPhone|iPad|iPod/i.test(navigator.userAgent); - mobileType += checkI ? 'Apple iPhone, iPad or iPod.' : ''; - return checkI; - }, - any: function() { - return ( isMobile.Windows() || isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() ); - } - }, - checkMOBS = isMobile.any(); - -// protect phones, older / low end devices -if (document.body.offsetWidth < 1200 || checkMOBS) { - var explain = ''; - explain += checkMOBS && mobileType !== '' ? ('For safety reasons, this page does not work with ' + mobileType) : ''; - explain += !checkMOBS && document.body.offsetWidth < 1200 && mobileType === '' ? 'For safety reasons this page does not work on your machine because it might be very old. In other cases the browser window size is not enough for the animation to work properly, so if that\'s the case, maximize the window, refresh and proceed with the tests.' : ''; - var warning = '
'; - warning +='

Warning!

'; - warning +='

This web page is only for high-end desktop computers.

'; - warning +='

We do not take any responsibility and we are not liable for any damage caused through use of this website, be it indirect, special, incidental or consequential damages to your devices.

'; - warning +='

'+explain+'

'; - warning +='
'; - document.body.innerHTML = warning; - throw new Error('This page is only for high-end desktop computers. ' + explain); -} - -// generate a random number within a given range -function random(min, max) { - return Math.random() * (max - min) + min; -} - -// the variables -var container = document.getElementById('container'); -var tws = []; - -function complete(){ - document.getElementById('info').style.display = 'block'; - container.innerHTML = ''; - tws = []; - if (engine==='tween') { - stop() - } -} - -function updateLeft(obj){ - obj.div.style.left = obj.left +'px'; -} - -function updateTranslate(obj){ - obj.div.style.transform = 'translate3d('+ ((obj.x * 10) / 10 >>0) + 'px,0px,0px)'; -} - -function buildObjects(){ - var c = document.querySelector('[data-count]'), e = document.querySelector('[data-engine]'), r = document.querySelector('[data-repeat]'), - p = document.querySelector('[data-property]'), ct = c && document.querySelector('[data-count]').getAttribute('data-count'), - count = ct ? parseInt(ct) : null, - engine = e && document.querySelector('[data-engine]').getAttribute('data-engine') || null, - repeat = r && document.querySelector('[data-repeat]').getAttribute('data-repeat') || null, - property = p && document.querySelector('[data-property]').getAttribute('data-property') || null, - warning = document.createElement('DIV'); - - warning.className = 'text-warning padding lead'; - container.innerHTML = ''; - if (count && engine && property && repeat) { - if (engine === 'gsap') { - document.getElementById('info').style.display = 'none'; - } - - createTest(count,property,engine,repeat); - // since our engines don't do sync, we make it our own here - if (engine==='kute') { - document.getElementById('info').style.display = 'none'; - startKUTE(); - } - if (engine==='tween') { - document.getElementById('info').style.display = 'none'; - startTWEEN(); - } - } else { - - if (!count && !property && !repeat && !engine){ - warning.innerHTML = 'We are missing all the settings here.'; - } else { - warning.innerHTML = 'Now missing
'; - warning.innerHTML += !engine ? '- engine
' : ''; - warning.innerHTML += !property ? '- property
' : ''; - warning.innerHTML += !repeat ? '- repeat
' : ''; - warning.innerHTML += !count ? '- count
' : ''; - } - - container.appendChild(warning); - } -} - -function animate( time ) { - requestAnimationFrame( animate ); - TWEEN.update( time ); -} - -function stop(){ - cancelAnimationFrame(animate) -} - -function startKUTE() { - var now = window.performance.now(), count = tws.length; - for (var t =0; t'; - b.setAttribute('data-'+link.parentNode.parentNode.parentNode.id, link.id); - } - } -} \ No newline at end of file diff --git a/demo/assets/js/prism.js b/demo/assets/js/prism.js deleted file mode 100644 index 8d21c08..0000000 --- a/demo/assets/js/prism.js +++ /dev/null @@ -1,6 +0,0 @@ -/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript */ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=_self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),P=[p,1];b&&P.push(b);var A=new a(i,g?t.tokenize(m,g):m,h);P.push(A),w&&P.push(w),Array.prototype.splice.apply(r,P)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var l={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}t.hooks.run("wrap",l);var o="";for(var s in l.attributes)o+=(o?" ":"")+s+'="'+(l.attributes[s]||"")+'"';return"<"+l.tag+' class="'+l.classes.join(" ")+'" '+o+">"+l.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code,l=n.immediateClose;_self.postMessage(t.highlight(r,t.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); -Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; -Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); -Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; -Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript; diff --git a/demo/assets/js/progress.js b/demo/assets/js/progress.js deleted file mode 100644 index 36601fc..0000000 --- a/demo/assets/js/progress.js +++ /dev/null @@ -1,16 +0,0 @@ - -// invalidate for unsupported browsers -var isIE = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null ? parseFloat( RegExp.$1 ) : false; -if (isIE&&isIE<9) { (function(){return; }()) } // return if SVG API is not supported - -// the range slider -var rangeSlider = document.querySelector('input[type="range"'); - -// basic morph, only fromTo and allFromTo should work -var morphTween = KUTE.fromTo('#rectangle', { path: '#rectangle' }, { path: '#star' }, { duration: 2500, /*repeat: Infinity, yoyo: true,*/ } ); - -var progressBar = new KUTE.ProgressBar(rangeSlider,morphTween) - -document.getElementById('rectangle').addEventListener('click',function(){ - !morphTween.playing && morphTween.start() -}) \ No newline at end of file diff --git a/demo/assets/js/sampleComponent.js b/demo/assets/js/sampleComponent.js deleted file mode 100644 index c0eda27..0000000 --- a/demo/assets/js/sampleComponent.js +++ /dev/null @@ -1,82 +0,0 @@ -// Component Util -// returns browser prefix -function getPrefix() { - const prefixes = ['Moz', 'moz', 'Webkit', 'webkit', 'O', 'o', 'Ms', 'ms']; - - let thePrefix; - for (let i = 0, pfl = prefixes.length; i < pfl; i++) { - if (`${prefixes[i]}Transform` in document.body.style) { thePrefix = prefixes[i]; break; } - } - return thePrefix; -} - -// returns prefixed property | property -function trueProperty(property) { - const prefixRequired = (!(property in document.body.style)) ? true : false; // is prefix required for property | prefix - - const prefix = getPrefix(); - return prefixRequired ? prefix + (property.charAt(0).toUpperCase() + property.slice(1)) : property; -} - -// some old browsers like to use preffixed properties -var transformProperty = trueProperty('transform'); - -// value 0 means that browser doesn't support any transform -// value 1 means that browser supports at least 2D transforms -var browserVersion = transformProperty in document.body.style ? 1 : 0 - -// Component usual imports -var numbers = KUTE.Interpolate.numbers; -var getInlineStyle = KUTE.Process.getInlineStyle; -var scope = window._KUTE; - -// Component Functions -function getMove(tweenProp,value){ - var currentTransform = getInlineStyle(this.element); - var left = this.element.style.left; - var top = this.element.style.top; - var x = browserVersion && currentTransform.translate ? currentTransform.translate[0] - : isFinite(left*1) ? left - : defaultValues.move[0]; - var y = browserVersion && currentTransform.translate ? currentTransform.translate[1] - : isFinite(top*1) ? top - : defaultValues.move[1]; - return [x,y] -} -function prepareMove(tweenProp,value){ - var x = isFinite(value*1) ? parseInt(value) : parseInt(value[0]) || 0; - var y = parseInt(value[1]) || 0; - return [ x, y ] -} -function onStartMove(tweenProp,value){ - if (!scope[tweenProp] && this.valuesEnd[tweenProp]) { - if (browserVersion){ - scope[tweenProp] = function (elem, a, b, v) { - elem.style[transformProperty] = 'translate('+numbers(a[0],b[0],v)+'px,'+numbers(a[1],b[1],v)+'px)'; - }; - } else { - scope[tweenProp] = function (elem, a, b, v) { - if (a[0]||b[0]) { - elem.style.left = numbers(a[0],b[0],v)+'px'; - } - if (a[1]||b[1]) { - elem.style.top = numbers(a[1],b[1],v)+'px'; - } - }; - } - } -} - -// the component object -var crossBrowserMoveOptions = { - component: 'crossBrowserMove', - property: 'move', - defaultValue: [0,0], - Interpolate: numbers, - functions: { - prepareStart: getMove, - prepareProperty: prepareMove, - onStart: onStartMove - } -}; -KUTE.Components.crossBrowserMove = new KUTE.Animation(crossBrowserMoveOptions) \ No newline at end of file diff --git a/demo/assets/js/scripts.js b/demo/assets/js/scripts.js deleted file mode 100644 index c2d13c3..0000000 --- a/demo/assets/js/scripts.js +++ /dev/null @@ -1,31 +0,0 @@ -// common demo JS -function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -// toggles utility -var toggles = document.querySelectorAll('[data-function="toggle"]'); - -function closeToggles(el){ - el.classList.remove('open'); -} - -function classToggles(el){ - el.classList.toggle('open'); -} - -document.addEventListener('click', function(e){ - if (e && !e.target.classList) {return;} - - var target = e.target.parentNode.tagName === 'LI' || e.target.parentNode.classList && e.target.parentNode.classList.contains('btn-group') ? e.target : e.target.parentNode, - parent = target.parentNode; - for (var i = 0, l = toggles.length; i') + ''; -var charsObject = heading.getElementsByTagName('SPAN'), l = charsObject.length; - - -// built the tween objects -var tps = KUTE.allFromTo(charsObject, - { fontSize:50, letterSpacing: 0, color: '#333'}, - { fontSize:80, letterSpacing: 10, color: 'red'}, - { offset: 75, duration: 250, repeat: 1, yoyo:true, repeatDelay: 150, easing: 'easingCubicOut'}); - - -button.addEventListener('click', function(e){ - e.preventDefault(); - if ( !tps.playing() ) { - tps.start(); - } -},false); -/* TEXT PROPERTIES EXAMPLE */ \ No newline at end of file diff --git a/demo/assets/js/textWrite.js b/demo/assets/js/textWrite.js deleted file mode 100644 index 2ceb616..0000000 --- a/demo/assets/js/textWrite.js +++ /dev/null @@ -1,61 +0,0 @@ -// number increment -var numText = document.getElementById('numText'), - numBtn = document.getElementById('numBtn'), - numTween = KUTE.to(numText, {number: 1550}, {duration: 3000, easing: 'easingCubicOut'}); - numBtn.addEventListener('click', function(){ - - if (!numTween.playing) { - if (numText.innerHTML === '1550') { numTween.valuesEnd['number'] = 0; } else { numTween.valuesEnd['number'] = 1550; } - numTween.start(); - } -}, false); - -// write text -var headText = document.getElementById('headText'), - headBtn = document.getElementById('headBtn'), - initText = headText.innerHTML, - whichTw = false, - nextText = "This is a super simple write text demo.", - headTween = KUTE.to(headText, {text: nextText}, {textChars: 'alpha', duration: 5000, easing: 'easingBounceOut'}), - headTween1 = KUTE.to(headText, {text: initText}, {textChars: 'alpha', duration: 5000, easing: 'easingBounceOut'}); -headBtn.addEventListener('click', function(){ - !whichTw && !headTween.playing && !headTween1.playing && (headTween.start(), whichTw = !whichTw); - whichTw && !headTween.playing && !headTween1.playing && (headTween1.start(), whichTw = !whichTw); -}, false); - - -// improved write text -var textTweenBTN = document.getElementById('textExampleBtn'); -var textTarget = document.getElementById('textExample'); -var textOriginal = textTarget.innerHTML; -var anotherText = 'This text has a link to homepage inside.'; -var options = {duration: 'auto', textChars: 'alphanumeric'} - -textTweenBTN.addEventListener('click', function(){ - var newContent = textTarget.innerHTML === textOriginal ? anotherText : textOriginal; - !textTarget.playing && KUTE.Util.createTextTweens(textTarget,newContent,options).start() -}) - - -// combo wombo -var comText = document.getElementById('comText'), - comNum = document.getElementById('comNum'), - comBtn = document.getElementById('comBtn'), - comTween11 = KUTE.to(comNum, {number: 2500}, {duration: 2000, easing: 'easingCubicOut'}), - comTween12 = KUTE.to(comText, {text: "People following on Github."}, { textChars: 'symbols', duration: 3000, easing: 'easingCubicInOut'}), - comTween21 = KUTE.to(comNum, {number: 7500}, {delay: 3000, duration: 2000, easing: 'easingCubicInOut'}), - comTween22 = KUTE.to(comText, {text: "More crazy tricks coming soon."}, {textChars: 'all', delay: 2000, duration: 3000, easing: 'easingCubicInOut'}); - -try{ - comTween11.chain(comTween21); - comTween12.chain(comTween22); -}catch(e){ - console.error(`${e} TweenBase doesn't support chain method`) -} - -comBtn.addEventListener('click', function(){ - if (!comTween11.playing && !comTween21.playing && !comTween12.playing && !comTween22.playing) { - comTween11.start(); - comTween12.start(); - } -}, false); \ No newline at end of file diff --git a/demo/assets/js/transformFunctions.js b/demo/assets/js/transformFunctions.js deleted file mode 100644 index 1b3e2ac..0000000 --- a/demo/assets/js/transformFunctions.js +++ /dev/null @@ -1,136 +0,0 @@ - -/* TRANSFORMS EXAMPLES */ -var translateExamples = document.getElementById('translate-examples'), - translateBtn = translateExamples.querySelector('.btn'), - tr2d = translateExamples.getElementsByTagName('div')[0], - trx = translateExamples.getElementsByTagName('div')[1], - trry = translateExamples.getElementsByTagName('div')[2], - trz = translateExamples.getElementsByTagName('div')[3], - tr2dTween = KUTE.to(tr2d, {translate:[170,170]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), - trxTween = KUTE.to(trx, {translateX:-170}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), - trryTween = KUTE.to(trry, {translate3d:[0,170,0]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), - trzTween = KUTE.to(trz, {perspective:200, translate3d:[0,0,-100]}, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}); - -translateBtn.addEventListener('click', function(){ - !tr2dTween.playing && tr2dTween.start(); - !trxTween.playing && trxTween.start(); - !trryTween.playing && trryTween.start(); - !trzTween.playing && trzTween.start(); -}, false); - -var rotExamples = document.getElementById('rotExamples'), - rotBtn = rotExamples.querySelector('.btn'), - r2d = rotExamples.querySelectorAll('div')[0], - rx = rotExamples.querySelectorAll('div')[1], - ry = rotExamples.querySelectorAll('div')[2], - rz = rotExamples.querySelectorAll('div')[3], - r2dTween = KUTE.to(r2d, {rotate:-720}, {easing:'easingCircularInOut', 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}), - rzTween = KUTE.to(rz, {rotateZ:360}, {easing:'easingBackOut', yoyo:true, repeat: 1, duration:1500}); - -rotBtn.addEventListener('click', function(){ - !r2dTween.playing && r2dTween.start(); - !rxTween.playing && rxTween.start(); - !ryTween.playing && ryTween.start(); - !rzTween.playing && rzTween.start(); -}, false); - -var skewExamples = document.getElementById('skewExamples'), - skewBtn = skewExamples.querySelector('.btn'), - sx = skewExamples.querySelectorAll('div')[0], - sy = skewExamples.querySelectorAll('div')[1], - sxTween = KUTE.to(sx, {skewX:-25}, {easing:'easingCircularInOut', yoyo:true, repeat: 1, duration:1500}), - syTween = KUTE.to(sy, {skew:[0,25]}, {easing:'easingCircularInOut', yoyo:true, repeat: 1, duration:1500}); -skewBtn.addEventListener('click', function(){ - !sxTween.playing && sxTween.start(); - !syTween.playing && syTween.start(); -}, false); - -var mixTransforms = document.getElementById('mixTransforms'), - mixBtn = mixTransforms.querySelector('.btn'), - mt1 = mixTransforms.querySelectorAll('div')[0], - mt2 = mixTransforms.querySelectorAll('div')[1], - // pp = KUTE.Util.trueProperty('perspective'), - // tfp = KUTE.Util.trueProperty('transform'), - // tfo = KUTE.Util.trueProperty('transformOrigin'), - mt1Tween = KUTE.to(mt1, {perspective:200,translateX:300,rotateX:360,rotateY:15,rotateZ:5}, { easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500}), - mt2Tween = KUTE.to(mt2, {translateX:300,rotateX:360,rotateY:15,rotateZ:5}, { easing:'easingCubicInOut', yoyo:true, repeat: 1, duration:1500}); - -mixBtn.addEventListener('click', function(){ - !mt1Tween.playing && mt1Tween.start(); - !mt2Tween.playing && mt2Tween.start(); -}, false); - -/* TRANSFORMS EXAMPLES */ - - -/* CHAINED TWEENS EXAMPLE */ -var chainedTweens = document.getElementById('chainedTweens'), - el1 = chainedTweens.querySelectorAll('.example-item')[0], - el2 = chainedTweens.querySelectorAll('.example-item')[1], - el3 = chainedTweens.querySelectorAll('.example-item')[2], - el4 = chainedTweens.querySelectorAll('.example-item')[3], - ctb = chainedTweens.querySelector('.btn'); - -// built the tween objects for element1 -var tween11 = KUTE.fromTo(el1, { perspective:400,translateX:0, rotateX: 0}, {perspective:400,translateX:150, rotateX: 25}, {duration: 2000}); -var tween12 = KUTE.fromTo(el1, { perspective:400,translateY:0, rotateY: 0}, {perspective:400,translateY:20, rotateY: 15}, {duration: 2000}); -var tween13 = KUTE.fromTo(el1, { perspective:400,translate3d:[150,20,0], rotate3d:[25,15,0]}, {perspective:400,translate3d:[0,0,0], rotate3d:[0,0,0]}, {duration: 3000}); - -// chain tweens -try { - tween11.chain(tween12); - tween12.chain(tween13); -} catch(e) { - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element2 -var tween21 = KUTE.fromTo(el2, { perspective:400,translateX:0, translateY:0, rotateX: 0, rotateY:0 }, {perspective:400,translateX:150, translateY:0, rotateX: 25, rotateY:0}, {duration: 2000}); -var tween22 = KUTE.fromTo(el2, { perspective:400,translateX:150, translateY:0, rotateX: 25, rotateY: 0}, {perspective:400,translateX:150, translateY:20, rotateX: 25, rotateY: 15}, {duration: 2000}); -var tween23 = KUTE.fromTo(el2, { perspective:400,translate3d:[150,20,0], rotateX: 25, rotateY:15}, {perspective:400,translate3d:[0,0,0], rotateX: 0, rotateY:0}, {duration: 3000}); - -// chain tweens -try{ - tween21.chain(tween22); - tween22.chain(tween23); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element3 -var tween31 = KUTE.to(el3,{ perspective:400,translateX:150, rotateX:25}, {duration: 2000}); -var tween32 = KUTE.to(el3,{ perspective:400,translateX:150,translateY:20, rotateY:15}, {duration: 2000}); -var tween33 = KUTE.to(el3,{ perspective:400,translateX:0, translateY:0, rotateX: 0, rotateY:0}, {duration: 3000}); - -// chain tweens -try{ - tween31.chain(tween32); - tween32.chain(tween33); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element4 -var tween41 = KUTE.to(el4,{ perspective:400, translate3d:[150,0,0], rotate3d: [25,0,0]}, {duration: 2000}); -var tween42 = KUTE.to(el4,{ perspective:400, translate3d:[150,20,0], rotate3d:[25,15,0]}, {duration: 2000}); -var tween43 = KUTE.to(el4,{ perspective:400, translate3d:[0,0,0], rotate3d: [0,0,0]}, {duration: 3000}); - -// chain tweens -try{ - tween41.chain(tween42); - tween42.chain(tween43); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - - -ctb.addEventListener('click',function(e){ - e.preventDefault(); - !tween11.playing && !tween12.playing && !tween13.playing && tween11.start(); - !tween21.playing && !tween22.playing && !tween23.playing && tween21.start(); - !tween31.playing && !tween32.playing && !tween33.playing && tween31.start(); - !tween41.playing && !tween42.playing && !tween43.playing && tween41.start(); -},false); -/* CHAINED TWEENS EXAMPLE */ \ No newline at end of file diff --git a/demo/assets/js/transformMatrix.js b/demo/assets/js/transformMatrix.js deleted file mode 100644 index 77afc5b..0000000 --- a/demo/assets/js/transformMatrix.js +++ /dev/null @@ -1,92 +0,0 @@ - -/* MATRIX TRANSFORMS EXAMPLES */ -/* using parent perspective */ -var matrixExamples = document.getElementById('matrix-examples'), - matrixBtn = matrixExamples.querySelector('.btn'), - mx1 = matrixExamples.getElementsByTagName('div')[0], - mx2 = matrixExamples.getElementsByTagName('div')[1], - mx3 = matrixExamples.getElementsByTagName('div')[2], - mx4 = matrixExamples.getElementsByTagName('div')[3], - mx1Tween = KUTE.to(mx1, {transform: { translate3d:[-50,-50,-50]} }, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), - mx2Tween = KUTE.to(mx2, {transform: { perspective: 100, translate3d:[-50,-50,-50], rotateX:180 } }, {easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), - mx3Tween = KUTE.to(mx3, {transform: { translate3d:[-50,-50,-50], skew:[-15,-15] } }, { easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}), // matrix(1, 45, 45, 1, 0, -170) - mx4Tween = KUTE.to(mx4, {transform: { translate3d:[-50,-50,-50], rotate3d:[0,-360,0], scaleX: 0.5 } }, { easing:'easingCubicOut', yoyo:true, repeat: 1, duration:1500}); - -matrixBtn.addEventListener('click', function(){ - !mx1Tween.playing && mx1Tween.start(); - !mx2Tween.playing && mx2Tween.start(); - !mx3Tween.playing && mx3Tween.start(); - !mx4Tween.playing && mx4Tween.start(); -}, false); - - -/* CHAINED TWEENS EXAMPLE */ -var chainedTweens = document.getElementById('chainedTweens'), - el1 = chainedTweens.querySelectorAll('.example-item')[0], - el2 = chainedTweens.querySelectorAll('.example-item')[1], - el3 = chainedTweens.querySelectorAll('.example-item')[2], - el4 = chainedTweens.querySelectorAll('.example-item')[3], - ctb = chainedTweens.querySelector('.btn'); - -// built the tween objects for element1 -var tween11 = KUTE.fromTo(el1, { transform: {perspective:400,translateX:0, rotateX: 0}}, {transform: {perspective:400,translateX:150, rotateX: 25}}, {duration: 2000}); -var tween12 = KUTE.fromTo(el1, { transform: {perspective:400,translateY:0, rotateY: 0}}, {transform: {perspective:400,translateY:20, rotateY: 15}}, {duration: 2000}); -var tween13 = KUTE.fromTo(el1, { transform: {perspective:400,translate3d:[150,20,0], rotate3d:[25,15,0]}}, {transform: {perspective:400,translate3d:[0,0,0], rotate3d:[0,0,0]}}, {duration: 3000}); - -// chain tweens -try { - tween11.chain(tween12); - tween12.chain(tween13); -} catch(e) { - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element2 -var tween21 = KUTE.fromTo(el2, { transform: {perspective:400,translateX:0, translateY:0, rotateX: 0, rotateY:0 }}, {transform: {perspective:400,translateX:150, translateY:0, rotateX: 25, rotateY:0}}, {duration: 2000}); -var tween22 = KUTE.fromTo(el2, { transform: {perspective:400,translateX:150, translateY:0, rotateX: 25, rotateY: 0}}, {transform: {perspective:400,translateX:150, translateY:20, rotateX: 25, rotateY: 15}}, {duration: 2000}); -var tween23 = KUTE.fromTo(el2, { transform: {perspective:400,translate3d:[150,20,0], rotateX: 25, rotateY:15}}, {transform: {perspective:400,translate3d:[0,0,0], rotateX: 0, rotateY:0}}, {duration: 3000}); - -// chain tweens -try{ - tween21.chain(tween22); - tween22.chain(tween23); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element3 -var tween31 = KUTE.to(el3,{ transform: {perspective:400,translateX:150, rotateX:25}}, {duration: 2000}); -var tween32 = KUTE.to(el3,{ transform: {perspective:400,translateX:150,translateY:20, rotateY:15}}, {duration: 2000}); -var tween33 = KUTE.to(el3,{ transform: {perspective:400,translateX:0, translateY:0, rotateX: 0, rotateY:0}}, {duration: 3000}); - -// chain tweens -try{ - tween31.chain(tween32); - tween32.chain(tween33); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - -// built the tween objects for element4 -var tween41 = KUTE.to(el4,{ transform: {perspective:400, translate3d:[150,0,0], rotate3d: [25,0,0]}}, {duration: 2000}); -var tween42 = KUTE.to(el4,{ transform: {perspective:400, translate3d:[150,20,0], rotate3d:[25,15,0]}}, {duration: 2000}); -var tween43 = KUTE.to(el4,{ transform: {perspective:400, translate3d:[0,0,0], rotate3d: [0,0,0]}}, {duration: 3000}); - -// chain tweens -try{ - tween41.chain(tween42); - tween42.chain(tween43); -}catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") -} - - -ctb.addEventListener('click',function(e){ - e.preventDefault(); - !tween11.playing && !tween12.playing && !tween13.playing && tween11.start(); - !tween21.playing && !tween22.playing && !tween23.playing && tween21.start(); - !tween31.playing && !tween32.playing && !tween33.playing && tween31.start(); - !tween41.playing && !tween42.playing && !tween43.playing && tween41.start(); -},false); -/* CHAINED TWEENS EXAMPLE */ - diff --git a/demo/assets/js/tween.min.js b/demo/assets/js/tween.min.js deleted file mode 100644 index a0fb5e7..0000000 --- a/demo/assets/js/tween.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// tween.js MIT License -(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global.TWEEN=factory())}(this,(function(){'use strict';var version='18.4.2';var _Group=function(){this._tweens={};this._tweensAddedDuringUpdate={}};_Group.prototype={getAll:function(){return Object.keys(this._tweens).map(function(tweenId){return this._tweens[tweenId]}.bind(this))},removeAll:function(){this._tweens={}},add:function(tween){this._tweens[tween.getId()]=tween;this._tweensAddedDuringUpdate[tween.getId()]=tween},remove:function(tween){delete this._tweens[tween.getId()];delete this._tweensAddedDuringUpdate[tween.getId()]},update:function(time,preserve){var tweenIds=Object.keys(this._tweens);if(tweenIds.length===0){return false}time=time!==undefined?time:TWEEN.now();while(tweenIds.length>0){this._tweensAddedDuringUpdate={};for(var i=0;i1)?1:elapsed;value=this._easingFunction(elapsed);for(property in this._valuesEnd){if(this._valuesStart[property]===undefined){continue}var start=this._valuesStart[property]||0;var end=this._valuesEnd[property];if(end instanceof Array){this._object[property]=this._interpolationFunction(end,value)}else{if(typeof(end)==='string'){if(end.charAt(0)==='+'||end.charAt(0)==='-'){end=start+parseFloat(end)}else{end=parseFloat(end)}}if(typeof(end)==='number'){this._object[property]=start+(end-start)*value}}}if(this._onUpdateCallback!==null){this._onUpdateCallback(this._object,elapsed)}if(elapsed===1){if(this._repeat>0){if(isFinite(this._repeat)){this._repeat-=1}for(property in this._valuesStartRepeat){if(typeof(this._valuesEnd[property])==='string'){this._valuesStartRepeat[property]=this._valuesStartRepeat[property]+parseFloat(this._valuesEnd[property])}if(this._yoyo){var tmp=this._valuesStartRepeat[property];this._valuesStartRepeat[property]=this._valuesEnd[property];this._valuesEnd[property]=tmp}this._valuesStart[property]=this._valuesStartRepeat[property]}if(this._yoyo){this._reversed=!this._reversed}if(this._repeatDelayTime!==undefined){this._startTime=time+this._repeatDelayTime}else{this._startTime=time+this._delayTime}if(this._onRepeatCallback!==null){this._onRepeatCallback(this._object)}return true}else{if(this._onCompleteCallback!==null){this._onCompleteCallback(this._object)}for(var i=0,numChainedTweens=this._chainedTweens.length;i1){return fn(v[m],v[m-1],m-f)}return fn(v[i],v[i+1>m?m:i+1],f-i)},Bezier:function(v,k){var b=0;var n=v.length-1;var pw=Math.pow;var bn=TWEEN.Interpolation.Utils.Bernstein;for(var i=0;i<=n;i+=1){b+=pw(1-k,n-i)*pw(k,i)*v[i]*bn(n,i)}return b},CatmullRom:function(v,k){var m=v.length-1;var f=m*k;var i=Math.floor(f);var fn=TWEEN.Interpolation.Utils.CatmullRom;if(v[0]===v[m]){if(k<0){i=Math.floor(f=m*(1+k))}return fn(v[(i-1+m)%m],v[i],v[(i+1)%m],v[(i+2)%m],f-i)}else{if(k<0){return v[0]-(fn(v[0],v[0],v[1],v[1],-f)-v[0])}if(k>1){return v[m]-(fn(v[m],v[m],v[m-1],v[m-1],f-m)-v[m])}return fn(v[i?i-1:0],v[i],v[m1;i-=1){s*=i}a[n]=s;return s}})(),CatmullRom:function(p0,p1,p2,p3,t){var v0=(p2-p0)*0.5;var v1=(p3-p1)*0.5;var t2=t*t;var t3=t*t2;return(2*p1-2*p2+v0+v1)*t3+(-3*p1+3*p2-2*v0-v1)*t2+v0*t+p1}}};TWEEN.version=version;return TWEEN}))); \ No newline at end of file diff --git a/demo/backgroundPosition.html b/demo/backgroundPosition.html deleted file mode 100644 index fb99057..0000000 --- a/demo/backgroundPosition.html +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Background Position - - - - - - - - - - - - - - -
- - - -
-

Background Position

-

The component that animates the CSS property controling the background-position property of a target element.

-
- -
-
-
-
-

Overview

-

Animate the position of the background image, simple and effective.

-
-
-

The KUTE.js Background Position component enables animation for the CSS backgroundPosition property on most browsers.

-

It can handle an entire set of input values [x,y], '0% 50%' and even 'left center'. The component always updates the values of the position - property via % suffix for simplicity reasons and even if px or any other unit is supported.

-

While we might not have much use for this kind of animation, some older browsers will love to show you something if that is the case.

-
-
-
-
- -
- -

Example

- -

Here a couple of possible tween objects:

- -
// provide the exact values for interpolation
-let bgPosTween = KUTE.to('selector1',{backgroundPosition:[0,50]}).start();
-
-// provide the coordinates
-let bgPosTween = KUTE.to('selector1',{backgroundPosition:"0% 50%"}).start();
-
-// or provide the position names
-let bgPosTween = KUTE.to('selector1',{backgroundPosition:"left center"}).start();
-
- -
-
- -
- Start -
-
- -

Notes

-
    -
  • Unfortunatelly this property also has no access at the sub-pixel level, animations are as good as it gets, despite the fact that the % suffix is used.
  • -
  • There are thankfully replacements for this forgotten property that strangelly supports CSS3 transitions, you can simply use all kinds of SVG masks and filters - and the HTML Attributes component for much more animation potential and supreme animation quality.
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • - -
-
- - - - -
- - - - - - - - - - - - - - - diff --git a/demo/borderRadius.html b/demo/borderRadius.html deleted file mode 100644 index 4b962e2..0000000 --- a/demo/borderRadius.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - KUTE.js Border Radius - - - - - - - - - - - - - -
- - - -
-

Border Radius

-

The component that animates the CSS properties that control the radius of the corners of a target element.

-
- -
-
-
-
-

Overview

-

Animate the radius for all corners or a specific one for a target element.

-
-
-

The KUTE.js Border Radius component provides support for the CSS3 border-radius property and all corner variations.

-

The component accepts any measurement unit but the best results in terms of visual presentation are when you use %, em or any other - subpixel units.

-

Even if you don't provide any unit at all, the component will work it out with px.

-

For a quick reference, here are the properties supported:

-
-
-
-
- -
- -

Border Radius Properties

-
    -
  • borderRadius allows you to animate the border-radius on all corners for a given element.
  • -
  • borderTopLeftRadius allows you to animate the border-top-left-radius for a given element.
  • -
  • borderTopRightRadius allows you to animate the border-top-right-radius for a given element.
  • -
  • borderBottomLeftRadius allows you to animate the border-bottom-left-radiusfor a given element.
  • -
  • borderBottomRightRadius allows you to animate the border-bottom-right-radiusfor a given element.
  • -
- - -

Examples

-

OK let's have a look at some sample tween objects and a quick demo:

- -
KUTE.to('selector1',{borderRadius:'100%'}).start();
-KUTE.to('selector2',{borderTopLeftRadius:'100%'}).start();
-KUTE.to('selector3',{borderTopRightRadius:'5em'}).start();
-KUTE.to('selector4',{borderBottomLeftRadius:50}).start();
-KUTE.to('selector5',{borderBottomRightRadius:'20px'}).start();
-
- -
-
ALL
-
TL
-
TR
-
BL
-
BR
- -
- Start -
-
- -

Notes

-
    -
  • A quick reminder here is that the component does not support radius shorthand values, EG border-radius: 50px 20px.
  • -
  • The component does not use vendor property preffixes anymore, the major browsers don't need for quite some time now. If you want to support - legacy browsers, you still have the utilities available.
  • -
  • Early implementations from any browser that have been deprecated are also not supported.
  • -
  • This component is bundled with demo/src/kute-extra.js file.
  • - -
-
- - - - - -
- - - - - - - - - - - - - - - - - diff --git a/demo/boxModel.html b/demo/boxModel.html deleted file mode 100644 index fb43caf..0000000 --- a/demo/boxModel.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - KUTE.js Box Model - - - - - - - - - - - - - -
- - - - -
-

Box Model

-

The component that animates most of the CSS box model properties of a target element on all browsers.

-
- -
-
-
-
-

Overview

-

Animate the width, height, borderWidth or spacing for a target element on all browsers.

-
-
-

The KUTE.js Box Model component provides support for all box-model properties and all their variations.

-

Unlike other components, this one only works with px measurement unit, simply because these properties have no control at subpixel level. This means that even if you use % - as suffix, the computed values are still pixel based in all browsers.

-

Because modern browsers shine with transform animations and box model properties generally come with performance penalties and other animation - jank, they can be used as fallback for legacy browsers, for your very special clients of course.

-
-
-
-
- -
- -

Box Model Properties

-
    -
  • left, top, right and bottom are position based properties for movement on - vertical and / or horizontal axis. These properties require that the element to animate uses position: absolute/relative styling as well as it's parent element requires - position:relative. These properties can be used as fallback for browsers with no support for translate properties such as IE8.
  • -
  • width, height, minWidth, minHeight, maxWidth, - maxHeight are properties that allow you to animate the size of an element on horizontal and / or vertical axis. These properties can be used on images as fallback for - scale on IE8 again, as well as for other purposes.
  • -
  • padding, margin, paddingTop, paddingBottom, paddingLeft, - paddingRight, marginTop, marginBottom, marginLeft and - marginRight are properties that allow you to animate the spacing of an element inside (via padding) and outside (via margin).
  • -
  • borderWidth, borderTopWidth, borderRightWidth, borderBottomWidth are - borderLeftWidth are properties that allow you to animate the border of an element either on all sides at once or each side separatelly.
  • -
  • outlineWidth property allows you to animate the outline-width of an element.
  • -
-

The properties marked with different color, namely left, top, width and height are part of a lighter - version of the component called baseBoxModel.js, since they're the most used and probably most needed in just about every KUTE.js distribution.

- -

Examples

-

OK let's have a look at some sample tween objects and a quick demo:

- -
let tween1 = KUTE.to('selector1',{width:200})
-let tween2 = KUTE.to('selector1',{height:300})
-let tween3 = KUTE.to('selector1',{left:250})
-let tween4 = KUTE.to('selector1',{top:100})
-let tween5 = KUTE.to('selector1',{marginTop:200})
-let tween6 = KUTE.to('selector1',{marginBottom:50})
-let tween7 = KUTE.to('selector1',{padding:30})
-let tween8 = KUTE.to('selector1',{margin:'5px'})
-
- -

We're gonna chain these tweens and start the animation.

-
-
BOX
 MODEL 
- -
- Start -
-
- - -

Notes

-
    -
  • Shorthand notations such as margin: "20px 50px" or any other property are not supported.
  • -
  • Most box-model properties (except top, left, bottom and right) are layout modifiers and will not - produce the best visual experience mainly because they force re-paint on all page layout and they don't support animation under the pixel level.
  • -
  • The baseBoxModel component is featured in all distributions, while the full component is bundled with demo/src/kute-extra.js file.
  • -
- -
- - - - -
- - - - - - - - - - - - - - - - diff --git a/demo/clipProperty.html b/demo/clipProperty.html deleted file mode 100644 index fe6bf78..0000000 --- a/demo/clipProperty.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Clip Property - - - - - - - - - - - - - -
- - - -
-

Clip Property

-

The component that animates the CSS clip property of a target element on most browsers.

-
- -
-
-
-
-

Overview

-

Animate the clip property of a target element when certain conditions are met.

-
-
-

The KUTE.js Clip Property component enables animation for the CSS clip property on most browsers.

-

What exactly does it do? Well you can animate the visible rectangular shape of an element that is set to position:absolute. - If conditions are not met (more conditions apply, see notes below), the component will update the target element, but the effect is not visible.

-

Generally you can set the CSS rule for this property like this clip: rect(top,right,bottom,left) which forms a rectangular masking shape above - a target element making parts of it invisible.

-

While the CSS clip property has been deprecated, it can still be used to emulate a type of scale/reveal animation for legacy browsers in certain cases.

-

This component is bundled with the demo/src/kute-extra.js file.

-
-
-
-
- - -
- -

Example

-

A possible tween object using the property:

- -
KUTE.to('selector',{clip:[0,150,100,0]}).start();
- -

And a quick example here could look like this:

- -
-
- -
- Start -
-
- -

Notes

-
    -
  • The component will produce no effect for target elements that have overflow:visible style rule.
  • -
  • Also target elements without position:absolute CSS rule will produce no effect.
  • -
  • This property will only work with px unit for the rectangular mask, which is unfortunate.
  • -
  • Don't stop here, there are thankfully replacements for this property, you can simply use all kinds of SVG masks and filters in combination - with the HTML Attributes component for much more animation potential and for no compromise on animation quality.
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • -
- -
- - - - -
- - - - - - - - - - - - - diff --git a/demo/colorProperties.html b/demo/colorProperties.html deleted file mode 100644 index efea12f..0000000 --- a/demo/colorProperties.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - KUTE.js Color Properties - - - - - - - - - - - - - -
- - - -
-

Color Properties

-

The component that animates CSS color properties for Element targets on most browsers.

-
- -
-
-
-
-

Overview

-

Animate color properties for a target element and updates its CSS style via RGB.

-
-
-

The KUTE.js Color Properties component provides support for all color properties and all their variations on most browsers.

-

While with previous versions we used to have a keepHex option to always use the HEX format of the output color, modern browsers outright ignore the option and always - deliver colors in RGB format, probably for performance reasons.

- -

The component supports input values such as HEX, RGB and RGBA for all color properties and most browsers should also work with - web safe colors, eg. color: 'red'.

- -

For a quick reference, here are all the supported properties:

-
-
-
-
- -
- -

Supported Properties

-
    -
  • color allows you to animate the color for a target text element. Eg. color: '#ff0000'.
  • -
  • backgroundColor allows you to animate the background-color for a target element. Eg. backgroundColor: 'rgb(202,150,20)'.
  • -
  • outlineColor allows you to animate the outline-color for a target element. Eg. outline-color: 'cyan'.
  • -
  • borderColor allows you to animate the border-color on all sides for a target element. Eg. borderColor: 'rgba(250,100,20,0.5)'.
  • -
  • borderTopColor, borderRightColor, borderBottomColor and borderLeftColor properties allow - you to animate the color of the border on each side of a target element. Eg. borderTopColor: 'rgb(0,66,99)'.
  • -
- -

Examples

-

OK let's have a look at some sample tween objects and a quick demo:

- -
KUTE.to('selector1',{color:'rgb(0,66,99)'}).start();
-KUTE.to('selector1',{backgroundColor:'#069'}).start();
-KUTE.to('selector1',{borderColor:'turquoise'}).start(); // IE9+
-
- -
-
Colors
- -
- Start -
-
- -

Notes

-
    -
  • The component will NOT work with SVGElement targets and their specific color attributes like fill or stroke, for that you can use the - HTML Attributes component.
  • -
  • To simplify your workflow, the value processing can also work with web safe colors like steelblue or darkorange.
  • -
  • You can also use RGB or RGBA, but the last one is not supported on legacy browsers and it should fallback to RGB.
  • -
  • Some properties like borderColor and its variations or outlineColor won't have any visible effect if no border or outline style is applied to - your target element.
  • -
  • This component is bundled with the standard kute.js distribution file and the demo/src/kute-extra.js file.
  • - -
- -
- - - - -
- - - - - - - - - - - - - - - - diff --git a/demo/filterEffects.html b/demo/filterEffects.html deleted file mode 100644 index 18fb47a..0000000 --- a/demo/filterEffects.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Filter Effects - - - - - - - - - - - - - - -
- - - -
-

Filter Effects

-

The component that animates the CSS3 filter property for specific Element targets on modern browsers.

-
- -
-
-
-
-

Overview

-

Animate filter functions for a target Element and deliver the best possible animation.

-
-
-

The KUTE.js Filter Effects component provides support for the CSS3 filter property on modern browsers.

-

The component covers all filter functions, except that the url() function cannot be animated, however the component will - try and keep it's value into the target element styling at all times.

-

Similar to the Transform Functions and the Transform Matrix components, - this component will try and keep same order of the filter functions, regardless of the input order, and the reason is that chained animations can - have some unwanted janky artifact effects.

-

Most values are in [0-Infinity] range and the presentation is delivered with % suffixed values, except blur() which uses px - as unit/suffix.

-
-
-
-
- -
-

Filter Functions

-
    -
  • url() function links an element to an SVG filter, the function is supported to keep it's value into the target element's style in case it's set - initially or you want to set it yourself.
  • -
  • opacity() can animate the opacity for a target element in the 0-100% range. Default is 100%.
  • -
  • blur() can animate the blur for a target element in the 0-Infinity range. Default is 0px and the unit is always px.
  • -
  • saturate() can animate the color saturation for a target element in the 0-Infinity range. Default is 100%.
  • -
  • grayscale() can animate the color desaturation for a target element in the 0-100% range. Default is 0%.
  • -
  • brightness() can animate the brightness for a target element in the 0-Infinity range. Default is 100%.
  • -
  • contrast() can animate the contrast for a target element in the 0-Infinity range. Default is 100%.
  • -
  • sepia() can animate the sepia filter for a target element in the 0-100% range. Default is 0%.
  • -
  • invert() can animate the color inversion for a target element in the 0-100% range. Default is 0%.
  • -
  • hueRotate() can animate the color hue rotation for a target element in the 0-Infinity range. Default is 0deg.
  • -
  • dropShadow() can animate the shadow and all related parameters for a target element. Default is [0,0,0,'black']
  • -
- -

Examples

-

Let's have a look at some sample tween objects and a quick example:

- -
let fe1 = KUTE.to('selector1', {filter :{ blur: 5 }})
-let fe2 = KUTE.to('selector2', {filter :{ sepia: 50, invert: 80 }})
-let fe3 = KUTE.to('selector3', {filter :{ saturate: 150, brightness: 90 }})
-let fe4 = KUTE.to('selector4', {filter :{ url: '#mySVGFilter', opacity: 40, dropShadow:[5,5,5,'olive'] }})
-
- -
- - - - - - - - - - - - - - -
FE1
-
FE2
-
FE3
-
FE4
- -
- Start -
-
-

Notes

-
    -
  • The CSS filter property is supported on all major browsers nowadays, but it's better to check and - double check.
  • -
  • This component can be a great addition to all SVG related components, especially because the dropShadow provides a better experience than - boxShadow, as shown here.
  • -
  • Since this component can work with the url() function the way it does, the HTML Attributes component will - complement greatly for even more animation potential.
  • -
  • Similar to the HTML Attributes component, this one can also deal with specific function namespace, for instance hue-rotate and - hueRotate.
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • -
-
- - - - -
- - - - - - - - - - - - - - diff --git a/demo/htmlAttributes.html b/demo/htmlAttributes.html deleted file mode 100644 index 089375a..0000000 --- a/demo/htmlAttributes.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - - - - - - - - KUTE.js HTML Attributes - - - - - - - - - - - - - -
- - - -
-

HTML Attributes

-

The component that animates color attributes or any single value presentation attribute of a target element on most browsers.

-
- -
-
-
-
-

Overview

-

Animate a wide variety of presetantion attributes of a target element.

-
-
-

The KUTE.js HTML Attributes component enables animation for any numeric presentation attribute, with or without a measurement unit / suffix as well as specific color attributes.

-

The component can be a great asset for creating complex animations in combination with the SVG components as we'll see in the following examples.

-

The component doesn't support attributes with multiple values like stroke-dasharray, viewBox or transform for specific reasons. To animate the stroke related attributes, the - SVG Draw component is the tool for you, while for transform you have the SVG Transform component and the - Transform Matrix component.

-

Despite the "limitations" of this component, you have access to just about any SVGElement or Element - presentation attribute available.

-
-
-
-
- -
-

General Usage

- -
// basic notation for unitless attributes
-var myAttrTween = KUTE.to('selector', {attr: {attributeName: 75}});
-
-// OR for attributes that are ALWAYS suffixed / have a measurement unit
-var mySuffAttrTween = KUTE.to('selector', {attr:{attributeName: '15%'}});
-
- -

Attributes Namespace

-

The HTML Attributes component can handle all possible single value presentation attributes with both dashed string and camel-case notation. Let's have a look at a sample notation so you can - get the idea:

- -
// dashed attribute notation
-var myDashedAttrStringTween = KUTE.to('selector', {attr: {'stroke-width': 75}});
-
-// non-dashed attribute notation
-var myNonDashedAttrStringTween = KUTE.to('selector', {attr:{strokeWidth: '15px'}});
-
- -

The strokeWidth attribute is very interesting because it can work with px, % or with no unit/suffix. In this case, and in any context, the component will always work with the - attribute's current value suffix to eliminate any possible janky animation.

- -

Examples

-

Color Attributes

-

The HTML Attributes component can also animate color attributes: fill, stroke and stopColor. If the elements are affected by their CSS counterparts, the effect - is not visible, you need to make sure that doesn't happen.

- -
// some fill rgb, rgba, hex
-var fillTween = KUTE.to('#element-to-fill', {attr: { fill: 'red' }});
-
-// some stopColor or 'stop-color'
-var stopColorTween = KUTE.to('#element-to-do-stop-color', {attr: {stopColor: 'rgb(0,66,99)'}});
-
- -
- - - - - -
- Start -
-
-

If in this example the fill attribute value would reference a gradient, then rgba(0,0,0,0) is used. Keep in mind that the component will not work with combined - fill values like url(#pattern) rgba(), you are better of only using the url(#pattern) and use other attributes to control directly the animation of that - linked pattern, just like in the last example below.

- -

Unitless Attributes

-

In the next example, let's play with the attributes of a <circle> element: radius and center coordinates.

- -
// radius attribute
-var radiusTween = KUTE.to('#circle', {attr: {r: 75}});
-
-// coordinates of the circle center
-var coordinatesTween = KUTE.to('#circle', {attr:{cx:0,cy:0}});
-
- -

A quick demo with the above:

- -
- - - - -
- Start -
-
- -

Suffixed Attributes

-

Similar to the example on circle attributes, we can also animate the gradient positions but this time with a specific to gradients suffix, and the component will make sure - to always include the suffix for you, as in this example the % unit is found in the current value and used as unit for the DOM update:

- -
// gradient positions to middle
-var closingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'49%', y1:'49%', y2:'49%'}});
-
-// gradient positions rotated
-var rotatingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'51%', y1:'51%', y2:'51%'}});
-
- -
- - - - - - - - - - -
- Start -
-
- -

Notes

-
    -
  • The power of this little gem comes from the fact that it can work with internally undefined/unknown attributes, as well as with attributes that are not yet present in the W3 draft. As long as you provide valid values specific - to the attribute, the component will assign an update function and will always double check for the current value to determine if it needs a suffix or if the attribute name needs adjustments - (EG: fillOpacity becomes fill-opacity).
  • -
  • This component is a great addition to complement any SVG related component as well as a great complement to Filter Effects component.
  • -
  • Remember to check your elements markup for changes, your animation might not be visible because equivalent CSS is used.
  • -
  • This component is bundled with the standard kute.js distribution file and the demo/src/kute-extra.js file.
  • -
-
- - - -
- - - - - - - - - - - - diff --git a/demo/index.html b/demo/index.html deleted file mode 100644 index c6032b8..0000000 --- a/demo/index.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - - - - - - - KUTE.js | JavaScript Animation Engine - - - - - - - - - - - - - - -
- - - -
-
-
-
-
-
-
-
-
-
-

Welcome to KUTE.js!

-
-
-

The JavaScript animation engine of the future

-
-
-

The magic behind Spicr, the result of hard work, - the bridge between old and new, the dream and inspiration.

-
-
-

- Download - Github - NPM - CDN -

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

Forward Looking

-

The modern JavaScript powering the core functionality, the modular architecture, the solid and complete components are all geared towards the future of web development.

-
-
-
-
-
-
-

Knowing the Past

-

While KUTE.js was re-developed to support mainly modern browsers, it also leaves the door open to old browsers with its legacy components, tools and polyfills.

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

ES6+ JavaScript

-
-
-

Inside the sources you will find fast & modern JavaScript code with solid build tools. Everything and anything can be done with SVGElement, - HTML attributes, CSS transform, etc.

-
-
-
-
-
-
-
-
-

Cubic Bezier Easing

-
-
-

While the library includes Robert Penner's easing functions, KUTE.js also includes its own - CubicBezier Easing class to provide fast and accurate easing for your animation.

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

What's not to love about it?

-

Yeah, the open source, modular and fully featured animation engine for the modern web, fully documented and MIT Licensed.

-

Any question? Find answers here, or post them here!

-
-
-
-
-
- -
    -
  1. -
  2. -
  3. -
  4. -
- - - - - - - - - - - - - - -
- -
-
-
-
-

Overview

-

If you're looking for that spicy tool to kickstart your animations, developed with latest technology and modular design, you will love KUTE.js.

-
-
- -

The JavaScript animation engine reimagined for the evolving modern web, the library that keeps track on the changing standards, the modular tool - to enable creativity.

-

Built on modern ES6+ JavaScript Standard, packed with utilities, build tools and a wide range of supported properties, KUTE.js is now a fully featured animation engine - you can use to create complex animations, with properties or elements that cannot be animated with CSS3 transitions or other animation engines, or attributes that aren't - even drafted in the specification yet.

- -

The JavaScript animation engine that never stops evolving just like we never stop learning. Instead of becoming more bloated, we make it more modular, - instead of compromising we chose innovating.

-

While KUTE.js doesn't activelly support legacy browsers, it provides a wide range of tools and utilities you can use to create a fallback animation for every browser - and property.

-

The demo pages use a dedicated polyfill for IE10+ browsers, but today we have polyfill services and a wide range of - browser detection options to handle legacy browsers, our focus here is the highest performance on modern browsers.

-

By the way, KUTE.js is really fast.

-
-
- -
-
- -
- -
-
-

ES6+ JavaScript

-

The entire codebase reworked on the latest standards with flexible rollup based build tools. Most classes are extensible via the ES6 extend - or your usual prototype, depending on the class.

-
-
-

Lots of Components

-

All your previously supported properties and plugins have been split into components for more modularity. New additions have been added for a broader scope. - The official distribution only includes most popular components.

-
-
-

Familiar Syntax

-

You can create your tween objects with a familiar syntax with your trusted options, the callback system and other component related options.

-
-
-

Tools and Options

-

Along the wide range of options, certain components provide tools for further control over the outcome. Also there's a progress - bar somewhere.

-
-
-

Well Documented

-

Each component demo page comes packed with tons of guides and tips on how to optimize the performance and visual presentation.

-
-
-

MIT License

-

The library is released under the MIT License.

-
- -
-
- - - - -
- - - - - - - - - - - - - - - diff --git a/demo/opacityProperty.html b/demo/opacityProperty.html deleted file mode 100644 index 60fba38..0000000 --- a/demo/opacityProperty.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Opacity Property - - - - - - - - - - - - - - -
- - - -
-

Opacity Property

-

The component that animates the CSS opacity property of a target Element on most browsers.

-
- -
-
-
-
-

Overview

-

Animate the opacity property of a target element.

-
-
-

The KUTE.js Opacity Property component enables animation for the opacity CSS property of an Element target on most browsers.

-

In most cases, the best presentatation can be offered with a nice and smooth fade animation, with opacity going from 0% all the way up to to 100%.

- -

While some components like HTML Attributes and Filter Effects do provide some - similar functionality for specific Element types, this component covers all types of elements and is supported on a wide range of modern - and legacy browsers alike.

-
-
-
-
- -
- -

Example

- -
// fade out
-let fadeOutTween = KUTE.to('selector1',{opacity:0}).start()
-
-// fade in
-let fadeInTween = KUTE.to('selector1',{opacity:1}).start()
-
- -
-
- - - -
- -
- -

Notes

-
    -
  • This demo should work with IE9+ browsers.
  • -
  • Support for the specific IE8 filter:alpha(opacity=50) have been dropped.
  • -
  • Early implementations with vendor preffixes such as -o-opacity, -moz-opacity or -ms-opacity are not supported.
  • -
  • The component is an essential part in ALL KUTE.js distributions.
  • -
-
- - - - -
- - - - - - - - - - - - - - diff --git a/demo/performance-matrix.html b/demo/performance-matrix.html deleted file mode 100644 index 5448109..0000000 --- a/demo/performance-matrix.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - KUTE.js | Transform Matrix Performance Testing Page - - - - - -
- -
- -
- -
-

These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, here's how.

-

Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.

- - -
- -
- - - - - - - - - - - - diff --git a/demo/performance-transform.html b/demo/performance-transform.html deleted file mode 100644 index 0b4b697..0000000 --- a/demo/performance-transform.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - - - - - -KUTE.js | Regular Transform Performance Testing Page - - - - - -
- - -
- -
- -
- -

These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, here's how.

-

Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.

- -
- -
- - - - - - - - - - diff --git a/demo/performance.html b/demo/performance.html deleted file mode 100644 index d91aeb4..0000000 --- a/demo/performance.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - - - - - - - -KUTE.js | Performance Testing Page - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-

These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, here's how.

-

Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.

- - -
- -
- - - - - - - - - - - - - - - - - - diff --git a/demo/progress.html b/demo/progress.html deleted file mode 100644 index 1d08be7..0000000 --- a/demo/progress.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - - - - - - - KUTE.js Using Update Functions | Javascript Animation Engine - - - - - - - - - - - - - - -
- - - -
-

Tween Progress Control

-

The handy tool to manually update a tween via an Input slider.

-
- -
-
-
-
-

Overview

-

Create a tween object and link it to a range slider Input. Some stuff happening.

-
-
-

The Progress Bar can be a handy tool that enables you to manually update your tween animation, just in case there is a little - detail you want to make it right.

-

KUTE.js object exposes all required methods in order for it to work, so why not try to do something fun? How about control tween progress? So let's make a quick tool:

-
    -
  • We need an <input type="range" min="0" max="1" step="0.00001" /> with these exact min, max and step attributes
  • -
  • Now we need a tween object, let's just do a svg morph for instance, but make sure you use KUTE.fromTo() method, the others don't prepare start values for the tween object
  • -
  • We also need to make sure nothing controls the progress except the range input, so don't use start() or pause() methods at all, as well as repeat and / or yoyo options
  • -
  • Next we attach an input event handler to update the tween progress by using the KUTE.update function, which is the step function triggered on every requestAnimationFrame tick
  • -
-
-
- -
-
- -
- - -

A very basic code sample will look like this:

- - -
// the range slider
-var rangeSlider = document.querySelector('input[type="range"');
-
-// basic morph, only fromTo and allFromTo should work
-var morphTween = KUTE.to('#rectangle', { path: '#star' } );  
-
-// initialize a progressBar for your tween
-var progressBar = new KUTE.ProgressBar(rangeSlider,morphTween)
-
-// also start animation when Element is clicked
-document.getElementById('rectangle').addEventListener('click',function(){
-!morphTween.playing && morphTween.start()
-})
-
- -

And now let's see the code in action:

-
-
- - 0% -
- - - - -
- -

We might argue that we want to use other methods in combination with this method, or use this method while animations are running, but there are other libraries out there that can do that already. This example here is just to showcase KUTE.js can do this too.

-

Note that this tool is not included in the official distribution file.

- -
- - - - -
- - - - - - - - - - - - - diff --git a/demo/scrollProperty.html b/demo/scrollProperty.html deleted file mode 100644 index 77e16dc..0000000 --- a/demo/scrollProperty.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Scroll Property - - - - - - - - - - - - - - - -
- - - -
-

Scroll Property

-

The component that animates the vertical scrolling of a target Element as well as the <window> on most browsers.

-
- -
-
-
-
-

Overview

-

The fully reworked component for vertical scrolling animation is an essential part of KUTE.js.

-
-
-

The KUTE.js Scroll Property component enables animation for the vertical scroll of a target Element or the - <window> on most browsers.

-

The vertical scrollling animation is a popular choice to spice up the in-page navigation, and most websites use a Back To Top button for - scrolling all the way back to top. For this reason, our component doesn't support horizontal scrolling animation.

-

The component also uses passive event option for best possible performance along with other improvements like removed the need to use - additional CSS or the use of data-scrolling attribute on the <body> element.

-

On animation start, the component will lock down all possible pointer events of the animation target to - avoid any unwanted animation glitches.

-
-
-
-
- -
- -

Example

- -
// all websites to top button
-KUTE.to(window,{scroll:0}).start()
-
-// scroll to a certain element
-KUTE.to(window,{scroll: document.getElementById('myElement').offsetTop }).start()
-
-// scroll to top an overflowing target element
-KUTE.to('#myElement',{scroll: 0 }).start()
-
- -
-
-

KUTE.js Scroll Property

-

Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy - foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive - innovation via workplace diversity and empowerment.

- -

Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal - that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in - real-time will have multiple touchpoints for offshoring.

- -

Capitalize on low hanging fruit to identify a ballpark value added activity to beta test. Override the digital divide with - additional clickthroughs from DevOps. Nanotechnology immersion along the information highway will close the loop on focusing - solely on the bottom line.

- -

Second Sample Heading

- -

Podcasting operational change management inside of workflows to establish a framework. Taking seamless key performance indicators - offline to maximise the long tail. Keeping your eye on the ball while performing a deep dive on the start-up mentality to derive - convergence on cross-platform integration.

- -

Collaboratively administrate empowered markets via plug-and-play networks. Dynamically procrastinate B2C users after installed - base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.

-
- -
- -
-
-

scroll-behavior: smooth

-

Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy - foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive - innovation via workplace diversity and empowerment.

- -

Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal - that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in - real-time will have multiple touchpoints for offshoring.

- -

Capitalize on low hanging fruit to identify a ballpark value added activity to beta test. Override the digital divide with - additional clickthroughs from DevOps. Nanotechnology immersion along the information highway will close the loop on focusing - solely on the bottom line.

- -

Second Sample Heading

- -

Podcasting operational change management inside of workflows to establish a framework. Taking seamless key performance indicators - offline to maximise the long tail. Keeping your eye on the ball while performing a deep dive on the start-up mentality to derive - convergence on cross-platform integration.

- -

Collaboratively administrate empowered markets via plug-and-play networks. Dynamically procrastinate B2C users after installed - base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.

-
-
- Bottom -
-
- Top -
-
-

The above shows a comparison of the Scroll Property component with the scroll-behavior: smooth CSS; while this browser - feature shows excellent performance it lacks the flexibility and support for legacy browsers.

- -

Notes

-
    -
  • The Scroll Property component will lock down any pointer event such as click, touch, or any other event of the target on - animation start to prevent any kind of animation glitches, so make sure to filter your tweens, perhaps you can take a look at the - scrollProperty.js sample code.
  • -
  • The scroll animation is not as smooth as with transform animations, it has no access at sub-pixel level, but you can play around - with various easing functions and durations to find the best possible outcome.
  • -
  • All pages in this documentation have a <a>Back to top</a> button at the bottom, just in case you didn't notice, but - only on this page scrollProperty component is used.
  • -
  • The component is only bundled with the demo/src/kute-extra.js file and not in the official build. That is thanks to - scroll-behavior, but you can include this component in your custom builds to enable scrolling for legacy browsers.
  • -
- -
- - - - -
- - - - - - - - - - - - - - diff --git a/demo/shadowProperties.html b/demo/shadowProperties.html deleted file mode 100644 index ba14f32..0000000 --- a/demo/shadowProperties.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Shadow Properties - - - - - - - - - - - - - - -
- - - -
-

Shadow Properties

-

The component that animates shadow properties of a specific target element on most browsers.

-
- -
-
-
-
-

Overview

-

Animate the shadow properties of a target element.

-
-
-

The KUTE.js Shadow Properties component enables animation for the text-shadow CSS property of text elements - as well as the box-shadow property of any element on most browsers.

-

The functionality was developed while writing a guide on how to extend KUTE.js a couple of years ago and is now a fully featured component.

-

The component uses px as unit for the shadow parameters, can animate the color of the shadow and can also handle the inset shadow parameter - of the boxShadow property.

-

OK let's have a look at a couple of quick examples:

-
-
-
-
- -
- -

Box Shadow

- -
// tween to a string value
-var myBSTween1 = KUTE.to('selector', {boxShadow: '10px 10px #069'}).start();
-
-// or a fromTo with string and array, hex and rgb
-var myBSTween2 = KUTE.fromTo(
-'selector',                         // target
-{boxShadow: [0, 0, 0, '#069']},     // from
-{boxShadow: '5px 5px rgb(0,0,0)'})  // to
-.start();
-
-// maybe you want to animate an inset boxShadow?
-var myBSTween3 = KUTE.fromTo(
-'selector',                                // target
-{boxShadow: [5, 5, 0, '#069', 'inset']},   // from
-{boxShadow: '0px 0px rgb(0,0,0)'})         // to
-.start();
-
- -
-
-
- Start -
-
- -

Text Shadow

- -
// tween to a string value
-var myTSTween1 = KUTE.to('selector', {textShadow: '10px 10px #069'}).start();
-
-// or a fromTo with string and array, hex and rgb
-var myTSTween2 = KUTE.fromTo(
-'selector',                          // target
-{textShadow: [0, 0, 0, '#069']},     // from
-{textShadow: '5px 5px rgb(0,0,0)'})  // to
-.start();
-
- -
-
Sample Text
- -
- Start -
-
- -

Notes

-
    -
  • The component will NOT handle multiple shadows per target at the same time.
  • -
  • The component features a solid value processing script, it can handle a great deal of combinations of input values.
  • -
  • I highly recommend that you check the boxShadow.js for more insight.
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • -
- -
- - - - -
- - - - - - - - - - - - - - - diff --git a/demo/src/kute-base.js b/demo/src/kute-base.js deleted file mode 100644 index fe676be..0000000 --- a/demo/src/kute-base.js +++ /dev/null @@ -1,908 +0,0 @@ -/*! -* KUTE.js Base v2.2.3 (http://thednp.github.io/kute.js) -* Copyright 2015-2021 © thednp -* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) -*/ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); -})(this, (function () { 'use strict'; - - /** - * The KUTE.js Execution Context - */ - var KEC = {}; - - var Tweens = []; - - var gl0bal; - - if (typeof global !== 'undefined') { gl0bal = global; } - else if (typeof window !== 'undefined') { gl0bal = window.self; } - else { gl0bal = {}; } - - var globalObject = gl0bal; - - // KUTE.js INTERPOLATE FUNCTIONS - // ============================= - var interpolate = {}; - - // schedule property specific function on animation start - // link property update function to KUTE.js execution context - var onStart = {}; - - // Include a performance.now polyfill. - // source https://github.com/tweenjs/tween.js/blob/master/src/Now.ts - var performanceNow; - - // In node.js, use process.hrtime. - // eslint-disable-next-line - // @ts-ignore - if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { - performanceNow = function () { - // eslint-disable-next-line - // @ts-ignore - var time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; - } else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { - // In a browser, use self.performance.now if it is available. - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - performanceNow = self.performance.now.bind(self.performance); - } else if (typeof Date !== 'undefined' && Date.now) { - // Use Date.now if it is available. - performanceNow = Date.now; - } else { - // Otherwise, use 'new Date().getTime()'. - performanceNow = function () { return new Date().getTime(); }; - } - - var now = performanceNow; - - var Time = {}; - Time.now = now; - - // eslint-disable-next-line import/no-mutable-exports -- impossible to satisfy - var Tick = 0; - - /** - * - * @param {number | Date} time - */ - var Ticker = function (time) { - var i = 0; - while (i < Tweens.length) { - if (Tweens[i].update(time)) { - i += 1; - } else { - Tweens.splice(i, 1); - } - } - Tick = requestAnimationFrame(Ticker); - }; - - // stop requesting animation frame - function stop() { - setTimeout(function () { // re-added for #81 - if (!Tweens.length && Tick) { - cancelAnimationFrame(Tick); - Tick = null; - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - if (KEC[obj]) { delete KEC[obj]; } - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - if (KEC[prop]) { delete KEC[prop]; } - }); - } - }); - - Object.keys(interpolate).forEach(function (i) { - if (KEC[i]) { delete KEC[i]; } - }); - } - }, 64); - } - - // render update functions - // ======================= - var Render = { - Tick: Tick, Ticker: Ticker, Tweens: Tweens, Time: Time, - }; - Object.keys(Render).forEach(function (blob) { - if (!KEC[blob]) { - KEC[blob] = blob === 'Time' ? Time.now : Render[blob]; - } - }); - - globalObject._KUTE = KEC; - - var defaultOptions = { - duration: 700, - delay: 0, - easing: 'linear', - repeat: 0, - repeatDelay: 0, - yoyo: false, - resetStart: false, - offset: 0, - }; - - // link properties to interpolate functions - var linkProperty = {}; - - // schedule property specific function on animation complete - var onComplete = {}; - - var Objects = { - defaultOptions: defaultOptions, - linkProperty: linkProperty, - onStart: onStart, - onComplete: onComplete, - }; - - // util - a general object for utils like rgbToHex, processEasing - var Util = {}; - - var connect = {}; - /** @type {KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra} */ - connect.tween = null; - connect.processEasing = null; - - // Select Robert Penner's Easing Functions - // updated for ESLint - var Easing = { - /** @type {KUTE.easingFunction} */ - linear: function (t) { return t; }, - /** @type {KUTE.easingFunction} */ - easingQuadraticIn: function (t) { return t * t; }, - /** @type {KUTE.easingFunction} */ - easingQuadraticOut: function (t) { return t * (2 - t); }, - /** @type {KUTE.easingFunction} */ - easingQuadraticInOut: function (t) { return (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t); }, - /** @type {KUTE.easingFunction} */ - easingCubicIn: function (t) { return t * t * t; }, - /** @type {KUTE.easingFunction} */ - easingCubicOut: function (t0) { var t = t0 - 1; return t * t * t + 1; }, - /** @type {KUTE.easingFunction} */ - easingCubicInOut: function (t) { return (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1); }, - /** @type {KUTE.easingFunction} */ - easingCircularIn: function (t) { return -(Math.sqrt(1 - (t * t)) - 1); }, - /** @type {KUTE.easingFunction} */ - easingCircularOut: function (t0) { var t = t0 - 1; return Math.sqrt(1 - t * t); }, - /** @type {KUTE.easingFunction} */ - easingCircularInOut: function (t0) { - var t = t0 * 2; - if (t < 1) { return -0.5 * (Math.sqrt(1 - t * t) - 1); } - t -= 2; return 0.5 * (Math.sqrt(1 - t * t) + 1); - }, - /** @type {KUTE.easingFunction} */ - easingBackIn: function (t) { var s = 1.70158; return t * t * ((s + 1) * t - s); }, - /** @type {KUTE.easingFunction} */ - easingBackOut: function (t0) { - var s = 1.70158; - var t = t0 - 1; - return t * t * ((s + 1) * t + s) + 1; - }, - /** @type {KUTE.easingFunction} */ - easingBackInOut: function (t0) { - var s = 1.70158 * 1.525; - var t = t0 * 2; - if (t < 1) { return 0.5 * (t * t * ((s + 1) * t - s)); } - t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2); - }, - }; - - /** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easing function - */ - function processEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof Easing[fn] === 'function') { - return Easing[fn]; // regular Robert Penner Easing Functions - } - return Easing.linear; - } - - connect.processEasing = processEasing; - - /** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var add = function (tw) { return Tweens.push(tw); }; - - /** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var remove = function (tw) { - var i = Tweens.indexOf(tw); - if (i !== -1) { Tweens.splice(i, 1); } - }; - - /** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ - var getAll = function () { return Tweens; }; - - /** - * KUTE.removeAll() - */ - var removeAll = function () { Tweens.length = 0; }; - - // all supported properties - var supportedProperties = {}; - - /** - * linkInterpolation - * @this {KUTE.Tween} - */ - function linkInterpolation() { - var this$1$1 = this; - // DON'T change - Object.keys(linkProperty).forEach(function (component) { - var componentLink = linkProperty[component]; - var componentProps = supportedProperties[component]; - - Object.keys(componentLink).forEach(function (fnObj) { - if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius - && Object.keys(this$1$1.valuesEnd).some(function (i) { return (componentProps && componentProps.includes(i)) - || (i === 'attr' && Object.keys(this$1$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); })); })) { - if (!KEC[fnObj]) { KEC[fnObj] = componentLink[fnObj]; } - } else { - Object.keys(this$1$1.valuesEnd).forEach(function (prop) { - var propObject = this$1$1.valuesEnd[prop]; - if (propObject instanceof Object) { - Object.keys(propObject).forEach(function (i) { - if (typeof (componentLink[i]) === 'function') { // transformCSS3 - if (!KEC[i]) { KEC[i] = componentLink[i]; } - } else { - Object.keys(componentLink[fnObj]).forEach(function (j) { - if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix - if (!KEC[j]) { KEC[j] = componentLink[i][j]; } - } - }); - } - }); - } - }); - } - }); - }); - } - - var internals = { - add: add, - remove: remove, - getAll: getAll, - removeAll: removeAll, - stop: stop, - linkInterpolation: linkInterpolation, - }; - - /** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ - function selector(el, multi) { - try { - var requestedElem; - var itemsArray; - if (multi) { - itemsArray = el instanceof Array && el.every(function (x) { return x instanceof Element; }); - requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray - ? el : document.querySelectorAll(el); - } else { - requestedElem = el instanceof Element || el === window // scroll - ? el : document.querySelector(el); - } - return requestedElem; - } catch (e) { - throw TypeError(("KUTE.js - Element(s) not found: " + el + ".")); - } - } - - /** - * Animation Base Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * This class only registers the minimal amount of component information - * required to enable components animation, which means value processing - * as well as `to()` and `allTo()` methods are not supported. - */ - var AnimationBase = function AnimationBase(Component) { - var ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty } - var Functions = { onStart: onStart, onComplete: onComplete }; - var Category = Component.category; - var Property = Component.property; - // ESLint - this._ = 0; - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach(function (fn) { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; } - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach(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) { - Object.keys(Component.Interpolate).forEach(function (fni) { - var compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach(function (sfn) { - if (typeof (compIntObj[sfn]) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach(function (fnu) { - if (!Util[fnu]) { Util[fnu] = Component.Util[fnu]; } - }); - } - - return { name: ComponentName }; - }; - - /** - * Perspective Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the perspective function in string format - */ - function perspective(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return ("perspective(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + u + ")"); - } - - /** - * Translate 3D Interpolation Function. - * - * @param {number[]} a start [x,y,z] position - * @param {number[]} b end [x,y,z] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D translation string - */ - function translate3d(a, b, u, v) { - var translateArray = []; - for (var ax = 0; ax < 3; ax += 1) { - translateArray[ax] = (a[ax] || b[ax] - // eslint-disable-next-line no-bitwise - ? ((a[ax] + (b[ax] - a[ax]) * v) * 1000 >> 0) / 1000 : 0) + u; - } - return ("translate3d(" + (translateArray.join(',')) + ")"); - } - - /** - * 3D Rotation Interpolation Function. - * - * @param {number} a start [x,y,z] angles - * @param {number} b end [x,y,z] angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D rotation string - */ - function rotate3d(a, b, u, v) { - var rotateStr = ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[0] || b[0] ? ("rotateX(" + (((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[1] || b[1] ? ("rotateY(" + (((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[2] || b[2] ? ("rotateZ(" + (((a[2] + (b[2] - a[2]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - return rotateStr; - } - - /** - * Translate 2D Interpolation Function. - * - * @param {number[]} a start [x,y] position - * @param {number[]} b end [x,y] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 2D translation string - */ - function translate(a, b, u, v) { - var translateArray = []; - // eslint-disable-next-line no-bitwise - translateArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')) + ")"); - } - - /** - * 2D Rotation Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated rotation - */ - function rotate(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return ("rotate(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + u + ")"); - } - - /** - * Scale Interpolation Function. - * - * @param {number} a start scale - * @param {number} b end scale - * @param {number} v progress - * @returns {string} the interpolated scale - */ - function scale(a, b, v) { - // eslint-disable-next-line no-bitwise - return ("scale(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + ")"); - } - - /** - * Skew Interpolation Function. - * - * @param {number} a start {x,y} angles - * @param {number} b end {x,y} angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated string value of skew(s) - */ - function skew(a, b, u, v) { - var skewArray = []; - // eslint-disable-next-line no-bitwise - skewArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')) + ")"); - } - - // Component Functions - /** - * Sets the property update function. - * * same to svgTransform, htmlAttributes - * @param {string} tweenProp the property name - */ - function onStartTransform(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0 - + (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z] - + (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z] - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } - } - - // Base Component - var TransformFunctionsBase = { - component: 'baseTransform', - property: 'transform', - functions: { onStart: onStartTransform }, - Interpolate: { - perspective: perspective, - translate3d: translate3d, - rotate3d: rotate3d, - translate: translate, - rotate: rotate, - scale: scale, - skew: skew, - }, - }; - - /** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ - function numbers(a, b, v) { - var A = +a; - var B = b - a; - // a = +a; b -= a; - return A + B * v; - } - - // Component Functions - /** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - function boxModelOnStart(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - /* eslint-disable no-bitwise -- impossible to satisfy */ - elem.style[tweenProp] = (v > 0.99 || v < 0.01 - ? ((numbers(a, b, v) * 10) >> 0) / 10 - : (numbers(a, b, v)) >> 0) + "px"; - /* eslint-enable no-bitwise */ - /* eslint-enable no-param-reassign */ - }; - } - } - - // Component Base Props - var baseBoxProps = ['top', 'left', 'width', 'height']; - var baseBoxOnStart = {}; - baseBoxProps.forEach(function (x) { baseBoxOnStart[x] = boxModelOnStart; }); - - // Component Base - var BoxModelBase = { - component: 'baseBoxModel', - category: 'boxModel', - properties: baseBoxProps, - Interpolate: { numbers: numbers }, - functions: { onStart: baseBoxOnStart }, - }; - - /* opacityProperty = { - property: 'opacity', - defaultValue: 1, - interpolators: {numbers}, - functions = { prepareStart, prepareProperty, onStart } - } */ - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartOpacity(tweenProp/* , value */) { - // opacity could be 0 sometimes, we need to check regardless - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000; - /* eslint-enable */ - }; - } - } - - // Base Component - var OpacityPropertyBase = { - component: 'baseOpacity', - property: 'opacity', - // defaultValue: 1, - Interpolate: { numbers: numbers }, - functions: { onStart: onStartOpacity }, - }; - - // import {baseCrossBrowserMove} from '../components/crossBrowserMove' - // support for kute-base ends here - - var Components = { - Transform: new AnimationBase(TransformFunctionsBase), - BoxModel: new AnimationBase(BoxModelBase), - Opacity: new AnimationBase(OpacityPropertyBase), - }; - - function queueStart() { - var this$1$1 = this; - - // fire onStart actions - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - onStart[obj].call(this$1$1, obj); // easing functions - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - onStart[obj][prop].call(this$1$1, prop); - }); - } - }); - - // add interpolations - linkInterpolation.call(this); - } - - /** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ - var TweenBase = function TweenBase(targetElement, startObject, endObject, opsObject) { - var this$1$1 = this; - - // element animation is applied to - this.element = targetElement; - - /** @type {boolean} */ - this.playing = false; - /** @type {number?} */ - this._startTime = null; - /** @type {boolean} */ - this._startFired = false; - - // type is set via KUTE.tweenProps - this.valuesEnd = endObject; - this.valuesStart = startObject; - - // OPTIONS - var options = opsObject || {}; - // internal option to process inline/computed style at start instead of init - // used by to() method and expects object : {} / false - this._resetStart = options.resetStart || 0; - // you can only set a core easing function as default - /** @type {KUTE.easingOption} */ - this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing); - /** @type {number} */ - this._duration = options.duration || defaultOptions.duration; // duration option | default - /** @type {number} */ - this._delay = options.delay || defaultOptions.delay; // delay option | default - - // set other options - Object.keys(options).forEach(function (op) { - var internalOption = "_" + op; - if (!(internalOption in this$1$1)) { this$1$1[internalOption] = options[op]; } - }); - - // callbacks should not be set as undefined - // this._onStart = options.onStart - // this._onUpdate = options.onUpdate - // this._onStop = options.onStop - // this._onComplete = options.onComplete - - // queue the easing - var easingFnName = this._easing.name; - if (!onStart[easingFnName]) { - onStart[easingFnName] = function easingFn(prop) { - if (!KEC[prop] && prop === this._easing.name) { KEC[prop] = this._easing; } - }; - } - - return this; - }; - - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.start = function start (time) { - // now it's a good time to start - add(this); - this.playing = true; - - this._startTime = typeof time !== 'undefined' ? time : KEC.Time(); - this._startTime += this._delay; - - if (!this._startFired) { - if (this._onStart) { - this._onStart.call(this); - } - - queueStart.call(this); - - this._startFired = true; - } - - if (!Tick) { Ticker(); } - return this; - }; - - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - TweenBase.prototype.stop = function stop () { - if (this.playing) { - remove(this); - this.playing = false; - - if (this._onStop) { - this._onStop.call(this); - } - this.close(); - } - return this; - }; - - /** - * Trigger internal completion callbacks. - */ - TweenBase.prototype.close = function close () { - var this$1$1 = this; - - // scroll|transformMatrix need this - Object.keys(onComplete).forEach(function (component) { - Object.keys(onComplete[component]).forEach(function (toClose) { - onComplete[component][toClose].call(this$1$1, toClose); - }); - }); - // when all animations are finished, stop ticking after ~3 frames - this._startFired = false; - stop.call(this); - }; - - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.chain = function chain (args) { - this._chain = []; - this._chain = args.length ? args : this._chain.concat(args); - return this; - }; - - /** - * Stop tweening the chained tween instances. - */ - TweenBase.prototype.stopChainedTweens = function stopChainedTweens () { - if (this._chain && this._chain.length) { this._chain.forEach(function (tw) { return tw.stop(); }); } - }; - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - TweenBase.prototype.update = function update (time) { - var this$1$1 = this; - - var T = time !== undefined ? time : KEC.Time(); - - var elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - var progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach(function (tweenProp) { - KEC[tweenProp](this$1$1.element, - this$1$1.valuesStart[tweenProp], - this$1$1.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.map(function (tw) { return tw.start(); }); - } - - return false; - } - - return true; - }; - - // Update Tween Interface - connect.tween = TweenBase; - - var TweenConstructor = connect.tween; - - /** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - function fromTo(element, startObject, endObject, optionsObj) { - var options = optionsObj || {}; - return new TweenConstructor(selector(element), startObject, endObject, options); - } - - var version = "2.2.3"; - - // @ts-ignore - - /** - * A global namespace for library version. - * @type {string} - */ - var Version = version; - - var indexBase = { - Animation: AnimationBase, - Components: Components, - - Tween: TweenBase, - fromTo: fromTo, - - Objects: Objects, - Easing: Easing, - Util: Util, - Render: Render, - Interpolate: interpolate, - Internals: internals, - Selector: selector, - Version: Version, - }; - - return indexBase; - -})); diff --git a/demo/src/kute-base.min.js b/demo/src/kute-base.min.js deleted file mode 100644 index 3eee4ab..0000000 --- a/demo/src/kute-base.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// KUTE.js Base v2.2.3 | thednp © 2021 | MIT-License -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=e()}(this,(function(){"use strict";var t={},e=[],n="undefined"!=typeof global?global:"undefined"!=typeof window?window.self:{},i={},o={},r="undefined"==typeof self&&"undefined"!=typeof process&&process.hrtime?function(){var t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:"undefined"!=typeof self&&void 0!==self.performance&&void 0!==self.performance.now?self.performance.now.bind(self.performance):"undefined"!=typeof Date&&Date.now?Date.now:function(){return(new Date).getTime()},a={};a.now=r;var s=0,c=function(t){for(var n=0;n>0)/1e3+n+")"}function T(t,e,n,i){for(var o=[],r=0;r<3;r+=1)o[r]=(t[r]||e[r]?(1e3*(t[r]+(e[r]-t[r])*i)>>0)/1e3:0)+n;return"translate3d("+o.join(",")+")"}function I(t,e,n,i){var o="";return o+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*i)>>0)/1e3+n+")":"",o+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*i)>>0)/1e3+n+")":"",o+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*i)>>0)/1e3+n+")":""}function S(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function C(t,e,n,i){var o=[];return o[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*i)>>0)/1e3)+n,o[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*i)>>0)/1e3)+n:"0","skew("+o.join(",")+")"}var x={component:"baseTransform",property:"transform",functions:{onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,n,i,o){t.style[e]=(n.perspective||i.perspective?w(n.perspective,i.perspective,"px",o):"")+(n.translate3d?T(n.translate3d,i.translate3d,"px",o):"")+(n.rotate3d?I(n.rotate3d,i.rotate3d,"deg",o):"")+(n.skew?C(n.skew,i.skew,"deg",o):"")+(n.scale||i.scale?S(n.scale,i.scale,o):"")})}},Interpolate:{perspective:w,translate3d:T,rotate3d:I,translate:function(t,e,n,i){var o=[];return o[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*i)>>0)/1e3)+n,o[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*i)>>0)/1e3)+n:"0","translate("+o.join(",")+")"},rotate:function(t,e,n,i){return"rotate("+(1e3*(t+(e-t)*i)>>0)/1e3+n+")"},scale:S,skew:C}};function U(t,e,n){return+t+(e-t)*n}function M(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,i,o){t.style[e]=(o>.99||o<.01?(10*U(n,i,o)>>0)/10:U(n,i,o)>>0)+"px"})}var q=["top","left","width","height"],A={};q.forEach((function(t){A[t]=M}));var F={component:"baseBoxModel",category:"boxModel",properties:q,Interpolate:{numbers:U},functions:{onStart:A}};var B={component:"baseOpacity",property:"opacity",Interpolate:{numbers:U},functions:{onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,i,o){t.style[e]=(1e3*U(n,i,o)>>0)/1e3})}}},D={Transform:new j(x),BoxModel:new j(F),Opacity:new j(B)};function K(){var t=this;Object.keys(o).forEach((function(e){"function"==typeof o[e]?o[e].call(t,e):Object.keys(o[e]).forEach((function(n){o[e][n].call(t,n)}))})),_.call(this)}var Q=function(e,n,i,r){var a=this;this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=i,this.valuesStart=n;var s=r||{};this._resetStart=s.resetStart||0,this._easing="function"==typeof s.easing?s.easing:v.processEasing(s.easing),this._duration=s.duration||l.duration,this._delay=s.delay||l.delay,Object.keys(s).forEach((function(t){var e="_"+t;e in a||(a[e]=s[t])}));var c=this._easing.name;return o[c]||(o[c]=function(e){t[e]||e!==this._easing.name||(t[e]=this._easing)}),this};Q.prototype.start=function(e){return g(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),K.call(this),this._startFired=!0),s||c(),this},Q.prototype.stop=function(){return this.playing&&(E(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},Q.prototype.close=function(){var t=this;Object.keys(p).forEach((function(e){Object.keys(p[e]).forEach((function(n){p[e][n].call(t,n)}))})),this._startFired=!1,u.call(this)},Q.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},Q.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.forEach((function(t){return t.stop()}))},Q.prototype.update=function(e){var n,i=this,o=void 0!==e?e:t.Time();if(o1?1:n;var r=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(e){t[e](i.element,i.valuesStart[e],i.valuesEnd[e],r)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.map((function(t){return t.start()})),!1)},v.tween=Q;var L=v.tween;return{Animation:j,Components:D,Tween:Q,fromTo:function(t,e,n,i){var o=i||{};return new L(k(t),e,n,o)},Objects:d,Easing:m,Util:y,Render:f,Interpolate:i,Internals:O,Selector:k,Version:"2.2.3"}})); diff --git a/demo/src/kute-extra.js b/demo/src/kute-extra.js deleted file mode 100644 index b557f0a..0000000 --- a/demo/src/kute-extra.js +++ /dev/null @@ -1,5731 +0,0 @@ -/*! -* KUTE.js Extra v2.2.3 (http://thednp.github.io/kute.js) -* Copyright 2015-2021 © thednp -* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) -*/ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); -})(this, (function () { 'use strict'; - - /** - * Creates cubic-bezier easing functions. - * - * @class - */ - var CubicBezier = function CubicBezier(p1x, p1y, p2x, p2y, functionName) { - var this$1$1 = this; - - // pre-calculate the polynomial coefficients - // First and last control points are implied to be (0,0) and (1.0, 1.0) - - /** @type {number} */ - this.cx = 3.0 * p1x; - - /** @type {number} */ - this.bx = 3.0 * (p2x - p1x) - this.cx; - - /** @type {number} */ - this.ax = 1.0 - this.cx - this.bx; - - /** @type {number} */ - this.cy = 3.0 * p1y; - - /** @type {number} */ - this.by = 3.0 * (p2y - p1y) - this.cy; - - /** @type {number} */ - this.ay = 1.0 - this.cy - this.by; - - /** @type {(t: number) => number} */ - var BezierEasing = function (t) { return this$1$1.sampleCurveY(this$1$1.solveCurveX(t)); }; - - // this function needs a name - Object.defineProperty(BezierEasing, 'name', { writable: true }); - BezierEasing.name = functionName || ("cubic-bezier(" + ([p1x, p1y, p2x, p2y]) + ")"); - - return BezierEasing; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled X value - */ - CubicBezier.prototype.sampleCurveX = function sampleCurveX (t) { - return ((this.ax * t + this.bx) * t + this.cx) * t; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled Y value - */ - CubicBezier.prototype.sampleCurveY = function sampleCurveY (t) { - return ((this.ay * t + this.by) * t + this.cy) * t; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled curve derivative X value - */ - CubicBezier.prototype.sampleCurveDerivativeX = function sampleCurveDerivativeX (t) { - return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx; - }; - - /** - * @param {number} x - progress [0-1] - * @return {number} - solved curve X value - */ - CubicBezier.prototype.solveCurveX = function solveCurveX (x) { - var t0; - var t1; - var t2; - var x2; - var d2; - var i; - var epsilon = 1e-5; // Precision - - // First try a few iterations of Newton's method -- normally very fast. - for (t2 = x, i = 0; i < 32; i += 1) { - x2 = this.sampleCurveX(t2) - x; - if (Math.abs(x2) < epsilon) { return t2; } - d2 = this.sampleCurveDerivativeX(t2); - if (Math.abs(d2) < epsilon) { break; } - t2 -= x2 / d2; - } - - // No solution found - use bi-section - t0 = 0.0; - t1 = 1.0; - t2 = x; - - if (t2 < t0) { return t0; } - if (t2 > t1) { return t1; } - - while (t0 < t1) { - x2 = this.sampleCurveX(t2); - if (Math.abs(x2 - x) < epsilon) { return t2; } - if (x > x2) { t0 = t2; } - else { t1 = t2; } - - t2 = (t1 - t0) * 0.5 + t0; - } - - // Give up - return t2; - }; - - var version$1 = "1.0.18"; - - // @ts-ignore - - /** - * A global namespace for library version. - * @type {string} - */ - var Version$1 = version$1; - - Object.assign(CubicBezier, { Version: Version$1 }); - - /** - * The KUTE.js Execution Context - */ - var KEC = {}; - - var Tweens = []; - - var gl0bal; - - if (typeof global !== 'undefined') { gl0bal = global; } - else if (typeof window !== 'undefined') { gl0bal = window.self; } - else { gl0bal = {}; } - - var globalObject = gl0bal; - - // KUTE.js INTERPOLATE FUNCTIONS - // ============================= - var interpolate = {}; - - // schedule property specific function on animation start - // link property update function to KUTE.js execution context - var onStart = {}; - - // Include a performance.now polyfill. - // source https://github.com/tweenjs/tween.js/blob/master/src/Now.ts - var performanceNow; - - // In node.js, use process.hrtime. - // eslint-disable-next-line - // @ts-ignore - if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { - performanceNow = function () { - // eslint-disable-next-line - // @ts-ignore - var time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; - } else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { - // In a browser, use self.performance.now if it is available. - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - performanceNow = self.performance.now.bind(self.performance); - } else if (typeof Date !== 'undefined' && Date.now) { - // Use Date.now if it is available. - performanceNow = Date.now; - } else { - // Otherwise, use 'new Date().getTime()'. - performanceNow = function () { return new Date().getTime(); }; - } - - var now = performanceNow; - - var Time = {}; - Time.now = now; - - // eslint-disable-next-line import/no-mutable-exports -- impossible to satisfy - var Tick = 0; - - /** - * - * @param {number | Date} time - */ - var Ticker = function (time) { - var i = 0; - while (i < Tweens.length) { - if (Tweens[i].update(time)) { - i += 1; - } else { - Tweens.splice(i, 1); - } - } - Tick = requestAnimationFrame(Ticker); - }; - - // stop requesting animation frame - function stop() { - setTimeout(function () { // re-added for #81 - if (!Tweens.length && Tick) { - cancelAnimationFrame(Tick); - Tick = null; - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - if (KEC[obj]) { delete KEC[obj]; } - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - if (KEC[prop]) { delete KEC[prop]; } - }); - } - }); - - Object.keys(interpolate).forEach(function (i) { - if (KEC[i]) { delete KEC[i]; } - }); - } - }, 64); - } - - // render update functions - // ======================= - var Render = { - Tick: Tick, Ticker: Ticker, Tweens: Tweens, Time: Time, - }; - Object.keys(Render).forEach(function (blob) { - if (!KEC[blob]) { - KEC[blob] = blob === 'Time' ? Time.now : Render[blob]; - } - }); - - globalObject._KUTE = KEC; - - // all supported properties - var supportedProperties = {}; - - var defaultValues = {}; - - var defaultOptions$1 = { - duration: 700, - delay: 0, - easing: 'linear', - repeat: 0, - repeatDelay: 0, - yoyo: false, - resetStart: false, - offset: 0, - }; - - // used in preparePropertiesObject - var prepareProperty = {}; - - // check current property value when .to() method is used - var prepareStart = {}; - - // checks for differences between the processed start and end values, - // can be set to make sure start unit and end unit are same, - // stack transforms, process SVG paths, - // any type of post processing the component needs - var crossCheck = {}; - - // schedule property specific function on animation complete - var onComplete = {}; - - // link properties to interpolate functions - var linkProperty = {}; - - var Objects = { - supportedProperties: supportedProperties, - defaultValues: defaultValues, - defaultOptions: defaultOptions$1, - prepareProperty: prepareProperty, - prepareStart: prepareStart, - crossCheck: crossCheck, - onStart: onStart, - onComplete: onComplete, - linkProperty: linkProperty, - }; - - // util - a general object for utils like rgbToHex, processEasing - var Util = {}; - - /** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var add = function (tw) { return Tweens.push(tw); }; - - /** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var remove = function (tw) { - var i = Tweens.indexOf(tw); - if (i !== -1) { Tweens.splice(i, 1); } - }; - - /** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ - var getAll = function () { return Tweens; }; - - /** - * KUTE.removeAll() - */ - var removeAll = function () { Tweens.length = 0; }; - - /** - * linkInterpolation - * @this {KUTE.Tween} - */ - function linkInterpolation() { - var this$1$1 = this; - // DON'T change - Object.keys(linkProperty).forEach(function (component) { - var componentLink = linkProperty[component]; - var componentProps = supportedProperties[component]; - - Object.keys(componentLink).forEach(function (fnObj) { - if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius - && Object.keys(this$1$1.valuesEnd).some(function (i) { return (componentProps && componentProps.includes(i)) - || (i === 'attr' && Object.keys(this$1$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); })); })) { - if (!KEC[fnObj]) { KEC[fnObj] = componentLink[fnObj]; } - } else { - Object.keys(this$1$1.valuesEnd).forEach(function (prop) { - var propObject = this$1$1.valuesEnd[prop]; - if (propObject instanceof Object) { - Object.keys(propObject).forEach(function (i) { - if (typeof (componentLink[i]) === 'function') { // transformCSS3 - if (!KEC[i]) { KEC[i] = componentLink[i]; } - } else { - Object.keys(componentLink[fnObj]).forEach(function (j) { - if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix - if (!KEC[j]) { KEC[j] = componentLink[i][j]; } - } - }); - } - }); - } - }); - } - }); - }); - } - - var internals = { - add: add, - remove: remove, - getAll: getAll, - removeAll: removeAll, - stop: stop, - linkInterpolation: linkInterpolation, - }; - - /** - * getInlineStyle - * Returns the transform style for element from - * cssText. Used by for the `.to()` static method. - * - * @param {Element} el target element - * @returns {object} - */ - function getInlineStyle(el) { - // if the scroll applies to `window` it returns as it has no styling - if (!el.style) { return false; } - // the cssText | the resulting transform object - var css = el.style.cssText.replace(/\s/g, '').split(';'); - var transformObject = {}; - var arrayFn = ['translate3d', 'translate', 'scale3d', 'skew']; - - css.forEach(function (cs) { - if (/transform/i.test(cs)) { - // all transform properties - var tps = cs.split(':')[1].split(')'); - tps.forEach(function (tpi) { - var tpv = tpi.split('('); - var tp = tpv[0]; - // each transform property - var tv = tpv[1]; - if (!/matrix/.test(tp)) { - transformObject[tp] = arrayFn.includes(tp) ? tv.split(',') : tv; - } - }); - } - }); - - return transformObject; - } - - /** - * getStyleForProperty - * - * Returns the computed style property for element for .to() method. - * Used by for the `.to()` static method. - * - * @param {Element} elem - * @param {string} propertyName - * @returns {string} - */ - function getStyleForProperty(elem, propertyName) { - var result = defaultValues[propertyName]; - var styleAttribute = elem.style; - var computedStyle = getComputedStyle(elem) || elem.currentStyle; - var styleValue = styleAttribute[propertyName] && !/auto|initial|none|unset/.test(styleAttribute[propertyName]) - ? styleAttribute[propertyName] - : computedStyle[propertyName]; - - if (propertyName !== 'transform' && (propertyName in computedStyle || propertyName in styleAttribute)) { - result = styleValue; - } - - return result; - } - - /** - * prepareObject - * - * Returns all processed valuesStart / valuesEnd. - * - * @param {Element} obj the values start/end object - * @param {string} fn toggles between the two - */ - function prepareObject(obj, fn) { - var this$1$1 = this; - // this, props object, type: start/end - var propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd; - - Object.keys(prepareProperty).forEach(function (component) { - var prepareComponent = prepareProperty[component]; - var supportComponent = supportedProperties[component]; - - Object.keys(prepareComponent).forEach(function (tweenCategory) { - var transformObject = {}; - - Object.keys(obj).forEach(function (tweenProp) { - // scroll, opacity, other components - if (defaultValues[tweenProp] && prepareComponent[tweenProp]) { - propertiesObject[tweenProp] = prepareComponent[tweenProp] - .call(this$1$1, tweenProp, obj[tweenProp]); - - // transform - } else if (!defaultValues[tweenCategory] && tweenCategory === 'transform' - && supportComponent.includes(tweenProp)) { - transformObject[tweenProp] = obj[tweenProp]; - - // allow transformFunctions to work with preprocessed input values - } else if (!defaultValues[tweenProp] && tweenProp === 'transform') { - propertiesObject[tweenProp] = obj[tweenProp]; - - // colors, boxModel, category - } else if (!defaultValues[tweenCategory] - && supportComponent && supportComponent.includes(tweenProp)) { - propertiesObject[tweenProp] = prepareComponent[tweenCategory] - .call(this$1$1, tweenProp, obj[tweenProp]); - } - }); - - // we filter out older browsers by checking Object.keys - if (Object.keys(transformObject).length) { - propertiesObject[tweenCategory] = prepareComponent[tweenCategory] - .call(this$1$1, tweenCategory, transformObject); - } - }); - }); - } - - /** - * getStartValues - * - * Returns the start values for to() method. - * Used by for the `.to()` static method. - * - * @this {KUTE.Tween} the tween instance - */ - function getStartValues() { - var this$1$1 = this; - - var startValues = {}; - var currentStyle = getInlineStyle(this.element); - - Object.keys(this.valuesStart).forEach(function (tweenProp) { - Object.keys(prepareStart).forEach(function (component) { - var componentStart = prepareStart[component]; - - Object.keys(componentStart).forEach(function (tweenCategory) { - // clip, opacity, scroll - if (tweenCategory === tweenProp && componentStart[tweenProp]) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this$1$1, tweenProp, this$1$1.valuesStart[tweenProp]); - // find in an array of properties - } else if (supportedProperties[component] - && supportedProperties[component].includes(tweenProp)) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this$1$1, tweenProp, this$1$1.valuesStart[tweenProp]); - } - }); - }); - }); - - // stack transformCSS props for .to() chains - // also add to startValues values from previous tweens - Object.keys(currentStyle).forEach(function (current) { - if (!(current in this$1$1.valuesStart)) { - startValues[current] = currentStyle[current] || defaultValues[current]; - } - }); - - this.valuesStart = {}; - prepareObject.call(this, startValues, 'start'); - } - - var Process = { - getInlineStyle: getInlineStyle, - getStyleForProperty: getStyleForProperty, - getStartValues: getStartValues, - prepareObject: prepareObject, - }; - - var connect = {}; - /** @type {KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra} */ - connect.tween = null; - connect.processEasing = null; - - var Easing = { - linear: new CubicBezier(0, 0, 1, 1, 'linear'), - easingSinusoidalIn: new CubicBezier(0.47, 0, 0.745, 0.715, 'easingSinusoidalIn'), - easingSinusoidalOut: new CubicBezier(0.39, 0.575, 0.565, 1, 'easingSinusoidalOut'), - easingSinusoidalInOut: new CubicBezier(0.445, 0.05, 0.55, 0.95, 'easingSinusoidalInOut'), - - easingQuadraticIn: new CubicBezier(0.550, 0.085, 0.680, 0.530, 'easingQuadraticIn'), - easingQuadraticOut: new CubicBezier(0.250, 0.460, 0.450, 0.940, 'easingQuadraticOut'), - easingQuadraticInOut: new CubicBezier(0.455, 0.030, 0.515, 0.955, 'easingQuadraticInOut'), - - easingCubicIn: new CubicBezier(0.55, 0.055, 0.675, 0.19, 'easingCubicIn'), - easingCubicOut: new CubicBezier(0.215, 0.61, 0.355, 1, 'easingCubicOut'), - easingCubicInOut: new CubicBezier(0.645, 0.045, 0.355, 1, 'easingCubicInOut'), - - easingQuarticIn: new CubicBezier(0.895, 0.03, 0.685, 0.22, 'easingQuarticIn'), - easingQuarticOut: new CubicBezier(0.165, 0.84, 0.44, 1, 'easingQuarticOut'), - easingQuarticInOut: new CubicBezier(0.77, 0, 0.175, 1, 'easingQuarticInOut'), - - easingQuinticIn: new CubicBezier(0.755, 0.05, 0.855, 0.06, 'easingQuinticIn'), - easingQuinticOut: new CubicBezier(0.23, 1, 0.32, 1, 'easingQuinticOut'), - easingQuinticInOut: new CubicBezier(0.86, 0, 0.07, 1, 'easingQuinticInOut'), - - easingExponentialIn: new CubicBezier(0.95, 0.05, 0.795, 0.035, 'easingExponentialIn'), - easingExponentialOut: new CubicBezier(0.19, 1, 0.22, 1, 'easingExponentialOut'), - easingExponentialInOut: new CubicBezier(1, 0, 0, 1, 'easingExponentialInOut'), - - easingCircularIn: new CubicBezier(0.6, 0.04, 0.98, 0.335, 'easingCircularIn'), - easingCircularOut: new CubicBezier(0.075, 0.82, 0.165, 1, 'easingCircularOut'), - easingCircularInOut: new CubicBezier(0.785, 0.135, 0.15, 0.86, 'easingCircularInOut'), - - easingBackIn: new CubicBezier(0.6, -0.28, 0.735, 0.045, 'easingBackIn'), - easingBackOut: new CubicBezier(0.175, 0.885, 0.32, 1.275, 'easingBackOut'), - easingBackInOut: new CubicBezier(0.68, -0.55, 0.265, 1.55, 'easingBackInOut'), - }; - - /** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easingfunction - */ - function processBezierEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof (Easing[fn]) === 'function') { - return Easing[fn]; - } if (/bezier/.test(fn)) { - var bz = fn.replace(/bezier|\s|\(|\)/g, '').split(','); - return new CubicBezier(bz[0] * 1, bz[1] * 1, bz[2] * 1, bz[3] * 1); // bezier easing - } - // if (/elastic|bounce/i.test(fn)) { - // throw TypeError(`KUTE - CubicBezier doesn't support ${fn} easing.`); - // } - return Easing.linear; - } - - connect.processEasing = processBezierEasing; - - /** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ - function selector(el, multi) { - try { - var requestedElem; - var itemsArray; - if (multi) { - itemsArray = el instanceof Array && el.every(function (x) { return x instanceof Element; }); - requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray - ? el : document.querySelectorAll(el); - } else { - requestedElem = el instanceof Element || el === window // scroll - ? el : document.querySelector(el); - } - return requestedElem; - } catch (e) { - throw TypeError(("KUTE.js - Element(s) not found: " + el + ".")); - } - } - - function queueStart() { - var this$1$1 = this; - - // fire onStart actions - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - onStart[obj].call(this$1$1, obj); // easing functions - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - onStart[obj][prop].call(this$1$1, prop); - }); - } - }); - - // add interpolations - linkInterpolation.call(this); - } - - /** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ - var TweenBase = function TweenBase(targetElement, startObject, endObject, opsObject) { - var this$1$1 = this; - - // element animation is applied to - this.element = targetElement; - - /** @type {boolean} */ - this.playing = false; - /** @type {number?} */ - this._startTime = null; - /** @type {boolean} */ - this._startFired = false; - - // type is set via KUTE.tweenProps - this.valuesEnd = endObject; - this.valuesStart = startObject; - - // OPTIONS - var options = opsObject || {}; - // internal option to process inline/computed style at start instead of init - // used by to() method and expects object : {} / false - this._resetStart = options.resetStart || 0; - // you can only set a core easing function as default - /** @type {KUTE.easingOption} */ - this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing); - /** @type {number} */ - this._duration = options.duration || defaultOptions$1.duration; // duration option | default - /** @type {number} */ - this._delay = options.delay || defaultOptions$1.delay; // delay option | default - - // set other options - Object.keys(options).forEach(function (op) { - var internalOption = "_" + op; - if (!(internalOption in this$1$1)) { this$1$1[internalOption] = options[op]; } - }); - - // callbacks should not be set as undefined - // this._onStart = options.onStart - // this._onUpdate = options.onUpdate - // this._onStop = options.onStop - // this._onComplete = options.onComplete - - // queue the easing - var easingFnName = this._easing.name; - if (!onStart[easingFnName]) { - onStart[easingFnName] = function easingFn(prop) { - if (!KEC[prop] && prop === this._easing.name) { KEC[prop] = this._easing; } - }; - } - - return this; - }; - - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.start = function start (time) { - // now it's a good time to start - add(this); - this.playing = true; - - this._startTime = typeof time !== 'undefined' ? time : KEC.Time(); - this._startTime += this._delay; - - if (!this._startFired) { - if (this._onStart) { - this._onStart.call(this); - } - - queueStart.call(this); - - this._startFired = true; - } - - if (!Tick) { Ticker(); } - return this; - }; - - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - TweenBase.prototype.stop = function stop () { - if (this.playing) { - remove(this); - this.playing = false; - - if (this._onStop) { - this._onStop.call(this); - } - this.close(); - } - return this; - }; - - /** - * Trigger internal completion callbacks. - */ - TweenBase.prototype.close = function close () { - var this$1$1 = this; - - // scroll|transformMatrix need this - Object.keys(onComplete).forEach(function (component) { - Object.keys(onComplete[component]).forEach(function (toClose) { - onComplete[component][toClose].call(this$1$1, toClose); - }); - }); - // when all animations are finished, stop ticking after ~3 frames - this._startFired = false; - stop.call(this); - }; - - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.chain = function chain (args) { - this._chain = []; - this._chain = args.length ? args : this._chain.concat(args); - return this; - }; - - /** - * Stop tweening the chained tween instances. - */ - TweenBase.prototype.stopChainedTweens = function stopChainedTweens () { - if (this._chain && this._chain.length) { this._chain.forEach(function (tw) { return tw.stop(); }); } - }; - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - TweenBase.prototype.update = function update (time) { - var this$1$1 = this; - - var T = time !== undefined ? time : KEC.Time(); - - var elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - var progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach(function (tweenProp) { - KEC[tweenProp](this$1$1.element, - this$1$1.valuesStart[tweenProp], - this$1$1.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.map(function (tw) { return tw.start(); }); - } - - return false; - } - - return true; - }; - - // Update Tween Interface - connect.tween = TweenBase; - - /** - * The `KUTE.Tween()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor adds additional functionality and is the default - * Tween object constructor in KUTE.js. - */ - var Tween = /*@__PURE__*/(function (TweenBase) { - function Tween() { - var this$1$1 = this; - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - TweenBase.apply(this, args); // this calls the constructor of TweenBase - - // reset interpolation values - this.valuesStart = {}; - this.valuesEnd = {}; - - // const startObject = args[1]; - // const endObject = args[2]; - var ref = args.slice(1); - var startObject = ref[0]; - var endObject = ref[1]; - var options = ref[2]; - - // set valuesEnd - prepareObject.call(this, endObject, 'end'); - - // set valuesStart - if (this._resetStart) { - this.valuesStart = startObject; - } else { - prepareObject.call(this, startObject, 'start'); - } - - // ready for crossCheck - if (!this._resetStart) { - Object.keys(crossCheck).forEach(function (component) { - Object.keys(crossCheck[component]).forEach(function (checkProp) { - crossCheck[component][checkProp].call(this$1$1, checkProp); - }); - }); - } - - // set paused state - /** @type {boolean} */ - this.paused = false; - /** @type {number?} */ - this._pauseTime = null; - - // additional properties and options - /** @type {number?} */ - this._repeat = options.repeat || defaultOptions$1.repeat; - /** @type {number?} */ - this._repeatDelay = options.repeatDelay || defaultOptions$1.repeatDelay; - // we cache the number of repeats to be able to put it back after all cycles finish - /** @type {number?} */ - this._repeatOption = this._repeat; - - // yoyo needs at least repeat: 1 - /** @type {KUTE.tweenProps} */ - this.valuesRepeat = {}; // valuesRepeat - /** @type {boolean} */ - this._yoyo = options.yoyo || defaultOptions$1.yoyo; - /** @type {boolean} */ - this._reversed = false; - - // don't load extra callbacks - // this._onPause = options.onPause || defaultOptions.onPause - // this._onResume = options.onResume || defaultOptions.onResume - - // chained Tweens - // this._chain = options.chain || defaultOptions.chain; - return this; - } - - if ( TweenBase ) Tween.__proto__ = TweenBase; - Tween.prototype = Object.create( TweenBase && TweenBase.prototype ); - Tween.prototype.constructor = Tween; - - /** - * Starts tweening, extended method - * @param {number?} time the tween start time - * @returns {Tween} this instance - */ - Tween.prototype.start = function start (time) { - var this$1$1 = this; - - // on start we reprocess the valuesStart for TO() method - if (this._resetStart) { - this.valuesStart = this._resetStart; - getStartValues.call(this); - - // this is where we do the valuesStart and valuesEnd check for fromTo() method - Object.keys(crossCheck).forEach(function (component) { - Object.keys(crossCheck[component]).forEach(function (checkProp) { - crossCheck[component][checkProp].call(this$1$1, checkProp); - }); - }); - } - // still not paused - this.paused = false; - - // set yoyo values - if (this._yoyo) { - Object.keys(this.valuesEnd).forEach(function (endProp) { - this$1$1.valuesRepeat[endProp] = this$1$1.valuesStart[endProp]; - }); - } - - TweenBase.prototype.start.call(this, time); - - return this; - }; - - /** - * Stops tweening, extended method - * @returns {Tween} this instance - */ - Tween.prototype.stop = function stop () { - TweenBase.prototype.stop.call(this); - if (!this.paused && this.playing) { - this.paused = false; - this.stopChainedTweens(); - } - return this; - }; - - /** - * Trigger internal completion callbacks. - */ - Tween.prototype.close = function close () { - TweenBase.prototype.close.call(this); - - if (this._repeatOption > 0) { - this._repeat = this._repeatOption; - } - if (this._yoyo && this._reversed === true) { - this.reverse(); - this._reversed = false; - } - - return this; - }; - - /** - * Resume tweening - * @returns {Tween} this instance - */ - Tween.prototype.resume = function resume () { - if (this.paused && this.playing) { - this.paused = false; - if (this._onResume !== undefined) { - this._onResume.call(this); - } - // re-queue execution context - queueStart.call(this); - // update time and let it roll - this._startTime += KEC.Time() - this._pauseTime; - add(this); - // restart ticker if stopped - if (!Tick) { Ticker(); } - } - return this; - }; - - /** - * Pause tweening - * @returns {Tween} this instance - */ - Tween.prototype.pause = function pause () { - if (!this.paused && this.playing) { - remove(this); - this.paused = true; - this._pauseTime = KEC.Time(); - if (this._onPause !== undefined) { - this._onPause.call(this); - } - } - return this; - }; - - /** - * Reverses start values with end values - */ - Tween.prototype.reverse = function reverse () { - var this$1$1 = this; - - Object.keys(this.valuesEnd).forEach(function (reverseProp) { - var tmp = this$1$1.valuesRepeat[reverseProp]; - this$1$1.valuesRepeat[reverseProp] = this$1$1.valuesEnd[reverseProp]; - this$1$1.valuesEnd[reverseProp] = tmp; - this$1$1.valuesStart[reverseProp] = this$1$1.valuesRepeat[reverseProp]; - }); - }; - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - Tween.prototype.update = function update (time) { - var this$1$1 = this; - - var T = time !== undefined ? time : KEC.Time(); - - var elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - var progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach(function (tweenProp) { - KEC[tweenProp](this$1$1.element, - this$1$1.valuesStart[tweenProp], - this$1$1.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - if (this._repeat > 0) { - if (Number.isFinite(this._repeat)) { this._repeat -= 1; } - - // set the right time for delay - this._startTime = T; - if (Number.isFinite(this._repeat) && this._yoyo && !this._reversed) { - this._startTime += this._repeatDelay; - } - - if (this._yoyo) { // handle yoyo - this._reversed = !this._reversed; - this.reverse(); - } - - return true; - } - - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.forEach(function (tw) { return tw.start(); }); - } - - return false; - } - return true; - }; - - return Tween; - }(TweenBase)); - - // Update Tween Interface Update - connect.tween = Tween; - - // to do - // * per property easing - // * per property duration - // * per property callback - // * per property delay/offset - // * new update method to work with the above - // * other cool ideas - - /** - * The `KUTE.TweenExtra()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor is intended for experiments or testing of new features. - */ - var TweenExtra = /*@__PURE__*/(function (Tween) { - function TweenExtra() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Tween.apply(this, args); // import constructor of TweenBase -> Tween - - return this; - } - - if ( Tween ) TweenExtra.__proto__ = Tween; - TweenExtra.prototype = Object.create( Tween && Tween.prototype ); - TweenExtra.prototype.constructor = TweenExtra; - - // additional methods - // set/override property - // to(property, value) { - // TO DO - // this.valuesEnd[property] = value // well that's not all - // } - - // fromTo(property, value) { - // TO DO - // this.valuesEnd[property] = value // well that's not all - // } - - // getTotalDuration() { - // to do - // } - - /** - * Method to add callbacks on the fly. - * @param {string} name callback name - * @param {Function} fn callback function - * @returns {TweenExtra} - */ - TweenExtra.prototype.on = function on (name, fn) { - if (['start', 'stop', 'update', 'complete', 'pause', 'resume'].indexOf(name) > -1) { - this[("_on" + (name.charAt(0).toUpperCase() + name.slice(1)))] = fn; - } - return this; - }; - - /** - * Method to set options on the fly. - * * accepting [repeat,yoyo,delay,repeatDelay,easing] - * - * @param {string} option the tick time - * @param {string | number | number[]} value the tick time - * @returns {TweenExtra} - */ - TweenExtra.prototype.option = function option (option$1, value) { - this[("_" + option$1)] = value; - return this; - }; - - return TweenExtra; - }(Tween)); - - // Tween Interface - connect.tween = TweenExtra; - - /** - * The static method creates a new `Tween` object for each `HTMLElement` - * from and `Array`, `HTMLCollection` or `NodeList`. - */ - var TweenCollection = function TweenCollection(els, vS, vE, Options) { - var this$1$1 = this; - - var TweenConstructor = connect.tween; - /** @type {KUTE.twCollection[]} */ - this.tweens = []; - - var Ops = Options || {}; - /** @type {number?} */ - Ops.delay = Ops.delay || defaultOptions$1.delay; - - // set all options - var options = []; - - Array.from(els).forEach(function (el, i) { - options[i] = Ops || {}; - options[i].delay = i > 0 ? Ops.delay + (Ops.offset || defaultOptions$1.offset) : Ops.delay; - if (el instanceof Element) { - this$1$1.tweens.push(new TweenConstructor(el, vS, vE, options[i])); - } else { - throw Error(("KUTE - " + el + " is not instanceof Element")); - } - }); - - /** @type {number?} */ - this.length = this.tweens.length; - return this; - }; - - /** - * Starts tweening, all targets - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.start = function start (time) { - var T = time === undefined ? KEC.Time() : time; - this.tweens.map(function (tween) { return tween.start(T); }); - return this; - }; - - /** - * Stops tweening, all targets and their chains - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.stop = function stop () { - this.tweens.map(function (tween) { return tween.stop(); }); - return this; - }; - - /** - * Pause tweening, all targets - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.pause = function pause () { - this.tweens.map(function (tween) { return tween.pause(); }); - return this; - }; - - /** - * Resume tweening, all targets - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.resume = function resume () { - this.tweens.map(function (tween) { return tween.resume(); }); - return this; - }; - - /** - * Schedule another tween or collection to start after - * this one is complete. - * @param {number?} args the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.chain = function chain (args) { - var lastTween = this.tweens[this.length - 1]; - if (args instanceof TweenCollection) { - lastTween.chain(args.tweens); - } else if (args instanceof connect.tween) { - lastTween.chain(args); - } else { - throw new TypeError('KUTE.js - invalid chain value'); - } - return this; - }; - - /** - * Check if any tween instance is playing - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.playing = function playing () { - return this.tweens.some(function (tw) { return tw.playing; }); - }; - - /** - * Remove all tweens in the collection - */ - TweenCollection.prototype.removeTweens = function removeTweens () { - this.tweens = []; - }; - - /** - * Returns the maximum animation duration - * @returns {number} this instance - */ - TweenCollection.prototype.getMaxDuration = function getMaxDuration () { - var durations = []; - this.tweens.forEach(function (tw) { - durations.push(tw._duration + tw._delay + tw._repeat * tw._repeatDelay); - }); - return Math.max(durations); - }; - - /** - * ProgressBar - * - * @class - * A progress bar utility for KUTE.js that will connect - * a target ``. with a Tween instance - * allowing it to control the progress of the Tween. - */ - var ProgressBar = function ProgressBar(element, tween) { - var assign; - - this.element = selector(element); - this.element.tween = tween; - this.element.tween.toolbar = this.element; - this.element.toolbar = this; - (assign = this.element.parentNode.getElementsByTagName('OUTPUT'), this.element.output = assign[0]); - - // invalidate - if (!(this.element instanceof HTMLInputElement)) { throw TypeError('Target element is not [HTMLInputElement]'); } - if (this.element.type !== 'range') { throw TypeError('Target element is not a range input'); } - if (!(tween instanceof connect.tween)) { throw TypeError(("tween parameter is not [" + (connect.tween) + "]")); } - - this.element.setAttribute('value', 0); - this.element.setAttribute('min', 0); - this.element.setAttribute('max', 1); - this.element.setAttribute('step', 0.0001); - - this.element.tween._onUpdate = this.updateBar; - - this.element.addEventListener('mousedown', this.downAction, false); - }; - - ProgressBar.prototype.updateBar = function updateBar () { - var tick = 0.0001; - var ref = this.toolbar; - var output = ref.output; - - // let progress = this.paused ? this.toolbar.value - // : (KEC.Time() - this._startTime) / this._duration; - // progress = progress > 1 - tick ? 1 : progress < 0.01 ? 0 : progress; - - var progress; - if (this.paused) { - progress = this.toolbar.value; - } else { - progress = (KEC.Time() - this._startTime) / this._duration; - } - - // progress = progress > 1 - tick ? 1 : progress < 0.01 ? 0 : progress; - if (progress > 1 - tick) { progress = 1; } - if (progress < 0.01) { progress = 0; } - - var value = !this._reversed ? progress : 1 - progress; - this.toolbar.value = value; - // eslint-disable-next-line no-bitwise - if (output) { output.value = ((value * 10000 >> 0) / 100) + "%"; } - }; - - ProgressBar.prototype.toggleEvents = function toggleEvents (action) { - // add passive handler ? - this.element[(action + "EventListener")]('mousemove', this.moveAction, false); - this.element[(action + "EventListener")]('mouseup', this.upAction, false); - }; - - ProgressBar.prototype.updateTween = function updateTween () { - // make sure we never complete the tween - var progress = (!this.tween._reversed ? this.value : 1 - this.value) - * this.tween._duration - 0.0001; - - this.tween._startTime = 0; - this.tween.update(progress); - }; - - ProgressBar.prototype.moveAction = function moveAction () { - this.toolbar.updateTween.call(this); - }; - - ProgressBar.prototype.downAction = function downAction () { - if (!this.tween.playing) { - this.tween.start(); - } - - if (!this.tween.paused) { - this.tween.pause(); - this.toolbar.toggleEvents('add'); - - KEC.Tick = cancelAnimationFrame(KEC.Ticker); - } - }; - - ProgressBar.prototype.upAction = function upAction () { - if (this.tween.paused) { - if (this.tween.paused) { this.tween.resume(); } - - this.tween._startTime = KEC.Time() - - (!this.tween._reversed ? this.value : 1 - this.value) * this.tween._duration; - - this.toolbar.toggleEvents('remove'); - KEC.Tick = requestAnimationFrame(KEC.Ticker); - } - }; - - var TweenConstructor$1 = connect.tween; - - /** - * The `KUTE.to()` static method returns a new Tween object - * for a single `HTMLElement` at its current state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - function to(element, endObject, optionsObj) { - var options = optionsObj || {}; - options.resetStart = endObject; - return new TweenConstructor$1(selector(element), endObject, endObject, options); - } - - var TweenConstructor = connect.tween; - - /** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - function fromTo(element, startObject, endObject, optionsObj) { - var options = optionsObj || {}; - return new TweenConstructor(selector(element), startObject, endObject, options); - } - - /** - * The `KUTE.allTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at their current state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenProps} optionsObj progress - * @returns {TweenCollection} the Tween object collection - */ - function allTo(elements, endObject, optionsObj) { - var options = optionsObj || {}; - options.resetStart = endObject; - return new TweenCollection(selector(elements, true), endObject, endObject, options); - } - - /** - * The `KUTE.allFromTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at a given state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {TweenCollection} the Tween object collection - */ - function allFromTo(elements, startObject, endObject, optionsObj) { - var options = optionsObj || {}; - return new TweenCollection(selector(elements, true), startObject, endObject, options); - } - - /** - * Animation Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - */ - var Animation = function Animation(Component) { - try { - if (Component.component in supportedProperties) { - throw Error(("KUTE - " + (Component.component) + " already registered")); - } else if (Component.property in defaultValues) { - throw Error(("KUTE - " + (Component.property) + " already registered")); - } - } catch (e) { - throw Error(e); - } - - var propertyInfo = this; - var ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - var Functions = { - prepareProperty: prepareProperty, prepareStart: prepareStart, onStart: onStart, onComplete: onComplete, crossCheck: crossCheck, - }; - var Category = Component.category; - var Property = Component.property; - var Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // single property - // {property,defaultvalue,defaultOptions,Interpolate,functions} - - // category colors, boxModel, borderRadius - // {category,properties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg transform, filter - // {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg htmlAttributes - // {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - defaultValues[Property] = Component.defaultValue; - - // minimal info - propertyInfo.supports = Property + " property"; - } else if (Component.defaultValues) { - Object.keys(Component.defaultValues).forEach(function (dv) { - defaultValues[dv] = Component.defaultValues[dv]; - }); - - // minimal info - propertyInfo.supports = (Length || Property) + " " + (Property || Category) + " properties"; - } - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions$1, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach(function (fn) { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; } - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach(function (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 interpolation functions - if (Component.Interpolate) { - Object.keys(Component.Interpolate).forEach(function (fni) { - var compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach(function (sfn) { - if (typeof (compIntObj[sfn]) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach(function (fnu) { - if (!Util[fnu]) { Util[fnu] = Component.Util[fnu]; } - }); - } - - return propertyInfo; - }; - - /** - * Animation Development Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * In addition to the default class, this one provides more component - * information to help you with custom component development. - */ - var AnimationDevelopment = /*@__PURE__*/(function (Animation) { - function AnimationDevelopment(Component) { - Animation.call(this, Component); - - var propertyInfo = this; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - var Functions = { - prepareProperty: prepareProperty, prepareStart: prepareStart, onStart: onStart, onComplete: onComplete, crossCheck: crossCheck, - }; - var Category = Component.category; - var Property = Component.property; - var Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - propertyInfo.supports = Property + " property"; - propertyInfo.defaultValue = "" + ((("" + (Component.defaultValue))).length ? 'YES' : 'not set or incorrect'); - } else if (Component.defaultValues) { - propertyInfo.supports = (Length || Property) + " " + (Property || Category) + " properties"; - propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? 'YES' : 'Not set or incomplete'; - } - - // set additional options - if (Component.defaultOptions) { - propertyInfo.extends = []; - - Object.keys(Component.defaultOptions).forEach(function (op) { - propertyInfo.extends.push(op); - }); - - if (propertyInfo.extends.length) { - propertyInfo.extends = "with <" + (propertyInfo.extends.join(', ')) + "> new option(s)"; - } else { - delete propertyInfo.extends; - } - } - - // set functions - if (Component.functions) { - propertyInfo.interface = []; - propertyInfo.render = []; - propertyInfo.warning = []; - - Object.keys(Functions).forEach(function (fnf) { - if (fnf in Component.functions) { - if (fnf === 'prepareProperty') { propertyInfo.interface.push('fromTo()'); } - if (fnf === 'prepareStart') { propertyInfo.interface.push('to()'); } - if (fnf === 'onStart') { propertyInfo.render = 'can render update'; } - } else { - if (fnf === 'prepareProperty') { propertyInfo.warning.push('fromTo()'); } - if (fnf === 'prepareStart') { propertyInfo.warning.push('to()'); } - if (fnf === 'onStart') { propertyInfo.render = 'no function to render update'; } - } - }); - - if (propertyInfo.interface.length) { - propertyInfo.interface = (Category || Property) + " can use [" + (propertyInfo.interface.join(', ')) + "] method(s)"; - } else { - delete propertyInfo.uses; - } - - if (propertyInfo.warning.length) { - propertyInfo.warning = (Category || Property) + " can't use [" + (propertyInfo.warning.join(', ')) + "] method(s) because values aren't processed"; - } else { - delete propertyInfo.warning; - } - } - - // register Interpolation functions - if (Component.Interpolate) { - propertyInfo.uses = []; - propertyInfo.adds = []; - - Object.keys(Component.Interpolate).forEach(function (fni) { - var compIntObj = Component.Interpolate[fni]; - // register new Interpolation functions - if (typeof (compIntObj) === 'function') { - if (!interpolate[fni]) { - propertyInfo.adds.push(("" + fni)); - } - propertyInfo.uses.push(("" + fni)); - } else { - Object.keys(compIntObj).forEach(function (sfn) { - if (typeof (compIntObj[sfn]) === 'function' && !interpolate[fni]) { - propertyInfo.adds.push(("" + sfn)); - } - propertyInfo.uses.push(("" + sfn)); - }); - } - }); - - if (propertyInfo.uses.length) { - propertyInfo.uses = "[" + (propertyInfo.uses.join(', ')) + "] interpolation function(s)"; - } else { - delete propertyInfo.uses; - } - - if (propertyInfo.adds.length) { - propertyInfo.adds = "new [" + (propertyInfo.adds.join(', ')) + "] interpolation function(s)"; - } else { - delete propertyInfo.adds; - } - } else { - propertyInfo.critical = "For " + (Property || Category) + " no interpolation function[s] is set"; - } - - // set component util - if (Component.Util) { - propertyInfo.hasUtil = Object.keys(Component.Util).join(','); - } - - return propertyInfo; - } - - if ( Animation ) AnimationDevelopment.__proto__ = Animation; - AnimationDevelopment.prototype = Object.create( Animation && Animation.prototype ); - AnimationDevelopment.prototype.constructor = AnimationDevelopment; - - return AnimationDevelopment; - }(Animation)); - - /** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ - function numbers(a, b, v) { - var A = +a; - var B = b - a; - // a = +a; b -= a; - return A + B * v; - } - - /** - * trueDimension - * - * Returns the string value of a specific CSS property converted into a nice - * { v = value, u = unit } object. - * - * @param {string} dimValue the property string value - * @param {boolean | number} isAngle sets the utility to investigate angles - * @returns {{v: number, u: string}} the true {value, unit} tuple - */ - var trueDimension = function (dimValue, isAngle) { - var intValue = parseInt(dimValue, 10) || 0; - var mUnits = ['px', '%', 'deg', 'rad', 'em', 'rem', 'vh', 'vw']; - var theUnit; - - for (var mIndex = 0; mIndex < mUnits.length; mIndex += 1) { - if (typeof dimValue === 'string' && dimValue.includes(mUnits[mIndex])) { - theUnit = mUnits[mIndex]; break; - } - } - if (theUnit === undefined) { - theUnit = isAngle ? 'deg' : 'px'; - } - - return { v: intValue, u: theUnit }; - }; - - // Component Functions - /** - * Sets the property update function. - * @param {string} prop the property name - */ - function onStartBgPos(prop) { - if (this.valuesEnd[prop] && !KEC[prop]) { - KEC[prop] = function (elem, a, b, v) { - /* eslint-disable -- no-bitwise & no-param-reassign impossible to satisfy */ - elem.style[prop] = ((numbers(a[0], b[0], v) * 100 >> 0) / 100) + "% " + (((numbers(a[1], b[1], v) * 100 >> 0) / 100)) + "%"; - /* eslint-enable -- no-bitwise & no-param-reassign impossible to satisfy */ - }; - } - } - - // Component Functions - - /** - * Returns the property computed style. - * @param {string} prop the property - * @returns {string} the property computed style - */ - function getBgPos(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ - function prepareBgPos(/* prop, */_, value) { - if (value instanceof Array) { - var x = trueDimension(value[0]).v; - var y = trueDimension(value[1]).v; - return [!Number.isNaN(x * 1) ? x : 50, !Number.isNaN(y * 1) ? y : 50]; - } - - var 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 - var bgPositionFunctions = { - prepareStart: getBgPos, - prepareProperty: prepareBgPos, - onStart: onStartBgPos, - }; - - // Component Full Object - var BackgroundPosition = { - component: 'backgroundPositionProp', - property: 'backgroundPosition', - defaultValue: [50, 50], - Interpolate: { numbers: numbers }, - functions: bgPositionFunctions, - Util: { trueDimension: trueDimension }, - }; - - /** - * Units Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the interpolated value + unit string - */ - function units(a, b, u, v) { // number1, number2, unit, progress - var A = +a; - var B = b - a; - // a = +a; b -= a; - return (A + B * v) + u; - } - - /* borderRadius = { - category: 'borderRadius', - properties : [..], - defaultValues: {..}, - interpolation: {units} - } */ - - // Component Properties - var radiusProps$1 = [ - 'borderRadius', - 'borderTopLeftRadius', 'borderTopRightRadius', - 'borderBottomLeftRadius', 'borderBottomRightRadius' ]; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function radiusOnStartFn(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = units(a.v, b.v, b.u, v); - }; - } - } - var radiusOnStart$1 = {}; - radiusProps$1.forEach(function (tweenProp) { - radiusOnStart$1[tweenProp] = radiusOnStartFn; - }); - - // Component Properties - var radiusProps = [ - 'borderRadius', - 'borderTopLeftRadius', 'borderTopRightRadius', - 'borderBottomLeftRadius', 'borderBottomRightRadius']; - - var radiusValues = {}; - radiusProps.forEach(function (x) { radiusValues[x] = 0; }); - - // Component Functions - var radiusOnStart = {}; - radiusProps.forEach(function (tweenProp) { - radiusOnStart[tweenProp] = radiusOnStartFn; - }); - - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} the property computed style - */ - function getRadius(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; - } - - /** - * Returns the property tween object. - * @param {string} value the property value - * @returns {{v: number, u: string}} the property tween object - */ - function prepareRadius(/* tweenProp, */_, value) { - return trueDimension(value); - } - - // All Component Functions - var radiusFunctions = { - prepareStart: getRadius, - prepareProperty: prepareRadius, - onStart: radiusOnStart, - }; - - // Full Component - var BorderRadius = { - component: 'borderRadiusProperties', - category: 'borderRadius', - properties: radiusProps, - defaultValues: radiusValues, - Interpolate: { units: units }, - functions: radiusFunctions, - Util: { trueDimension: trueDimension }, - }; - - // Component Functions - /** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - function boxModelOnStart(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - /* eslint-disable no-bitwise -- impossible to satisfy */ - elem.style[tweenProp] = (v > 0.99 || v < 0.01 - ? ((numbers(a, b, v) * 10) >> 0) / 10 - : (numbers(a, b, v)) >> 0) + "px"; - /* eslint-enable no-bitwise */ - /* eslint-enable no-param-reassign */ - }; - } - } - - // Component Base Props - var baseBoxProps = ['top', 'left', 'width', 'height']; - var baseBoxOnStart = {}; - baseBoxProps.forEach(function (x) { baseBoxOnStart[x] = boxModelOnStart; }); - - // Component Properties - var boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', - 'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', - 'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', - 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth']; - - var boxModelValues = {}; - boxModelProperties.forEach(function (x) { boxModelValues[x] = 0; }); - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getBoxModel(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareBoxModel(tweenProp, value) { - var boxValue = trueDimension(value); var - offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; - return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v; - } - var boxPropsOnStart = {}; - boxModelProperties.forEach(function (x) { boxPropsOnStart[x] = boxModelOnStart; }); - - // All Component Functions - var boxModelFunctions = { - prepareStart: getBoxModel, - prepareProperty: prepareBoxModel, - onStart: boxPropsOnStart, - }; - - // Component Full Component - var BoxModel = { - component: 'boxModelProperties', - category: 'boxModel', - properties: boxModelProperties, - defaultValues: boxModelValues, - Interpolate: { numbers: numbers }, - functions: boxModelFunctions, - }; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartClip(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - var h = 0; var - cl = []; - for (h; h < 4; h += 1) { - var c1 = a[h].v; - var c2 = b[h].v; - var cu = b[h].u || 'px'; - // eslint-disable-next-line no-bitwise -- impossible to satisfy - cl[h] = ((numbers(c1, c2, v) * 100 >> 0) / 100) + cu; - } - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.clip = "rect(" + cl + ")"; - }; - } - } - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string | number[]} computed style for property - */ - function getClip(tweenProp/* , value */) { - var ref = this; - var element = ref.element; - var currentClip = getStyleForProperty(element, tweenProp); - var width = getStyleForProperty(element, 'width'); - var height = getStyleForProperty(element, 'height'); - return !/rect/.test(currentClip) ? [0, width, height, 0] : currentClip; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ - function prepareClip(/* tweenProp, */_, value) { - if (value instanceof Array) { - return value.map(function (x) { return trueDimension(x); }); - } - var clipValue = value.replace(/rect|\(|\)/g, ''); - clipValue = /,/g.test(clipValue) ? clipValue.split(',') : clipValue.split(/\s/); - return clipValue.map(function (x) { return trueDimension(x); }); - } - - // All Component Functions - var clipFunctions = { - prepareStart: getClip, - prepareProperty: prepareClip, - onStart: onStartClip, - }; - - // Component Full - var ClipProperty = { - component: 'clipProperty', - property: 'clip', - defaultValue: [0, 0, 0, 0], - Interpolate: { numbers: numbers }, - functions: clipFunctions, - Util: { trueDimension: trueDimension }, - }; - - /** - * hexToRGB - * - * Converts a #HEX color format into RGB - * and returns a color object {r,g,b}. - * - * @param {string} hex the degree angle - * @returns {KUTE.colorObject | null} the radian angle - */ - var hexToRGB = function (hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var hexShorthand = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - var HEX = hex.replace(hexShorthand, function (_, r, g, b) { return r + r + g + g + b + b; }); - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(HEX); - - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), - } : null; - }; - - /** - * trueColor - * - * Transform any color to rgba()/rgb() and return a nice RGB(a) object. - * - * @param {string} colorString the color input - * @returns {KUTE.colorObject} the {r,g,b,a} color object - */ - var trueColor = function (colorString) { - var result; - if (/rgb|rgba/.test(colorString)) { // first check if it's a rgb string - var vrgb = colorString.replace(/\s|\)/, '').split('(')[1].split(','); - var colorAlpha = vrgb[3] ? vrgb[3] : null; - if (!colorAlpha) { - result = { r: parseInt(vrgb[0], 10), g: parseInt(vrgb[1], 10), b: parseInt(vrgb[2], 10) }; - } - result = { - r: parseInt(vrgb[0], 10), - g: parseInt(vrgb[1], 10), - b: parseInt(vrgb[2], 10), - a: parseFloat(colorAlpha), - }; - } if (/^#/.test(colorString)) { - var fromHex = hexToRGB(colorString); - result = { r: fromHex.r, g: fromHex.g, b: fromHex.b }; - } if (/transparent|none|initial|inherit/.test(colorString)) { - result = { - r: 0, g: 0, b: 0, a: 0, - }; - } - // maybe we can check for web safe colors - // only works in a browser - if (!/^#|^rgb/.test(colorString)) { - var siteHead = document.getElementsByTagName('head')[0]; - siteHead.style.color = colorString; - var webColor = getComputedStyle(siteHead, null).color; - webColor = /rgb/.test(webColor) ? webColor.replace(/[^\d,]/g, '').split(',') : [0, 0, 0]; - siteHead.style.color = ''; - result = { - r: parseInt(webColor[0], 10), - g: parseInt(webColor[1], 10), - b: parseInt(webColor[2], 10), - }; - } - return result; - }; - - /** - * Color Interpolation Function. - * - * @param {KUTE.colorObject} a start color - * @param {KUTE.colorObject} b end color - * @param {number} v progress - * @returns {string} the resulting color - */ - function colors(a, b, v) { - var _c = {}; - var ep = ')'; - var cm = ','; - var rgb = 'rgb('; - var rgba = 'rgba('; - - Object.keys(b).forEach(function (c) { - if (c !== 'a') { - _c[c] = numbers(a[c], b[c], v) >> 0 || 0; // eslint-disable-line no-bitwise - } else if (a[c] && b[c]) { - _c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100; // eslint-disable-line no-bitwise - } - }); - - 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; - } - - // Component Interpolation - // rgba1, rgba2, progress - - // Component Properties - // supported formats - // 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) - var supportedColors$1 = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', - 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor' ]; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartColors(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = colors(a, b, v); - }; - } - } - - var colorsOnStart$1 = {}; - supportedColors$1.forEach(function (x) { colorsOnStart$1[x] = onStartColors; }); - - // Component Properties - // supported formats - // 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) - var supportedColors = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor' ]; - - var defaultColors = {}; - supportedColors.forEach(function (tweenProp) { - defaultColors[tweenProp] = '#000'; - }); - - // Component Functions - var colorsOnStart = {}; - supportedColors.forEach(function (x) { - colorsOnStart[x] = onStartColors; - }); - - /** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} property computed style - */ - function getColor(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.colorObject} the property tween object - */ - function prepareColor(/* prop, */_, value) { - return trueColor(value); - } - - // All Component Functions - var colorFunctions = { - prepareStart: getColor, - prepareProperty: prepareColor, - onStart: colorsOnStart, - }; - - // Component Full - var colorProperties = { - component: 'colorProperties', - category: 'colors', - properties: supportedColors, - defaultValues: defaultColors, - Interpolate: { numbers: numbers, colors: colors }, - functions: colorFunctions, - Util: { trueColor: trueColor }, - }; - - // Component Interpolation - /** - * Sets the `drop-shadow` sub-property update function. - * * disimbiguation `dropshadow` interpolation function and `dropShadow` property - * @param {string} tweenProp the property name - */ - function dropshadow(a, b, v) { - var params = []; - var unit = 'px'; - - for (var i = 0; i < 3; i += 1) { - // eslint-disable-next-line no-bitwise - params[i] = ((numbers(a[i], b[i], v) * 100 >> 0) / 100) + unit; - } - return ("drop-shadow(" + (params.concat(colors(a[3], b[3], v)).join(' ')) + ")"); - } - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartFilter(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable-next-line no-param-reassign -- impossible to satisfy */ - elem.style[tweenProp] = (b.url ? ("url(" + (b.url) + ")") : '') - /* eslint-disable no-bitwise -- impossible to satisfy */ - + (a.opacity || b.opacity ? ("opacity(" + (((numbers(a.opacity, b.opacity, v) * 100) >> 0) / 100) + "%)") : '') - + (a.blur || b.blur ? ("blur(" + (((numbers(a.blur, b.blur, v) * 100) >> 0) / 100) + "em)") : '') - + (a.saturate || b.saturate ? ("saturate(" + (((numbers(a.saturate, b.saturate, v) * 100) >> 0) / 100) + "%)") : '') - + (a.invert || b.invert ? ("invert(" + (((numbers(a.invert, b.invert, v) * 100) >> 0) / 100) + "%)") : '') - + (a.grayscale || b.grayscale ? ("grayscale(" + (((numbers(a.grayscale, b.grayscale, v) * 100) >> 0) / 100) + "%)") : '') - + (a.hueRotate || b.hueRotate ? ("hue-rotate(" + (((numbers(a.hueRotate, b.hueRotate, v) * 100) >> 0) / 100) + "deg)") : '') - + (a.sepia || b.sepia ? ("sepia(" + (((numbers(a.sepia, b.sepia, v) * 100) >> 0) / 100) + "%)") : '') - + (a.brightness || b.brightness ? ("brightness(" + (((numbers(a.brightness, b.brightness, v) * 100) >> 0) / 100) + "%)") : '') - + (a.contrast || b.contrast ? ("contrast(" + (((numbers(a.contrast, b.contrast, v) * 100) >> 0) / 100) + "%)") : '') - + (a.dropShadow || b.dropShadow ? dropshadow(a.dropShadow, b.dropShadow, v) : ''); - /* eslint-enable no-bitwise -- impossible to satisfy */ - }; - } - } - - /* filterEffects = { - property: 'filter', - subProperties: {}, - defaultValue: {}, - interpolators: {}, - functions = { prepareStart, prepareProperty, onStart, crossCheck } - } */ - - // Component Util - /** - * Returns camelCase filter sub-property. - * @param {string} str source string - * @returns {string} camelCase property name - */ - function replaceDashNamespace(str) { - return str.replace('-r', 'R').replace('-s', 'S'); - } - - /** - * Returns `drop-shadow` sub-property object. - * @param {(string | number)[]} shadow and `Array` with `drop-shadow` parameters - * @returns {KUTE.filterList['dropShadow']} the expected `drop-shadow` values - */ - function parseDropShadow(shadow) { - var newShadow; - - if (shadow.length === 3) { // [h-shadow, v-shadow, color] - newShadow = [shadow[0], shadow[1], 0, shadow[2]]; - } else if (shadow.length === 4) { // ideal [, , , ] - newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]]; - } - - // make sure the values are ready to tween - for (var i = 0; i < 3; i += 1) { - newShadow[i] = parseFloat(newShadow[i]); - } - // also the color must be a rgb object - newShadow[3] = trueColor(newShadow[3]); - return newShadow; - } - - /** - * Returns an array with current filter sub-properties values. - * @param {string} currentStyle the current filter computed style - * @returns {{[x: string]: number}} the filter tuple - */ - function parseFilterString(currentStyle) { - var result = {}; - var fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g; - var matches = currentStyle.match(fnReg); - var fnArray = currentStyle !== 'none' ? matches : 'none'; - - if (fnArray instanceof Array) { - for (var j = 0, jl = fnArray.length; j < jl; j += 1) { - var p = fnArray[j].trim().split(/\((.+)/); - var pp = replaceDashNamespace(p[0]); - if (pp === 'dropShadow') { - var shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0]; - var params = p[1].replace(shadowColor, '').split(/\s/).map(parseFloat); - result[pp] = params.filter(function (el) { return !Number.isNaN(el); }).concat(shadowColor); - } else { - result[pp] = p[1].replace(/'|"|\)/g, ''); - } - } - } - - return result; - } - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {string} computed style for property - */ - function getFilter(tweenProp, value) { - var currentStyle = getStyleForProperty(this.element, tweenProp); - var filterObject = parseFilterString(currentStyle); - var fnp; - - Object.keys(value).forEach(function (fn) { - fnp = replaceDashNamespace(fn); - if (!filterObject[fnp]) { - filterObject[fnp] = defaultValues[tweenProp][fn]; - } - }); - - return filterObject; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property name - * @returns {KUTE.filterList} the property tween object - */ - function prepareFilter(/* tweenProp, */_, value) { - var filterObject = {}; - var fnp; - - // property: range | default - // opacity: [0-100%] | 100 - // blur: [0-Nem] | 0 - // saturate: [0-N%] | 100 - // invert: [0-100%] | 0 - // grayscale: [0-100%] | 0 - // brightness: [0-N%] | 100 - // contrast: [0-N%] | 100 - // sepia: [0-N%] | 0 - // 'hueRotate': [0-Ndeg] | 0 - // 'dropShadow': [0,0,0,(r:0,g:0,b:0)] | 0 - // url: '' | '' - - Object.keys(value).forEach(function (fn) { - fnp = replaceDashNamespace(fn); - if (/hue/.test(fn)) { - filterObject[fnp] = parseFloat(value[fn]); - } else if (/drop/.test(fn)) { - filterObject[fnp] = parseDropShadow(value[fn]); - } else if (fn === 'url') { - filterObject[fn] = value[fn]; - // } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) { - } else { - filterObject[fn] = parseFloat(value[fn]); - } - }); - - return filterObject; - } - - /** - * Adds missing sub-properties in `valuesEnd` from `valuesStart`. - * @param {string} tweenProp the property name - */ - function crossCheckFilter(tweenProp) { - var this$1$1 = this; - - if (this.valuesEnd[tweenProp]) { - Object.keys(this.valuesStart[tweenProp]).forEach(function (fn) { - if (!this$1$1.valuesEnd[tweenProp][fn]) { - this$1$1.valuesEnd[tweenProp][fn] = this$1$1.valuesStart[tweenProp][fn]; - } - }); - } - } - - // All Component Functions - var filterFunctions = { - prepareStart: getFilter, - prepareProperty: prepareFilter, - onStart: onStartFilter, - crossCheck: crossCheckFilter, - }; - - // Full Component - var filterEffects = { - component: 'filterEffects', - property: 'filter', - // opacity function interfere with opacityProperty - // subProperties: [ - // 'blur', 'brightness','contrast','dropShadow', - // 'hueRotate','grayscale','invert','opacity','saturate','sepia','url' - // ], - defaultValue: { - opacity: 100, - blur: 0, - saturate: 100, - grayscale: 0, - brightness: 100, - contrast: 100, - sepia: 0, - invert: 0, - hueRotate: 0, - dropShadow: [0, 0, 0, { r: 0, g: 0, b: 0 }], - url: '', - }, - Interpolate: { - opacity: numbers, - blur: numbers, - saturate: numbers, - grayscale: numbers, - brightness: numbers, - contrast: numbers, - sepia: numbers, - invert: numbers, - hueRotate: numbers, - dropShadow: { numbers: numbers, colors: colors, dropshadow: dropshadow }, - }, - functions: filterFunctions, - Util: { - parseDropShadow: parseDropShadow, parseFilterString: parseFilterString, replaceDashNamespace: replaceDashNamespace, trueColor: trueColor, - }, - }; - - // Component Special - var attributes = {}; - - var onStartAttr = { - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - attr: function attr(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (elem, vS, vE, v) { - Object.keys(vE).forEach(function (oneAttr) { - KEC.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v); - }); - }; - } - }, - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - attributes: function attributes$1(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd.attr) { - KEC[tweenProp] = attributes; - } - }, - }; - - // Component Name - var ComponentName = 'htmlAttributes'; - - // Component Properties - var svgColors = ['fill', 'stroke', 'stop-color']; - - // Component Util - /** - * Returns non-camelcase property name. - * @param {string} a the camelcase property name - * @returns {string} the non-camelcase property name - */ - function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); } - - // Component Functions - /** - * Returns the current attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {{[x:string]: string}} attribute value - */ - function getAttr(/* tweenProp, */_, value) { - var this$1$1 = this; - - var attrStartValues = {}; - Object.keys(value).forEach(function (attr) { - // get the value for 'fill-opacity' not fillOpacity - // also 'width' not the internal 'width_px' - var attribute = replaceUppercase(attr).replace(/_+[a-z]+/, ''); - var currentValue = this$1$1.element.getAttribute(attribute); - attrStartValues[attribute] = svgColors.includes(attribute) - ? (currentValue || 'rgba(0,0,0,0)') - : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); - }); - - return attrStartValues; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} attrObj the property value - * @returns {number} the property tween object - */ - function prepareAttr(tweenProp, attrObj) { - var this$1$1 = this; - // attr (string),attrObj (object) - var attributesObject = {}; - - Object.keys(attrObj).forEach(function (p) { - var prop = replaceUppercase(p); - var regex = /(%|[a-z]+)$/; - var currentValue = this$1$1.element.getAttribute(prop.replace(/_+[a-z]+/, '')); - - if (!svgColors.includes(prop)) { - // attributes set with unit suffixes - if (currentValue !== null && regex.test(currentValue)) { - var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - var suffix = /%/.test(unit) ? '_percent' : ("_" + unit); - - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop + suffix] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - var _p = oneAttr.replace(suffix, ''); - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - 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] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000); - }; - } - }; - attributesObject[prop] = parseFloat(attrObj[p]); - } - } else { // colors - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - elem.setAttribute(oneAttr, colors(a, b, v)); - }; - } - }; - attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; - } - }); - - return attributesObject; - } - - // All Component Functions - var attrFunctions = { - prepareStart: getAttr, - prepareProperty: prepareAttr, - onStart: onStartAttr, - }; - - // Component Full - var htmlAttributes = { - component: ComponentName, - property: 'attr', - // the Animation class will need some values to validate this Object attribute - subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'], - defaultValue: { - fill: 'rgb(0,0,0)', - stroke: 'rgb(0,0,0)', - 'stop-color': 'rgb(0,0,0)', - opacity: 1, - 'stroke-opacity': 1, - 'fill-opacity': 1, // same here - }, - Interpolate: { numbers: numbers, colors: colors }, - functions: attrFunctions, - // export to global for faster execution - Util: { replaceUppercase: replaceUppercase, trueColor: trueColor, trueDimension: trueDimension }, - }; - - /* opacityProperty = { - property: 'opacity', - defaultValue: 1, - interpolators: {numbers}, - functions = { prepareStart, prepareProperty, onStart } - } */ - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartOpacity(tweenProp/* , value */) { - // opacity could be 0 sometimes, we need to check regardless - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000; - /* eslint-enable */ - }; - } - } - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getOpacity(tweenProp/* , value */) { - return getStyleForProperty(this.element, tweenProp); - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareOpacity(/* tweenProp, */_, value) { - return parseFloat(value); // opacity always FLOAT - } - - // All Component Functions - var opacityFunctions = { - prepareStart: getOpacity, - prepareProperty: prepareOpacity, - onStart: onStartOpacity, - }; - - // Full Component - var OpacityProperty = { - component: 'opacityProperty', - property: 'opacity', - defaultValue: 1, - Interpolate: { numbers: numbers }, - functions: opacityFunctions, - }; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartDraw(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable no-bitwise -- impossible to satisfy */ - var pathLength = (a.l * 100 >> 0) / 100; - var start = (numbers(a.s, b.s, v) * 100 >> 0) / 100; - var end = (numbers(a.e, b.e, v) * 100 >> 0) / 100; - var offset = 0 - start; - var dashOne = end + offset; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDashoffset = offset + "px"; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDasharray = (((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100) + "px, " + pathLength + "px"; - /* eslint-disable no-bitwise -- impossible to satisfy */ - }; - } - } - - // Component Util - /** - * Convert a `` length percent value to absolute. - * @param {string} v raw value - * @param {number} l length value - * @returns {number} the absolute value - */ - function percent(v, l) { - return (parseFloat(v) / 100) * l; - } - - /** - * Returns the `` length. - * It doesn't compute `rx` and / or `ry` of the element. - * @see http://stackoverflow.com/a/30376660 - * @param {SVGRectElement} el target element - * @returns {number} the `` length - */ - function getRectLength(el) { - var w = el.getAttribute('width'); - var h = el.getAttribute('height'); - return (w * 2) + (h * 2); - } - - /** - * Returns the `` / `` length. - * @param {SVGPolylineElement | SVGPolygonElement} el target element - * @returns {number} the element length - */ - function getPolyLength(el) { - var points = el.getAttribute('points').split(' '); - - var len = 0; - if (points.length > 1) { - var coord = function (p) { - var c = p.split(','); - if (c.length !== 2) { return 0; } // return undefined - if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; } - return [parseFloat(c[0]), parseFloat(c[1])]; - }; - - var dist = function (c1, c2) { - if (c1 !== undefined && c2 !== undefined) { - return Math.sqrt(Math.pow( (c2[0] - c1[0]), 2 ) + Math.pow( (c2[1] - c1[1]), 2 )); - } - return 0; - }; - - if (points.length > 2) { - for (var i = 0; i < points.length - 1; i += 1) { - len += dist(coord(points[i]), coord(points[i + 1])); - } - } - len += el.tagName === 'polygon' - ? dist(coord(points[0]), coord(points[points.length - 1])) : 0; - } - return len; - } - - /** - * Returns the `` length. - * @param {SVGLineElement} el target element - * @returns {number} the element length - */ - function getLineLength(el) { - var x1 = el.getAttribute('x1'); - var x2 = el.getAttribute('x2'); - var y1 = el.getAttribute('y1'); - var y2 = el.getAttribute('y2'); - return Math.sqrt(Math.pow( (x2 - x1), 2 ) + Math.pow( (y2 - y1), 2 )); - } - - /** - * Returns the `` length. - * @param {SVGCircleElement} el target element - * @returns {number} the element length - */ - function getCircleLength(el) { - var r = el.getAttribute('r'); - return 2 * Math.PI * r; - } - - // returns the length of an ellipse - /** - * Returns the `` length. - * @param {SVGEllipseElement} el target element - * @returns {number} the element length - */ - function getEllipseLength(el) { - var rx = el.getAttribute('rx'); - var ry = el.getAttribute('ry'); - var len = 2 * rx; - var wid = 2 * ry; - return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; - } - - /** - * Returns the shape length. - * @param {SVGPathCommander.shapeTypes} el target element - * @returns {number} the element length - */ - function getTotalLength(el) { - if (el.tagName === 'rect') { - return getRectLength(el); - } if (el.tagName === 'circle') { - return getCircleLength(el); - } if (el.tagName === 'ellipse') { - return getEllipseLength(el); - } if (['polygon', 'polyline'].includes(el.tagName)) { - return getPolyLength(el); - } if (el.tagName === 'line') { - return getLineLength(el); - } - // ESLint - return 0; - } - - /** - * Returns the property tween object. - * @param {SVGPathCommander.shapeTypes} element the target element - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function getDraw(element, value) { - var length = /path|glyph/.test(element.tagName) - ? element.getTotalLength() - : getTotalLength(element); - var start; - var end; - var dasharray; - var offset; - - if (value instanceof Object && Object.keys(value).every(function (v) { return ['s', 'e', 'l'].includes(v); })) { - return value; - } if (typeof value === 'string') { - var v = value.split(/,|\s/); - start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]); - end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]); - } else if (typeof value === 'undefined') { - offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset')); - dasharray = getStyleForProperty(element, 'stroke-dasharray').split(','); - - start = 0 - offset; - end = parseFloat(dasharray[0]) + start || length; - } - return { s: start, e: end, l: length }; - } - - /** - * Reset CSS properties associated with the `draw` property. - * @param {SVGPathCommander.shapeTypes} element target - */ - function resetDraw(elem) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - elem.style.strokeDashoffset = ''; - elem.style.strokeDasharray = ''; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - } - - // Component Functions - /** - * Returns the property tween object. - * @returns {KUTE.drawObject} the property tween object - */ - function getDrawValue(/* prop, value */) { - return getDraw(this.element); - } - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function prepareDraw(_, value) { - return getDraw(this.element, value); - } - - // All Component Functions - var svgDrawFunctions = { - prepareStart: getDrawValue, - prepareProperty: prepareDraw, - onStart: onStartDraw, - }; - - // Component Full - var SvgDrawProperty = { - component: 'svgDraw', - property: 'draw', - defaultValue: '0% 0%', - Interpolate: { numbers: numbers }, - functions: svgDrawFunctions, - // Export to global for faster execution - Util: { - getRectLength: getRectLength, - getPolyLength: getPolyLength, - getLineLength: getLineLength, - getCircleLength: getCircleLength, - getEllipseLength: getEllipseLength, - getTotalLength: getTotalLength, - resetDraw: resetDraw, - getDraw: getDraw, - percent: percent, - }, - }; - - /** - * Segment params length - * @type {Record} - */ - var paramsCount = { - a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0, - }; - - /** - * Breaks the parsing of a pathString once a segment is finalized. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function finalizeSegment(path) { - var pathCommand = path.pathValue[path.segmentStart]; - var LK = pathCommand.toLowerCase(); - var data = path.data; - - // Process duplicated commands (without comand name) - if (LK === 'm' && data.length > 2) { - // @ts-ignore - path.segments.push([pathCommand, data[0], data[1]]); - data = data.slice(2); - LK = 'l'; - pathCommand = pathCommand === 'm' ? 'l' : 'L'; - } - - // @ts-ignore - while (data.length >= paramsCount[LK]) { - // path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK]))); - // @ts-ignore - path.segments.push([pathCommand ].concat( data.splice(0, paramsCount[LK]))); - // @ts-ignore - if (!paramsCount[LK]) { - break; - } - } - } - - var invalidPathValue = 'Invalid path value'; - - /** - * Validates an A (arc-to) specific path command value. - * Usually a `large-arc-flag` or `sweep-flag`. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanFlag(path) { - var index = path.index; - var ch = path.pathValue.charCodeAt(index); - - if (ch === 0x30/* 0 */) { - path.param = 0; - path.index += 1; - return; - } - - if (ch === 0x31/* 1 */) { - path.param = 1; - path.index += 1; - return; - } - - path.err = invalidPathValue + ": invalid Arc flag \"" + ch + "\", expecting 0 or 1 at index " + index; - } - - /** - * Checks if a character is a digit. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isDigit(code) { - return (code >= 48 && code <= 57); // 0..9 - } - - /** - * Validates every character of the path string, - * every path command, negative numbers or floating point numbers. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanParam(path) { - var max = path.max; - var pathValue = path.pathValue; - var start = path.index; - var index = start; - var zeroFirst = false; - var hasCeiling = false; - var hasDecimal = false; - var hasDot = false; - var ch; - - if (index >= max) { - // path.err = 'SvgPath: missed param (at pos ' + index + ')'; - path.err = invalidPathValue + " at " + index + ": missing param " + (pathValue[index]); - return; - } - ch = pathValue.charCodeAt(index); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - // This logic is shamelessly borrowed from Esprima - // https://github.com/ariya/esprimas - if (!isDigit(ch) && ch !== 0x2E/* . */) { - // path.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')'; - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " is not a number"; - return; - } - - if (ch !== 0x2E/* . */) { - zeroFirst = (ch === 0x30/* 0 */); - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - - if (zeroFirst && index < max) { - // decimal number starts with '0' such as '09' is illegal. - if (ch && isDigit(ch)) { - // path.err = 'SvgPath: numbers started with `0` such as `09` - // are illegal (at pos ' + start + ')'; - path.err = invalidPathValue + " at index " + start + ": " + (pathValue[start]) + " illegal number"; - return; - } - } - - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasCeiling = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x2E/* . */) { - hasDot = true; - index += 1; - while (isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasDecimal = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x65/* e */ || ch === 0x45/* E */) { - if (hasDot && !hasCeiling && !hasDecimal) { - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " invalid float exponent"; - return; - } - - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - } - if (index < max && isDigit(pathValue.charCodeAt(index))) { - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - } - } else { - // path.err = 'SvgPath: invalid float exponent (at pos ' + index + ')'; - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " invalid float exponent"; - return; - } - } - - path.index = index; - path.param = +path.pathValue.slice(start, index); - } - - /** - * Checks if the character is a space. - * - * @param {number} ch the character to check - * @returns {boolean} check result - */ - function isSpace(ch) { - var specialSpaces = [ - 0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, - 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF]; - return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029) // Line terminators - // White spaces - || (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) - || (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); - } - - /** - * Points the parser to the next character in the - * path string every time it encounters any kind of - * space character. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function skipSpaces(path) { - var pathValue = path.pathValue; - var max = path.max; - while (path.index < max && isSpace(pathValue.charCodeAt(path.index))) { - path.index += 1; - } - } - - /** - * Checks if the character is a path command. - * - * @param {any} code the character to check - * @returns {boolean} check result - */ - function isPathCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - switch (code | 0x20) { - case 0x6D/* m */: - case 0x7A/* z */: - case 0x6C/* l */: - case 0x68/* h */: - case 0x76/* v */: - case 0x63/* c */: - case 0x73/* s */: - case 0x71/* q */: - case 0x74/* t */: - case 0x61/* a */: - // case 0x72/* r */: - return true; - default: - return false; - } - } - - /** - * Checks if the character is or belongs to a number. - * [0-9]|+|-|. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isDigitStart(code) { - return (code >= 48 && code <= 57) /* 0..9 */ - || code === 0x2B /* + */ - || code === 0x2D /* - */ - || code === 0x2E; /* . */ - } - - /** - * Checks if the character is an A (arc-to) path command. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isArcCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - return (code | 0x20) === 0x61; - } - - /** - * Scans every character in the path string to determine - * where a segment starts and where it ends. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanSegment(path) { - var max = path.max; - var pathValue = path.pathValue; - var index = path.index; - var cmdCode = pathValue.charCodeAt(index); - var reqParams = paramsCount[pathValue[index].toLowerCase()]; - - path.segmentStart = index; - - if (!isPathCommand(cmdCode)) { - path.err = invalidPathValue + ": " + (pathValue[index]) + " not a path command"; - return; - } - - path.index += 1; - skipSpaces(path); - - path.data = []; - - if (!reqParams) { - // Z - finalizeSegment(path); - return; - } - - for (;;) { - for (var i = reqParams; i > 0; i -= 1) { - if (isArcCommand(cmdCode) && (i === 3 || i === 4)) { scanFlag(path); } - else { scanParam(path); } - - if (path.err.length) { - return; - } - path.data.push(path.param); - - skipSpaces(path); - - // after ',' param is mandatory - if (path.index < max && pathValue.charCodeAt(path.index) === 0x2C/* , */) { - path.index += 1; - skipSpaces(path); - } - } - - if (path.index >= path.max) { - break; - } - - // Stop on next segment - if (!isDigitStart(pathValue.charCodeAt(path.index))) { - break; - } - } - - finalizeSegment(path); - } - - /** - * Returns a clone of an existing `pathArray`. - * - * @param {SVGPathCommander.pathArray | SVGPathCommander.pathSegment} path the source `pathArray` - * @returns {any} the cloned `pathArray` - */ - function clonePath(path) { - return path.map(function (x) { return (Array.isArray(x) ? [].concat( x ) : x); }); - } - - /** - * The `PathParser` is used by the `parsePathString` static method - * to generate a `pathArray`. - * - * @param {string} pathString - */ - function PathParser(pathString) { - /** @type {SVGPathCommander.pathArray} */ - // @ts-ignore - this.segments = []; - /** @type {string} */ - this.pathValue = pathString; - /** @type {number} */ - this.max = pathString.length; - /** @type {number} */ - this.index = 0; - /** @type {number} */ - this.param = 0.0; - /** @type {number} */ - this.segmentStart = 0; - /** @type {any} */ - this.data = []; - /** @type {string} */ - this.err = ''; - } - - /** - * Iterates an array to check if it's an actual `pathArray`. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isPathArray(path) { - return Array.isArray(path) && path.every(function (seg) { - var lk = seg[0].toLowerCase(); - return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk); - }); - } - - /** - * Parses a path string value and returns an array - * of segments we like to call `pathArray`. - * - * @param {SVGPathCommander.pathArray | string} pathInput the string to be parsed - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` - */ - function parsePathString(pathInput) { - if (isPathArray(pathInput)) { - // @ts-ignore -- isPathArray also checks if it's an `Array` - return clonePath(pathInput); - } - - // @ts-ignore -- pathInput is now string - var path = new PathParser(pathInput); - - skipSpaces(path); - - while (path.index < path.max && !path.err.length) { - scanSegment(path); - } - - if (path.err.length) { - // @ts-ignore - path.segments = []; - } else if (path.segments.length) { - if (!'mM'.includes(path.segments[0][0])) { - path.err = invalidPathValue + ": missing M/m"; - // @ts-ignore - path.segments = []; - } else { - path.segments[0][0] = 'M'; - } - } - - return path.segments; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isAbsoluteArray(path) { - return isPathArray(path) - // @ts-ignore -- `isPathArray` also checks if it's `Array` - && path.every(function (x) { return x[0] === x[0].toUpperCase(); }); - } - - /** - * Parses a path string value or object and returns an array - * of segments, all converted to absolute values. - * - * @param {string | SVGPathCommander.pathArray} pathInput the path string | object - * @returns {SVGPathCommander.absoluteArray} the resulted `pathArray` with absolute values - */ - function pathToAbsolute(pathInput) { - if (isAbsoluteArray(pathInput)) { - // @ts-ignore -- `isAbsoluteArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - var path = parsePathString(pathInput); - var x = 0; var y = 0; - var mx = 0; var my = 0; - - // @ts-ignore -- the `absoluteSegment[]` is for sure an `absolutePath` - return path.map(function (segment) { - var assign, assign$1, assign$2; - - var values = segment.slice(1).map(Number); - var pathCommand = segment[0]; - /** @type {SVGPathCommander.absoluteCommand} */ - // @ts-ignore - var absCommand = pathCommand.toUpperCase(); - - if (pathCommand === 'M') { - (assign = values, x = assign[0], y = assign[1]); - mx = x; - my = y; - return ['M', x, y]; - } - /** @type {SVGPathCommander.absoluteSegment} */ - // @ts-ignore - var absoluteSegment = []; - - if (pathCommand !== absCommand) { - switch (absCommand) { - case 'A': - absoluteSegment = [ - absCommand, values[0], values[1], values[2], - values[3], values[4], values[5] + x, values[6] + y]; - break; - case 'V': - absoluteSegment = [absCommand, values[0] + y]; - break; - case 'H': - absoluteSegment = [absCommand, values[0] + x]; - break; - default: { - // use brakets for `eslint: no-case-declaration` - // https://stackoverflow.com/a/50753272/803358 - var absValues = values.map(function (n, j) { return n + (j % 2 ? y : x); }); - // @ts-ignore for n, l, c, s, q, t - absoluteSegment = [absCommand ].concat( absValues); - } - } - } else { - // @ts-ignore - absoluteSegment = [absCommand ].concat( values); - } - - var segLength = absoluteSegment.length; - switch (absCommand) { - case 'Z': - x = mx; - y = my; - break; - case 'H': - // @ts-ignore - (assign$1 = absoluteSegment, x = assign$1[1]); - break; - case 'V': - // @ts-ignore - (assign$2 = absoluteSegment, y = assign$2[1]); - break; - default: - // @ts-ignore - x = absoluteSegment[segLength - 2]; - // @ts-ignore - y = absoluteSegment[segLength - 1]; - - if (absCommand === 'M') { - mx = x; - my = y; - } - } - return absoluteSegment; - }); - } - - /** - * Splits an extended A (arc-to) segment into two cubic-bezier segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` this segment belongs to - * @param {string[]} allPathCommands all previous path commands - * @param {number} i the segment index - */ - - function fixArc(path, allPathCommands, i) { - if (path[i].length > 7) { - path[i].shift(); - var segment = path[i]; - var ni = i; // ESLint - while (segment.length) { - // if created multiple C:s, their original seg is saved - allPathCommands[i] = 'A'; - // @ts-ignore - path.splice(ni += 1, 0, ['C' ].concat( segment.splice(0, 6))); - } - path.splice(i, 1); - } - } - - /** - * Returns the missing control point from an - * T (shorthand quadratic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {string} prevCommand the previous path command - * @returns {{qx: number, qy: number}}} the missing control point - */ - function shorthandToQuad(x1, y1, qx, qy, prevCommand) { - return 'QT'.includes(prevCommand) - ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy } - : { qx: x1, qy: y1 }; - } - - /** - * Returns the missing control point from an - * S (shorthand cubic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @param {string} prevCommand the previous path command - * @returns {{x1: number, y1: number}}} the missing control point - */ - function shorthandToCubic(x1, y1, x2, y2, prevCommand) { - return 'CS'.includes(prevCommand) - ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2 } - : { x1: x1, y1: y1 }; - } - - /** - * Normalizes a single segment of a `pathArray` object. - * - * @param {SVGPathCommander.pathSegment} segment the segment object - * @param {any} params the coordinates of the previous segment - * @param {string} prevCommand the path command of the previous segment - * @returns {SVGPathCommander.normalSegment} the normalized segment - */ - function normalizeSegment(segment, params, prevCommand) { - var pathCommand = segment[0]; - var px1 = params.x1; - var py1 = params.y1; - var px2 = params.x2; - var py2 = params.y2; - var values = segment.slice(1).map(Number); - var result = segment; - - if (!'TQ'.includes(pathCommand)) { - // optional but good to be cautious - params.qx = null; - params.qy = null; - } - - if (pathCommand === 'H') { - result = ['L', segment[1], py1]; - } else if (pathCommand === 'V') { - result = ['L', px1, segment[1]]; - } else if (pathCommand === 'S') { - var ref = shorthandToCubic(px1, py1, px2, py2, prevCommand); - var x1 = ref.x1; - var y1 = ref.y1; - params.x1 = x1; - params.y1 = y1; - // @ts-ignore - result = ['C', x1, y1 ].concat( values); - } else if (pathCommand === 'T') { - var ref$1 = shorthandToQuad(px1, py1, params.qx, params.qy, prevCommand); - var qx = ref$1.qx; - var qy = ref$1.qy; - params.qx = qx; - params.qy = qy; - // @ts-ignore - result = ['Q', qx, qy ].concat( values); - } else if (pathCommand === 'Q') { - var nqx = values[0]; - var nqy = values[1]; - params.qx = nqx; - params.qy = nqy; - } - - // @ts-ignore -- we-re switching `pathSegment` type - return result; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all segments are in non-shorthand notation - * with absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isNormalizedArray(path) { - // @ts-ignore -- `isAbsoluteArray` also checks if it's `Array` - return isAbsoluteArray(path) && path.every(function (seg) { return 'ACLMQZ'.includes(seg[0]); }); - } - - /** - * @type {SVGPathCommander.parserParams} - */ - var paramsParser = { - x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null, - }; - - /** - * Normalizes a `path` object for further processing: - * * convert segments to absolute values - * * convert shorthand path commands to their non-shorthand notation - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.normalArray} the normalized `pathArray` - */ - function normalizePath(pathInput) { - var assign; - - if (isNormalizedArray(pathInput)) { - // @ts-ignore -- `isNormalizedArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - /** @type {SVGPathCommander.normalArray} */ - // @ts-ignore -- `absoluteArray` will become a `normalArray` - var path = pathToAbsolute(pathInput); - var params = Object.assign({}, paramsParser); - var allPathCommands = []; - var ii = path.length; - var pathCommand = ''; - var prevCommand = ''; - - for (var i = 0; i < ii; i += 1) { - (assign = path[i], pathCommand = assign[0]); - - // Save current path command - allPathCommands[i] = pathCommand; - // Get previous path command - if (i) { prevCommand = allPathCommands[i - 1]; } - // Previous path command is used to normalizeSegment - // @ts-ignore -- expected on normalization - path[i] = normalizeSegment(path[i], params, prevCommand); - - var segment = path[i]; - var seglen = segment.length; - - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - return path; - } - - /** - * Checks a `pathArray` for an unnecessary `Z` segment - * and returns a new `pathArray` without it. - * - * The `pathInput` must be a single path, without - * sub-paths. For multi-path `` elements, - * use `splitPath` first and apply this utility on each - * sub-path separately. - * - * @param {SVGPathCommander.pathArray | string} pathInput the `pathArray` source - * @return {SVGPathCommander.pathArray} a fixed `pathArray` - */ - function fixPath(pathInput) { - var pathArray = parsePathString(pathInput); - var normalArray = normalizePath(pathArray); - var length = pathArray.length; - var isClosed = normalArray.slice(-1)[0][0] === 'Z'; - var segBeforeZ = isClosed ? length - 2 : length - 1; - - var ref = normalArray[0].slice(1); - var mx = ref[0]; - var my = ref[1]; - var ref$1 = normalArray[segBeforeZ].slice(-2); - var x = ref$1[0]; - var y = ref$1[1]; - - if (isClosed && mx === x && my === y) { - // @ts-ignore -- `pathSegment[]` is quite a `pathArray` - return pathArray.slice(0, -1); - } - return pathArray; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all C (cubic bezier) segments. - * - * @param {string | SVGPathCommander.pathArray} path the `Array` to be checked - * @returns {boolean} iteration result - */ - function isCurveArray(path) { - // @ts-ignore -- `isPathArray` also checks if it's `Array` - return isPathArray(path) && path.every(function (seg) { return 'MC'.includes(seg[0]); }); - } - - /** - * Returns an {x,y} vector rotated by a given - * angle in radian. - * - * @param {number} x the initial vector x - * @param {number} y the initial vector y - * @param {number} rad the radian vector angle - * @returns {{x: number, y: number}} the rotated vector - */ - function rotateVector(x, y, rad) { - var X = x * Math.cos(rad) - y * Math.sin(rad); - var Y = x * Math.sin(rad) + y * Math.cos(rad); - return { x: X, y: Y }; - } - - /** - * Converts A (arc-to) segments to C (cubic-bezier-to). - * - * For more information of where this math came from visit: - * http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - * - * @param {number} X1 the starting x position - * @param {number} Y1 the starting y position - * @param {number} RX x-radius of the arc - * @param {number} RY y-radius of the arc - * @param {number} angle x-axis-rotation of the arc - * @param {number} LAF large-arc-flag of the arc - * @param {number} SF sweep-flag of the arc - * @param {number} X2 the ending x position - * @param {number} Y2 the ending y position - * @param {number[]=} recursive the parameters needed to split arc into 2 segments - * @return {number[]} the resulting cubic-bezier segment(s) - */ - function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) { - var assign; - - var x1 = X1; var y1 = Y1; var rx = RX; var ry = RY; var x2 = X2; var y2 = Y2; - // for more information of where this Math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - var d120 = (Math.PI * 120) / 180; - - var rad = (Math.PI / 180) * (+angle || 0); - /** @type {number[]} */ - var res = []; - var xy; - var f1; - var f2; - var cx; - var cy; - - if (!recursive) { - xy = rotateVector(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotateVector(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - - var x = (x1 - x2) / 2; - var y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = Math.sqrt(h); - rx *= h; - ry *= h; - } - var rx2 = rx * rx; - var ry2 = ry * ry; - - var k = (LAF === SF ? -1 : 1) - * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) - / (rx2 * y * y + ry2 * x * x))); - - cx = ((k * rx * y) / ry) + ((x1 + x2) / 2); - cy = ((k * -ry * x) / rx) + ((y1 + y2) / 2); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f1 = (Math.asin((((y1 - cy) / ry))) * (Math.pow( 10, 9 )) >> 0) / (Math.pow( 10, 9 )); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f2 = (Math.asin((((y2 - cy) / ry))) * (Math.pow( 10, 9 )) >> 0) / (Math.pow( 10, 9 )); - - f1 = x1 < cx ? Math.PI - f1 : f1; - f2 = x2 < cx ? Math.PI - f2 : f2; - if (f1 < 0) { (f1 = Math.PI * 2 + f1); } - if (f2 < 0) { (f2 = Math.PI * 2 + f2); } - if (SF && f1 > f2) { - f1 -= Math.PI * 2; - } - if (!SF && f2 > f1) { - f2 -= Math.PI * 2; - } - } else { - (assign = recursive, f1 = assign[0], f2 = assign[1], cx = assign[2], cy = assign[3]); - } - var df = f2 - f1; - if (Math.abs(df) > d120) { - var f2old = f2; - var x2old = x2; - var y2old = y2; - f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1); - x2 = cx + rx * Math.cos(f2); - y2 = cy + ry * Math.sin(f2); - res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - var c1 = Math.cos(f1); - var s1 = Math.sin(f1); - var c2 = Math.cos(f2); - var s2 = Math.sin(f2); - var t = Math.tan(df / 4); - var hx = (4 / 3) * rx * t; - var hy = (4 / 3) * ry * t; - var m1 = [x1, y1]; - var m2 = [x1 + hx * s1, y1 - hy * c1]; - var m3 = [x2 + hx * s2, y2 - hy * c2]; - var m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return m2.concat( m3, m4, res); - } - res = m2.concat( m3, m4, res); - var newres = []; - for (var i = 0, ii = res.length; i < ii; i += 1) { - newres[i] = i % 2 - ? rotateVector(res[i - 1], res[i], rad).y - : rotateVector(res[i], res[i + 1], rad).x; - } - return newres; - } - - /** - * Converts a Q (quadratic-bezier) segment to C (cubic-bezier). - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @returns {number[]} the cubic-bezier segment - */ - function quadToCubic(x1, y1, qx, qy, x2, y2) { - var r13 = 1 / 3; - var r23 = 2 / 3; - return [ - r13 * x1 + r23 * qx, // cpx1 - r13 * y1 + r23 * qy, // cpy1 - r13 * x2 + r23 * qx, // cpx2 - r13 * y2 + r23 * qy, // cpy2 - x2, y2 ]; - } - - /** - * Returns the coordinates of a specified distance - * ratio between two points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @param {number} t the ratio - * @returns {[number, number]} the midpoint coordinates - */ - function midPoint(a, b, t) { - var ax = a[0]; - var ay = a[1]; var bx = b[0]; - var by = b[1]; - return [ax + (bx - ax) * t, ay + (by - ay) * t]; - } - - /** - * Returns the square root of the distance - * between two given points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @returns {number} the distance value - */ - function distanceSquareRoot(a, b) { - return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) - + (a[1] - b[1]) * (a[1] - b[1]) - ); - } - - /** - * Returns the length of a line (L,V,H,Z) segment, - * or a point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the distance to point - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentLineFactory(x1, y1, x2, y2, distance) { - var length = distanceSquareRoot([x1, y1], [x2, y2]); - var margin = 0.001; - - if (typeof distance === 'number') { - if (distance < margin) { - return { x: x1, y: y1 }; - } - if (distance > length + margin) { - return { x: x2, y: y2 }; - } - var ref = midPoint([x1, y1], [x2, y2], distance / length); - var x = ref[0]; - var y = ref[1]; - return { x: x, y: y }; - } - return length; - } - - /** - * Converts an L (line-to) segment to C (cubic-bezier). - * - * @param {number} x1 line start x - * @param {number} y1 line start y - * @param {number} x2 line end x - * @param {number} y2 line end y - * @returns {number[]} the cubic-bezier segment - */ - function lineToCubic(x1, y1, x2, y2) { - var t = 0.5; - /** @type {[number, number]} */ - var p0 = [x1, y1]; - /** @type {[number, number]} */ - var p1 = [x2, y2]; - var p2 = midPoint(p0, p1, t); - var p3 = midPoint(p1, p2, t); - var p4 = midPoint(p2, p3, t); - var p5 = midPoint(p3, p4, t); - var p6 = midPoint(p4, p5, t); - var seg1 = p0.concat( p2, p4, p6, [t]); - // @ts-ignore - var cp1 = segmentLineFactory.apply(void 0, seg1); - var seg2 = p6.concat( p5, p3, p1, [0]); - // @ts-ignore - var cp2 = segmentLineFactory.apply(void 0, seg2); - - // @ts-ignore - return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2]; - } - - /** - * Converts any segment to C (cubic-bezier). - * - * @param {SVGPathCommander.pathSegment} segment the source segment - * @param {SVGPathCommander.parserParams} params the source segment parameters - * @returns {SVGPathCommander.cubicSegment | SVGPathCommander.MSegment} the cubic-bezier segment - */ - function segmentToCubic(segment, params) { - var pathCommand = segment[0]; - var values = segment.slice(1).map(function (n) { return +n; }); - var x = values[0]; - var y = values[1]; - var args; - var px1 = params.x1; - var py1 = params.y1; - var px = params.x; - var py = params.y; - - if (!'TQ'.includes(pathCommand)) { - params.qx = null; - params.qy = null; - } - - switch (pathCommand) { - case 'M': - params.x = x; - params.y = y; - return segment; - case 'A': - args = [px1, py1 ].concat( values); - // @ts-ignore -- relax, the utility will return 6 numbers - return ['C' ].concat( arcToCubic.apply(void 0, args)); - case 'Q': - params.qx = x; - params.qy = y; - args = [px1, py1 ].concat( values); - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( quadToCubic.apply(void 0, args)); - case 'L': - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( lineToCubic(px1, py1, x, y)); - case 'Z': - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( lineToCubic(px1, py1, px, py)); - } - // @ts-ignore -- we're switching `pathSegment` type - return segment; - } - - /** - * Parses a path string value or 'pathArray' and returns a new one - * in which all segments are converted to cubic-bezier. - * - * In addition, un-necessary `Z` segment is removed if previous segment - * extends to the `M` segment. - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.curveArray} the resulted `pathArray` converted to cubic-bezier - */ - function pathToCurve(pathInput) { - var assign; - - if (isCurveArray(pathInput)) { - // @ts-ignore -- `isCurveArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - var path = fixPath(normalizePath(pathInput)); - var params = Object.assign({}, paramsParser); - var allPathCommands = []; - var pathCommand = ''; // ts-lint - var ii = path.length; - - for (var i = 0; i < ii; i += 1) { - (assign = path[i], pathCommand = assign[0]); - allPathCommands[i] = pathCommand; - - path[i] = segmentToCubic(path[i], params); - - fixArc(path, allPathCommands, i); - ii = path.length; - - var segment = path[i]; - var seglen = segment.length; - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - // @ts-ignore - return path; - } - - /** - * SVGPathCommander default options - * @type {SVGPathCommander.options} - */ - var defaultOptions = { - origin: [0, 0, 0], - round: 4, - }; - - /** - * Rounds the values of a `pathArray` instance to - * a specified amount of decimals and returns it. - * - * @param {SVGPathCommander.pathArray} path the source `pathArray` - * @param {number | boolean} roundOption the amount of decimals to round numbers to - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` with rounded values - */ - function roundPath(path, roundOption) { - var round = defaultOptions.round; - if (roundOption === false || round === false) { return clonePath(path); } - round = roundOption >= 1 ? roundOption : round; - // to round values to the power - // the `round` value must be integer - // @ts-ignore - var pow = round >= 1 ? (Math.pow( 10, round )) : 1; - - // @ts-ignore -- `pathSegment[]` is `pathArray` - return path.map(function (pi) { - var values = pi.slice(1).map(Number) - .map(function (n) { return (n % 1 === 0 ? n : Math.round(n * pow) / pow); }); - return [pi[0] ].concat( values); - }); - } - - /** - * Returns a valid `d` attribute string value created - * by rounding values and concatenating the `pathArray` segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` object - * @param {any} round amount of decimals to round values to - * @returns {string} the concatenated path string - */ - function pathToString(path, round) { - return roundPath(path, round) - .map(function (x) { return x[0] + x.slice(1).join(' '); }).join(''); - } - - /** - * Reverses all segments and their values from a `pathArray` - * which consists of only C (cubic-bezier) path commands. - * - * @param {SVGPathCommander.curveArray} path the source `pathArray` - * @returns {SVGPathCommander.curveArray} the reversed `pathArray` - */ - function reverseCurve(path) { - var rotatedCurve = path.slice(1) - .map(function (x, i, curveOnly) { return (!i - ? path[0].slice(1).concat( x.slice(1)) - : curveOnly[i - 1].slice(-2).concat( x.slice(1))); }) - .map(function (x) { return x.map(function (_, i) { return x[x.length - i - 2 * (1 - (i % 2))]; }); }) - .reverse(); - - // @ts-ignore -- expected on reverse operations - return [['M' ].concat( rotatedCurve[0].slice(0, 2)) ].concat( rotatedCurve.map(function (x) { return ['C' ].concat( x.slice(2)); })); - } - - /** - * Returns the area of a single cubic-bezier segment. - * - * http://objectmix.com/graphics/133553-area-closed-bezier-curve.html - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @returns {number} the area of the cubic-bezier segment - */ - function getCubicSegArea(x1, y1, c1x, c1y, c2x, c2y, x2, y2) { - return (3 * ((y2 - y1) * (c1x + c2x) - (x2 - x1) * (c1y + c2y) - + (c1y * (x1 - c2x)) - (c1x * (y1 - c2y)) - + (y2 * (c2x + x1 / 3)) - (x2 * (c2y + y1 / 3)))) / 20; - } - - /** - * Returns the area of a shape. - * @author Jürg Lehni & Jonathan Puckey - * - * @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js - * - * @param {SVGPathCommander.pathArray} path the shape `pathArray` - * @returns {number} the length of the cubic-bezier segment - */ - function getPathArea(path) { - var x = 0; var y = 0; var len = 0; - - return pathToCurve(path).map(function (seg) { - var assign, assign$1; - - switch (seg[0]) { - case 'M': - (assign = seg, x = assign[1], y = assign[2]); - return 0; - default: - // @ts-ignore -- the utility will have proper amount of params - len = getCubicSegArea.apply(void 0, [ x, y ].concat( seg.slice(1) )); - // @ts-ignore -- the segment always has numbers - (assign$1 = seg.slice(-2), x = assign$1[0], y = assign$1[1]); - return len; - } - }).reduce(function (a, b) { return a + b; }, 0); - } - - /** - * Check if a path is drawn clockwise and returns true if so, - * false otherwise. - * - * @param {SVGPathCommander.pathArray} path the path string or `pathArray` - * @returns {boolean} true when clockwise or false if not - */ - function getDrawDirection(path) { - return getPathArea(pathToCurve(path)) >= 0; - } - - /** - * Split a cubic-bezier segment into two. - * - * @param {number[]} pts the cubic-bezier parameters - * @return {SVGPathCommander.cubicSegment[]} two new cubic-bezier segments - */ - function splitCubic(pts/* , ratio */) { - var t = /* ratio || */ 0.5; - var p0 = pts.slice(0, 2); - var p1 = pts.slice(2, 4); - var p2 = pts.slice(4, 6); - var p3 = pts.slice(6, 8); - // @ts-ignore - var p4 = midPoint(p0, p1, t); - // @ts-ignore - var p5 = midPoint(p1, p2, t); - // @ts-ignore - var p6 = midPoint(p2, p3, t); - var p7 = midPoint(p4, p5, t); - var p8 = midPoint(p5, p6, t); - var p9 = midPoint(p7, p8, t); - - return [ - ['C' ].concat( p4, p7, p9), - // @ts-ignore - ['C' ].concat( p8, p6, p3) ]; - } - - /** - * Split a path into an `Array` of sub-path strings. - * - * In the process, values are converted to absolute - * for visual consistency. - * - * @param {SVGPathCommander.pathArray | string} pathInput the source `pathArray` - * @return {string[]} an array with all sub-path strings - */ - function splitPath(pathInput) { - return pathToString(pathToAbsolute(pathInput), 0) - .replace(/(m|M)/g, '|$1') - .split('|') - .map(function (s) { return s.trim(); }) - .filter(function (s) { return s; }); - } - - /** - * Returns a point at a given length of a C (cubic-bezier) segment. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number} t a [0-1] ratio - * @returns {{x: number, y: number}} the cubic-bezier segment length - */ - function getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t) { - var t1 = 1 - t; - return { - x: (Math.pow( t1, 3 )) * x1 - + 3 * (Math.pow( t1, 2 )) * t * c1x - + 3 * t1 * (Math.pow( t, 2 )) * c2x - + (Math.pow( t, 3 )) * x2, - y: (Math.pow( t1, 3 )) * y1 - + 3 * (Math.pow( t1, 2 )) * t * c1y - + 3 * t1 * (Math.pow( t, 2 )) * c2y - + (Math.pow( t, 3 )) * y2, - }; - } - - /** - * Returns the length of a C (cubic-bezier) segment, - * or an {x,y} point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the point distance - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentCubicFactory(x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance) { - var assign; - - var x = x1; var y = y1; - var lengthMargin = 0.001; - var totalLength = 0; - var prev = [x1, y1, totalLength]; - /** @type {[number, number]} */ - var cur = [x1, y1]; - var t = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x: x, y: y }; - } - - var n = 100; - for (var j = 0; j <= n; j += 1) { - t = j / n; - - ((assign = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t), x = assign.x, y = assign.y)); - totalLength += distanceSquareRoot(cur, [x, y]); - cur = [x, y]; - - if (typeof distance === 'number' && totalLength >= distance) { - var dv = (totalLength - distance) / (totalLength - prev[2]); - - return { - x: cur[0] * (1 - dv) + prev[0] * dv, - y: cur[1] * (1 - dv) + prev[1] * dv, - }; - } - prev = [x, y, totalLength]; - } - - if (typeof distance === 'number' && distance >= totalLength) { - return { x: x2, y: y2 }; - } - return totalLength; - } - - // Component Functions - - /** - * Sets the property update function. - * @param {string} tweenProp the `path` property - */ - function onStartCubicMorph(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function updateMorph(elem, a, b, v) { - var curve = []; - var path1 = a.curve; - var path2 = b.curve; - for (var i = 0, l = path2.length; i < l; i += 1) { // each path command - curve.push([path1[i][0]]); - for (var j = 1, l2 = path1[i].length; j < l2; j += 1) { // each command coordinate - /* eslint-disable-next-line no-bitwise -- impossible to satisfy */ - curve[i].push((numbers(path1[i][j], path2[i][j], v) * 1000 >> 0) / 1000); - } - } - elem.setAttribute('d', v === 1 ? b.original : pathToString(curve)); - }; - } - } - - // Component Util - /** - * Returns first `pathArray` from multi-paths path. - * @param {SVGPathCommander.pathArray | string} source the source `pathArray` or string - * @returns {KUTE.curveSpecs[]} an `Array` with a custom tuple for `equalizeSegments` - */ - function getCurveArray(source) { - return pathToCurve(splitPath(source)[0]) - .map(function (segment, i, pathArray) { - var segmentData = i && pathArray[i - 1].slice(-2).concat( segment.slice(1)); - var curveLength = i ? segmentCubicFactory.apply(void 0, segmentData) : 0; - - var subsegs; - if (i) { - // must be [segment,segment] - subsegs = curveLength ? splitCubic(segmentData) : [segment, segment]; - } else { - subsegs = [segment]; - } - - return { - s: segment, - ss: subsegs, - l: curveLength, - }; - }); - } - - /** - * Returns two `curveArray` with same amount of segments. - * @param {SVGPathCommander.curveArray} path1 the first `curveArray` - * @param {SVGPathCommander.curveArray} path2 the second `curveArray` - * @param {number} TL the maximum `curveArray` length - * @returns {SVGPathCommander.curveArray[]} equalized segments - */ - function equalizeSegments(path1, path2, TL) { - var c1 = getCurveArray(path1); - var c2 = getCurveArray(path2); - var L1 = c1.length; - var L2 = c2.length; - var l1 = c1.filter(function (x) { return x.l; }).length; - var l2 = c2.filter(function (x) { return x.l; }).length; - var m1 = c1.filter(function (x) { return x.l; }).reduce(function (a, ref) { - var l = ref.l; - - return a + l; - }, 0) / l1 || 0; - var m2 = c2.filter(function (x) { return x.l; }).reduce(function (a, ref) { - var l = ref.l; - - return a + l; - }, 0) / l2 || 0; - var tl = TL || Math.max(L1, L2); - var mm = [m1, m2]; - var dif = [tl - L1, tl - L2]; - var canSplit = 0; - var result = [c1, c2] - .map(function (x, i) { return (x.l === tl - ? x.map(function (y) { return y.s; }) - : x.map(function (y, j) { - canSplit = j && dif[i] && y.l >= mm[i]; - dif[i] -= canSplit ? 1 : 0; - return canSplit ? y.ss : [y.s]; - }).flat()); }); - - return result[0].length === result[1].length - ? result - : equalizeSegments(result[0], result[1], tl); - } - - /** - * Returns all possible path rotations for `curveArray`. - * @param {SVGPathCommander.curveArray} a the source `curveArray` - * @returns {SVGPathCommander.curveArray[]} all rotations for source - */ - function getRotations(a) { - var segCount = a.length; - var pointCount = segCount - 1; - - return a.map(function (_, idx) { return a.map(function (__, i) { - var oldSegIdx = idx + i; - var seg; - - if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) { - seg = a[oldSegIdx]; - return ['M' ].concat( seg.slice(-2)); - } - if (oldSegIdx >= segCount) { oldSegIdx -= pointCount; } - return a[oldSegIdx]; - }); }); - } - - /** - * Returns the `curveArray` rotation for the best morphing animation. - * @param {SVGPathCommander.curveArray} a the target `curveArray` - * @param {SVGPathCommander.curveArray} b the reference `curveArray` - * @returns {SVGPathCommander.curveArray} the best `a` rotation - */ - function getRotatedCurve(a, b) { - var segCount = a.length - 1; - var lineLengths = []; - var computedIndex = 0; - var sumLensSqrd = 0; - var rotations = getRotations(a); - - rotations.forEach(function (_, i) { - a.slice(1).forEach(function (__, j) { - sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2)); - }); - lineLengths[i] = sumLensSqrd; - sumLensSqrd = 0; - }); - - computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths)); - - return rotations[computedIndex]; - } - - // Component Functions - /** - * Returns the current `d` attribute value. - * @returns {string} - */ - function getCubicMorph(/* tweenProp, value */) { - return this.element.getAttribute('d'); - } - - /** - * Returns the property tween object. - * @see KUTE.curveObject - * - * @param {string} _ is the `path` property name, not needed - * @param {string | KUTE.curveObject} value the `path` property value - * @returns {KUTE.curveObject} - */ - function prepareCubicMorph(/* tweenProp, */_, value) { - // get path d attribute or create a path from string value - var pathObject = {}; - // remove newlines, they break some JSON strings - var pathReg = new RegExp('\\n', 'ig'); - - var el = null; - if (value instanceof SVGElement) { - el = value; - } else if (/^\.|^#/.test(value)) { - el = selector(value); - } - - // make sure to return pre-processed values - if (typeof (value) === 'object' && value.curve) { - return value; - } if (el && /path|glyph/.test(el.tagName)) { - pathObject.original = el.getAttribute('d').replace(pathReg, ''); - // maybe it's a string path already - } else if (!el && typeof (value) === 'string') { - pathObject.original = value.replace(pathReg, ''); - } - return pathObject; - } - - /** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} tweenProp is `path` tween property, but it's not needed - */ - function crossCheckCubicMorph(tweenProp/** , value */) { - if (this.valuesEnd[tweenProp]) { - var pathCurve1 = this.valuesStart[tweenProp].curve; - var pathCurve2 = this.valuesEnd[tweenProp].curve; - - if (!pathCurve1 || !pathCurve2 - || (pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length)) { - var path1 = this.valuesStart[tweenProp].original; - var path2 = this.valuesEnd[tweenProp].original; - var curves = equalizeSegments(path1, path2); - var curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) - ? reverseCurve(curves[0]) - : clonePath(curves[0]); - - this.valuesStart[tweenProp].curve = curve0; - this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1], curve0); - } - } - } - - // All Component Functions - var svgCubicMorphFunctions = { - prepareStart: getCubicMorph, - prepareProperty: prepareCubicMorph, - onStart: onStartCubicMorph, - crossCheck: crossCheckCubicMorph, - }; - - // Component Full - var svgCubicMorph = { - component: 'svgCubicMorph', - property: 'path', - defaultValue: [], - Interpolate: { numbers: numbers, pathToString: pathToString }, - functions: svgCubicMorphFunctions, - // export utils to global for faster execution - Util: { - pathToCurve: pathToCurve, - pathToAbsolute: pathToAbsolute, - pathToString: pathToString, - parsePathString: parsePathString, - getRotatedCurve: getRotatedCurve, - getRotations: getRotations, - equalizeSegments: equalizeSegments, - reverseCurve: reverseCurve, - clonePath: clonePath, - getDrawDirection: getDrawDirection, - segmentCubicFactory: segmentCubicFactory, - splitCubic: splitCubic, - splitPath: splitPath, - fixPath: fixPath, - getCurveArray: getCurveArray, - }, - }; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function svgTransformOnStart(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (l, a, b, v) { - var x = 0; - var y = 0; - var deg = Math.PI / 180; - var scale = 'scale' in b ? numbers(a.scale, b.scale, v) : 1; - var rotate = 'rotate' in b ? numbers(a.rotate, b.rotate, v) : 0; - var sin = Math.sin(rotate * deg); - var cos = Math.cos(rotate * deg); - var skewX = 'skewX' in b ? numbers(a.skewX, b.skewX, v) : 0; - var skewY = 'skewY' in b ? numbers(a.skewY, b.skewY, v) : 0; - var complex = rotate || skewX || skewY || scale !== 1 || 0; - - // start normalizing the translation, we start from last to first - // (from last chained translation) - // the normalized translation will handle the transformOrigin tween option - // and makes sure to have a consistent transformation - - // we start with removing transformOrigin from translation - x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0; - x *= scale; y *= scale; // we now apply the scale - // now we apply skews - y += skewY ? x * Math.tan(skewY * deg) : 0; x += skewX ? y * Math.tan(skewX * deg) : 0; - var 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 - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - l.setAttribute('transform', (x || y ? (("translate(" + ((x * 1000 >> 0) / 1000) + (y ? (("," + ((y * 1000 >> 0) / 1000))) : '') + ")")) : '') - + (rotate ? ("rotate(" + ((rotate * 1000 >> 0) / 1000) + ")") : '') - + (skewX ? ("skewX(" + ((skewX * 1000 >> 0) / 1000) + ")") : '') - + (skewY ? ("skewY(" + ((skewY * 1000 >> 0) / 1000) + ")") : '') - + (scale !== 1 ? ("scale(" + ((scale * 1000 >> 0) / 1000) + ")") : '')); - }; - } - } - - // Component Util - /** - * Returns a correct transform origin consistent with the shape bounding box. - * @param {string} origin transform origin string - * @param {SVGPathCommander.pathBBox} bbox path bounding box - * @returns {number} - */ - function parseStringOrigin(origin, bbox) { - var result; - var x = bbox.x; - var width = bbox.width; - if (/[a-z]/i.test(origin) && !/px/.test(origin)) { - result = origin.replace(/top|left/, 0) - .replace(/right|bottom/, 100) - .replace(/center|middle/, 50); - } else { - result = /%/.test(origin) ? (x + (parseFloat(origin) * width) / 100) : parseFloat(origin); - } - return result; - } - - /** - * Parse SVG transform string and return an object. - * @param {string} a transform string - * @returns {Object} - */ - function parseTransformString(a) { - var c = {}; - var d = a && /\)/.test(a) - ? a.substring(0, a.length - 1).split(/\)\s|\)/) - : 'none'; - - if (d instanceof Array) { - for (var j = 0, jl = d.length; j < jl; j += 1) { - var ref = d[j].trim().split('('); - var prop = ref[0]; - var val = ref[1]; - c[prop] = val; - } - } - return c; - } - - /** - * Returns the SVG transform tween object. - * @param {string} _ property name - * @param {Object} v property value object - * @returns {KUTE.transformSVGObject} the SVG transform tween object - */ - function parseTransformSVG(/* prop */_, v) { - /** @type {KUTE.transformSVGObject} */ - var svgTransformObject = {}; - - // by default the transformOrigin is "50% 50%" of the shape box - var bb = this.element.getBBox(); - var cx = bb.x + bb.width / 2; - var cy = bb.y + bb.height / 2; - - var origin = this._transformOrigin; - var translation; - - if (typeof (origin) !== 'undefined') { - origin = origin instanceof Array ? origin : origin.split(/\s/); - } else { - origin = [cx, cy]; - } - - origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0], bb); - origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1], bb); - - svgTransformObject.origin = origin; - - // populate the valuesStart and / or valuesEnd - Object.keys(v).forEach(function (i) { - var assign; - - if (i === 'rotate') { - if (typeof v[i] === 'number') { - svgTransformObject[i] = v[i]; - } else if (v[i] instanceof Array) { - (assign = v[i], svgTransformObject[i] = assign[0]); - } else { - svgTransformObject[i] = v[i].split(/\s/)[0] * 1; - } - } else if (i === 'translate') { - if (v[i] instanceof Array) { - translation = v[i]; - } else if (/,|\s/.test(v[i])) { - translation = v[i].split(','); - } else { - translation = [v[i], 0]; - } - svgTransformObject[i] = [translation[0] * 1 || 0, translation[1] * 1 || 0]; - } else if (/skew/.test(i)) { - svgTransformObject[i] = v[i] * 1 || 0; - } else if (i === 'scale') { - svgTransformObject[i] = parseFloat(v[i]) || 1; - } - }); - - return svgTransformObject; - } - - // Component Functions - /** - * Returns the property tween object. - * @param {string} prop the property name - * @param {string} value the property value - * @returns {KUTE.transformSVGObject} the property tween object - */ - function prepareSvgTransform(prop, value) { - return parseTransformSVG.call(this, prop, value); - } - - /** - * Returns an object with the current transform attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {string} current transform object - */ - function getStartSvgTransform(/* tweenProp */_, value) { - var transformObject = {}; - var currentTransform = parseTransformString(this.element.getAttribute('transform')); - - // find a value in current attribute value or add a default value - Object.keys(value).forEach(function (j) { - var scaleValue = j === 'scale' ? 1 : 0; - transformObject[j] = j in currentTransform ? currentTransform[j] : scaleValue; - }); - - return transformObject; - } - - function svgTransformCrossCheck(prop) { - if (!this._resetStart) { return; } // fix since 1.6.1 for fromTo() method - - if (this.valuesEnd[prop]) { - var valuesStart = this.valuesStart[prop]; - var valuesEnd = this.valuesEnd[prop]; - var currentTransform = parseTransformSVG.call(this, prop, - parseTransformString(this.element.getAttribute('transform'))); - - // populate the valuesStart first - Object.keys(currentTransform).forEach(function (tp) { - valuesStart[tp] = currentTransform[tp]; - }); - - // now try to determine the REAL translation - var parentSVG = this.element.ownerSVGElement; - var startMatrix = parentSVG.createSVGTransformFromMatrix( - parentSVG.createSVGMatrix() - .translate(-valuesStart.origin[0], -valuesStart.origin[1]) // - origin - .translate('translate' in valuesStart // the current translate - ? valuesStart.translate[0] : 0, 'translate' in valuesStart ? valuesStart.translate[1] - : 0) - .rotate(valuesStart.rotate || 0) - .skewX(valuesStart.skewX || 0) - .skewY(valuesStart.skewY || 0) - .scale(valuesStart.scale || 1)// the other functions - .translate(+valuesStart.origin[0], +valuesStart.origin[1]) // + origin - ); - // finally the translate we're looking for - valuesStart.translate = [startMatrix.matrix.e, startMatrix.matrix.f]; - - // copy existing and unused properties to the valuesEnd - Object.keys(valuesStart).forEach(function (s) { - if (!(s in valuesEnd) || s === 'origin') { - valuesEnd[s] = valuesStart[s]; - } - }); - } - } - - // All Component Functions - var svgTransformFunctions = { - prepareStart: getStartSvgTransform, - prepareProperty: prepareSvgTransform, - onStart: svgTransformOnStart, - crossCheck: svgTransformCrossCheck, - }; - - // Component Full - var svgTransform = { - component: 'svgTransformProperty', - property: 'svgTransform', - // subProperties: ['translate','rotate','skewX','skewY','scale'], - defaultOptions: { transformOrigin: '50% 50%' }, - defaultValue: { - translate: 0, rotate: 0, skewX: 0, skewY: 0, scale: 1, - }, - Interpolate: { numbers: numbers }, - functions: svgTransformFunctions, - - // export utils to globals for faster execution - Util: { parseStringOrigin: parseStringOrigin, parseTransformString: parseTransformString, parseTransformSVG: parseTransformSVG }, - }; - - /** - * A global namespace for 'addEventListener' string. - * @type {string} - */ - var addEventListener = 'addEventListener'; - - /** - * A global namespace for 'removeEventListener' string. - * @type {string} - */ - var removeEventListener = 'removeEventListener'; - - /** - * A global namespace for passive events support. - * @type {boolean} - */ - var supportPassive = (function () { - var result = false; - try { - var opts = Object.defineProperty({}, 'passive', { - get: function get() { - result = true; - return result; - }, - }); - document[addEventListener]('DOMContentLoaded', function wrap() { - document[removeEventListener]('DOMContentLoaded', wrap, opts); - }, opts); - } catch (e) { - throw Error('Passive events are not supported'); - } - - return result; - })(); - - // general event options - - /** - * A global namespace for most scroll event listeners. - */ - var passiveHandler = supportPassive ? { passive: true } : false; - - /** - * A global namespace for mouse hover events. - * @type {[string, string]} - */ - var mouseHoverEvents = ('onmouseleave' in document) ? ['mouseenter', 'mouseleave'] : ['mouseover', 'mouseout']; - - /** - * A global namespace for touch events support. - * @type {boolean} - */ - var supportTouch = 'ontouchstart' in window || 'msMaxTouchPoints' in navigator; - - // Component Util - // events preventing scroll - var touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel'; - - // true scroll container - // very important and specific to the component - var scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent) - ? document.body - : document.documentElement; - - /** - * Prevent further scroll events until scroll animation is over. - * @param {Event} e event object - */ - function preventScroll(e) { - if (this.scrolling) { e.preventDefault(); } - } - - /** - * Returns the scroll element / target. - * @returns {{el: Element, st: Element}} - */ - function getScrollTargets() { - var el = this.element; - return el === scrollContainer ? { el: document, st: document.body } : { el: el, st: el }; - } - - /** - * Toggles scroll prevention callback on scroll events. - * @param {string} action addEventListener / removeEventListener - * @param {Element} element target - */ - function toggleScrollEvents(action, element) { - element[action](mouseHoverEvents[0], preventScroll, passiveHandler); - element[action](touchOrWheel, preventScroll, passiveHandler); - } - - /** - * Action performed before scroll animation start. - */ - function scrollIn() { - var targets = getScrollTargets.call(this); - - if ('scroll' in this.valuesEnd && !targets.el.scrolling) { - targets.el.scrolling = 1; - toggleScrollEvents('addEventListener', targets.el); - targets.st.style.pointerEvents = 'none'; - } - } - /** - * Action performed when scroll animation ends. - */ - function scrollOut() { // prevent scroll when tweening scroll - var targets = getScrollTargets.call(this); - - if ('scroll' in this.valuesEnd && targets.el.scrolling) { - targets.el.scrolling = 0; - toggleScrollEvents('removeEventListener', targets.el); - targets.st.style.pointerEvents = ''; - } - } - - // Component Functions - /** - * * Sets the scroll target. - * * Adds the scroll prevention event listener. - * * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartScroll(tweenProp) { - // checking 0 will NOT add the render function - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) - ? scrollContainer : this.element; - scrollIn.call(this); - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.scrollTop = (numbers(a, b, v)) >> 0; - /* eslint-enable */ - }; - } - } - - /** - * Removes the scroll prevention event listener. - */ - function onCompleteScroll(/* tweenProp */) { - scrollOut.call(this); - } - - // Component Functions - /** - * Returns the current property computed style. - * @returns {number} computed style for property - */ - function getScroll() { - this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) - ? scrollContainer : this.element; - - return this.element === scrollContainer - ? (window.pageYOffset || scrollContainer.scrollTop) - : this.element.scrollTop; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareScroll(/* prop, */_, value) { - return parseInt(value, 10); - } - - // All Component Functions - var scrollFunctions = { - prepareStart: getScroll, - prepareProperty: prepareScroll, - onStart: onStartScroll, - onComplete: onCompleteScroll, - }; - - // Full Component - var ScrollProperty = { - component: 'scrollProperty', - property: 'scroll', - defaultValue: 0, - Interpolate: { numbers: numbers }, - functions: scrollFunctions, - // export stuff to global - Util: { - preventScroll: preventScroll, scrollIn: scrollIn, scrollOut: scrollOut, getScrollTargets: getScrollTargets, toggleScrollEvents: toggleScrollEvents, - }, - }; - - // Component Properties - var shadowProps$1 = ['boxShadow', 'textShadow']; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartShadow(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // let's start with the numbers | set unit | also determine inset - var params = []; - var unit = 'px'; - var sl = tweenProp === 'textShadow' ? 3 : 4; - var colA = sl === 3 ? a[3] : a[4]; - var colB = sl === 3 ? b[3] : b[4]; - var inset = (a[5] && a[5] !== 'none') || (b[5] && b[5] !== 'none') ? ' inset' : false; - - for (var i = 0; i < sl; i += 1) { - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - params.push(((numbers(a[i], b[i], v) * 1000 >> 0) / 1000) + unit); - } - // the final piece of the puzzle, the DOM update - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = inset - ? colors(colA, colB, v) + params.join(' ') + inset - : colors(colA, colB, v) + params.join(' '); - }; - } - } - var shadowPropOnStart$1 = {}; - shadowProps$1.forEach(function (x) { shadowPropOnStart$1[x] = onStartShadow; }); - - // Component Properties - var shadowProps = ['boxShadow', 'textShadow']; - - // Component Util - - /** - * Return the box-shadow / text-shadow tween object. - * * box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit - * * text-shadow: none | offset-x offset-y blur-radius color |initial|inherit - * * numbers must be floats and color must be rgb object - * - * @param {(number | string)[]} shadow an `Array` with shadow parameters - * @param {string} tweenProp the property name - * @returns {KUTE.shadowObject} the property tween object - */ - function processShadowArray(shadow, tweenProp) { - var newShadow; - - // [h-shadow, v-shadow, color] - if (shadow.length === 3) { - newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none']; - // [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color] - } else if (shadow.length === 4) { - newShadow = /inset|none/.test(shadow[3]) - ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]] - : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none']; - // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color] - } else if (shadow.length === 5) { - newShadow = /inset|none/.test(shadow[4]) - ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]] - : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none']; - // ideal [h-shadow, v-shadow, blur, spread, color, inset] - } else if (shadow.length === 6) { - newShadow = shadow; - } - - // make sure the values are ready to tween - for (var i = 0; i < 4; i += 1) { - newShadow[i] = parseFloat(newShadow[i]); - } - - // also the color must be a rgb object - newShadow[4] = trueColor(newShadow[4]); - - newShadow = tweenProp === 'boxShadow' - ? newShadow - : newShadow.filter(function (_, i) { return [0, 1, 2, 4].includes(i); }); - - return newShadow; - } - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getShadow(tweenProp/* , value */) { - var cssShadow = getStyleForProperty(this.element, tweenProp); - // '0px 0px 0px 0px rgb(0,0,0)' - return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow) - ? defaultValues[tweenProp] - : cssShadow; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} propValue the property value - * @returns {KUTE.shadowObject} the property tween object - */ - function prepareShadow(tweenProp, propValue) { - // [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset] - // parseProperty for boxShadow, builds basic structure with ready to tween values - var value = propValue; - if (typeof value === 'string') { - var inset = 'none'; - // a full RegEx for color strings - var colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi; - var currentColor = value.match(colRegEx); - - // make sure to always have the inset last if possible - inset = /inset/.test(value) ? 'inset' : inset; - value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g, '') : value; - - // also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset" - value = value.replace(currentColor[0], '').split(' ').concat([currentColor[0].replace(/\s/g, '')], [inset]); - - value = processShadowArray(value, tweenProp); - } else if (value instanceof Array) { - value = processShadowArray(value, tweenProp); - } - - return value; - } - - var shadowPropOnStart = {}; - shadowProps.forEach(function (x) { shadowPropOnStart[x] = onStartShadow; }); - - // All Component Functions - var shadowFunctions = { - prepareStart: getShadow, - prepareProperty: prepareShadow, - onStart: shadowPropOnStart, - }; - - // Component Full - var ShadowProperties = { - component: 'shadowProperties', - properties: shadowProps, - defaultValues: { - boxShadow: '0px 0px 0px 0px rgb(0,0,0)', - textShadow: '0px 0px 0px rgb(0,0,0)', - }, - Interpolate: { numbers: numbers, colors: colors }, - functions: shadowFunctions, - Util: { processShadowArray: processShadowArray, trueColor: trueColor }, - }; - - // Component Properties - var textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing']; - var textOnStart$1 = {}; - - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function textPropOnStart(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = units(a.v, b.v, b.u, v); - }; - } - } - - textProperties.forEach(function (tweenProp) { - textOnStart$1[tweenProp] = textPropOnStart; - }); - - // Component Properties - var textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing']; - var textOnStart = {}; - - // Component Functions - textProps.forEach(function (tweenProp) { - textOnStart[tweenProp] = textPropOnStart; - }); - - /** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} computed style for property - */ - function getTextProp(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareTextProp(/* prop */_, value) { - return trueDimension(value); - } - - // All Component Functions - var textPropFunctions = { - prepareStart: getTextProp, - prepareProperty: prepareTextProp, - onStart: textOnStart, - }; - - // Component Full - var TextProperties = { - component: 'textProperties', - category: 'textProperties', - properties: textProps, - defaultValues: { - fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0, - }, - Interpolate: { units: units }, - functions: textPropFunctions, - Util: { trueDimension: trueDimension }, - }; - - // Component Values - var lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase - var upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase - var nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols - var numeric = String('0123456789').split(''); // numeric - var alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric - var allTypes = alphaNumeric.concat(nonAlpha); // all caracters - - var charSet = { - alpha: lowerCaseAlpha, // lowercase - upper: upperCaseAlpha, // uppercase - symbols: nonAlpha, // symbols - numeric: numeric, - alphanumeric: alphaNumeric, - all: allTypes, - }; - - // Component Functions - var onStartWrite = { - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - text: function text(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - var chars = this._textChars; - var charsets = charSet[defaultOptions$1.textChars]; - - if (chars in charSet) { - charsets = charSet[chars]; - } else if (chars && chars.length) { - charsets = chars; - } - - KEC[tweenProp] = function (elem, a, b, v) { - var initialText = ''; - var endText = ''; - var finalText = b === '' ? ' ' : b; - var firstLetterA = a.substring(0); - var firstLetterB = b.substring(0); - /* eslint-disable */ - var pointer = charsets[(Math.random() * charsets.length) >> 0]; - - if (a === ' ') { - endText = firstLetterB - .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0); - elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText; - } else if (b === ' ') { - initialText = firstLetterA - .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0); - elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText; - } else { - initialText = firstLetterA - .substring(firstLetterA.length, - Math.min(v * firstLetterA.length, firstLetterA.length) >> 0); - endText = firstLetterB - .substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0); - elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText; - } - /* eslint-enable */ - }; - } - }, - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - number: function number(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { // numbers can be 0 - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.innerHTML = numbers(a, b, v) >> 0; - /* eslint-enable */ - }; - } - }, - }; - - // Component Util - // utility for multi-child targets - // wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class - function wrapContentsSpan(el, classNAME) { - var assign; - - var textWriteWrapper; - var newElem; - if (typeof (el) === 'string') { - newElem = document.createElement('SPAN'); - newElem.innerHTML = el; - newElem.className = classNAME; - return newElem; - } - if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) { - var elementInnerHTML = el.innerHTML; - textWriteWrapper = document.createElement('SPAN'); - textWriteWrapper.className = classNAME; - textWriteWrapper.innerHTML = elementInnerHTML; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - el.appendChild(textWriteWrapper); - el.innerHTML = textWriteWrapper.outerHTML; - /* eslint-enable no-param-reassign -- impossible to satisfy */ - } else if (el.children.length && el.children[0].className === classNAME) { - (assign = el.children, textWriteWrapper = assign[0]); - } - return textWriteWrapper; - } - - function getTextPartsArray(el, classNAME) { - var elementsArray = []; - var len = el.children.length; - if (len) { - var textParts = []; - var remainingMarkup = el.innerHTML; - var wrapperParts; - - for (var i = 0, currentChild = (void 0), childOuter = (void 0), unTaggedContent = (void 0); i < len; i += 1) { - currentChild = el.children[i]; - childOuter = currentChild.outerHTML; - wrapperParts = remainingMarkup.split(childOuter); - - if (wrapperParts[0] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0], ''); - } else if (wrapperParts[1] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], ''); - } - - if (!currentChild.classList.contains(classNAME)) { currentChild.classList.add(classNAME); } - textParts.push(currentChild); - remainingMarkup = remainingMarkup.replace(childOuter, ''); - } - - if (remainingMarkup !== '') { - var unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME); - textParts.push(unTaggedRemaining); - } - - elementsArray = elementsArray.concat(textParts); - } else { - elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]); - } - return elementsArray; - } - - function setSegments(target, newText) { - var oldTargetSegs = getTextPartsArray(target, 'text-part'); - var newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part'); - - /* eslint-disable no-param-reassign */ - target.innerHTML = ''; - target.innerHTML += oldTargetSegs.map(function (s) { s.className += ' oldText'; return s.outerHTML; }).join(''); - target.innerHTML += newTargetSegs.map(function (s) { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join(''); - /* eslint-enable no-param-reassign */ - - return [oldTargetSegs, newTargetSegs]; - } - - function createTextTweens(target, newText, ops) { - if (target.playing) { return false; } - - var options = ops || {}; - options.duration = 1000; - - if (ops.duration === 'auto') { - options.duration = 'auto'; - } else if (Number.isFinite(ops.duration * 1)) { - options.duration = ops.duration * 1; - } - - var TweenContructor = connect.tween; - var segs = setSegments(target, newText); - var oldTargetSegs = segs[0]; - var newTargetSegs = segs[1]; - var oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); - var newTargets = [].slice.call(target.getElementsByClassName('newText')); - - var textTween = []; - var totalDelay = 0; - - textTween = textTween.concat(oldTargets.map(function (el, i) { - options.duration = options.duration === 'auto' - ? oldTargetSegs[i].innerHTML.length * 75 - : options.duration; - options.delay = totalDelay; - options.onComplete = null; - - totalDelay += options.duration; - return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options); - })); - textTween = textTween.concat(newTargets.map(function (el, i) { - function onComplete() { - /* eslint-disable no-param-reassign */ - target.innerHTML = newText; - target.playing = false; - /* eslint-enable no-param-reassign */ - } - - options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; - options.delay = totalDelay; - options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null; - totalDelay += options.duration; - - return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options); - })); - - textTween.start = function startTweens() { - if (!target.playing) { - textTween.forEach(function (tw) { return tw.start(); }); - // eslint-disable-next-line no-param-reassign - target.playing = true; - } - }; - - return textTween; - } - - // Component Functions - /** - * Returns the current element `innerHTML`. - * @returns {string} computed style for property - */ - function getWrite(/* tweenProp, value */) { - return this.element.innerHTML; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number | string} the property tween object - */ - function prepareText(tweenProp, value) { - if (tweenProp === 'number') { - return parseFloat(value); - } - // empty strings crash the update function - return value === '' ? ' ' : value; - } - - // All Component Functions - var textWriteFunctions = { - prepareStart: getWrite, - prepareProperty: prepareText, - onStart: onStartWrite, - }; - - // Full Component - var TextWrite = { - component: 'textWriteProperties', - category: 'textWrite', - properties: ['text', 'number'], - defaultValues: { text: ' ', number: '0' }, - defaultOptions: { textChars: 'alpha' }, - Interpolate: { numbers: numbers }, - functions: textWriteFunctions, - // export to global for faster execution - Util: { charSet: charSet, createTextTweens: createTextTweens }, - }; - - /** - * Array Interpolation Function. - * - * @param {number[]} a start array - * @param {number[]} b end array - * @param {number} v progress - * @returns {number[]} the resulting array - */ - function arrays(a, b, v) { - var result = []; var length = b.length; - for (var i = 0; i < length; i += 1) { - // eslint-disable-next-line no-bitwise - result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0) / 1000; - } - return result; - } - - // Component special - // this component is restricted to modern browsers only - var CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null; - - // Component Functions - var onStartTransform = { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - transform: function transform(tweenProp) { - if (CSS3Matrix && this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - var matrix = new CSS3Matrix(); - var tObject = {}; - - Object.keys(b).forEach(function (p) { - tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v); - }); - - // set perspective - if (tObject.perspective) { matrix.m34 = -1 / tObject.perspective; } - - // set translate - matrix = tObject.translate3d - ? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2]) - : matrix; - - // set rotation - matrix = tObject.rotate3d - ? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2]) - : matrix; - - // set skew - if (tObject.skew) { - matrix = tObject.skew[0] ? matrix.skewX(tObject.skew[0]) : matrix; - matrix = tObject.skew[1] ? matrix.skewY(tObject.skew[1]) : matrix; - } - - // set scale - matrix = tObject.scale3d - ? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2]) - : matrix; - - // set element style - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = matrix.toString(); - }; - } - }, - /** - * onStartTransform.CSS3Matrix - * - * Sets the update function for the property. - * @param {string} prop the property name - */ - CSS3Matrix: function CSS3Matrix$1(prop) { - if (CSS3Matrix && this.valuesEnd.transform) { - if (!KEC[prop]) { KEC[prop] = CSS3Matrix; } - } - }, - }; - - // Component name - var matrixComponent = 'transformMatrix'; - - // Component Functions - /** - * Returns the current transform object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.transformMObject} transform object - */ - function getTransform(/* tweenProp, */_, value) { - var transformObject = {}; - var currentValue = this.element[matrixComponent]; - - if (currentValue) { - Object.keys(currentValue).forEach(function (vS) { - transformObject[vS] = currentValue[vS]; - }); - } else { - Object.keys(value).forEach(function (vE) { - transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE]; - }); - } - return transformObject; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformMObject} the property tween object - */ - function prepareTransform(/* tweenProp, */_, value) { - if (typeof (value) === 'object' && !value.length) { - var pv; - var transformObject = {}; - var translate3dObj = {}; - var rotate3dObj = {}; - var scale3dObj = {}; - var skewObj = {}; - var axis = [{ translate3d: translate3dObj }, - { rotate3d: rotate3dObj }, - { skew: skewObj }, - { scale3d: scale3dObj }]; - - Object.keys(value).forEach(function (prop) { - if (/3d/.test(prop) && typeof (value[prop]) === 'object' && value[prop].length) { - pv = value[prop].map(function (v) { return (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)) { - var 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; - } - var 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(function (v) { return parseInt(v, 10) || 0; }); - transformObject[prop] = [pv[0] || 0, pv[1] || 0]; - } else { // perspective - transformObject[prop] = parseInt(value[prop], 10); - } - }); - - axis.forEach(function (o) { - var tp = Object.keys(o)[0]; - var tv = o[tp]; - if (Object.keys(tv).length && !transformObject[tp]) { - if (tp === 'scale3d') { - transformObject[tp] = [tv.x || 1, tv.y || 1, tv.z || 1]; - } else if (tp === 'skew') { - transformObject[tp] = [tv.x || 0, tv.y || 0]; - } else { // translate | rotate - transformObject[tp] = [tv.x || 0, tv.y || 0, tv.z || 0]; - } - } - }); - return transformObject; - } // string | array - // if ( typeof (value) === 'object' && value.length ) { - // } else if ( typeof (value) === string && value.includes('matrix')) { - // decompose matrix to object - throw Error(("KUTE.js - \"" + value + "\" is not valid/supported transform function")); - } - - /** - * Sets the end values for the next `to()` method call. - * @param {string} tweenProp the property name - */ - function onCompleteTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - this.element[matrixComponent] = Object.assign({}, this.valuesEnd[tweenProp]); - } - } - - /** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ - function crossCheckTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } - } - - // All Component Functions - var matrixFunctions = { - prepareStart: getTransform, - prepareProperty: prepareTransform, - onStart: onStartTransform, - onComplete: onCompleteTransform, - crossCheck: crossCheckTransform, - }; - - // Component Full Object - var matrixTransform = { - component: matrixComponent, - property: 'transform', - /* subProperties: [ - 'perspective', 'translate3d', 'translateX', 'translateY', 'translateZ', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', - 'skew','skewX','skewY', - 'scale3d', 'scaleX', 'scaleY', 'scaleZ'], */ - defaultValue: { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - skew: [0, 0], - skewX: 0, - skewY: 0, - scale3d: [1, 1, 1], - scaleX: 1, - scaleY: 1, - scaleZ: 1, - }, - functions: matrixFunctions, - Interpolate: { - perspective: numbers, - translate3d: arrays, - rotate3d: arrays, - skew: arrays, - scale3d: arrays, - }, - }; - - var Components = { - BackgroundPosition: BackgroundPosition, - BorderRadius: BorderRadius, - BoxModel: BoxModel, - ClipProperty: ClipProperty, - ColorProperties: colorProperties, - FilterEffects: filterEffects, - HTMLAttributes: htmlAttributes, - OpacityProperty: OpacityProperty, - SVGDraw: SvgDrawProperty, - SVGCubicMorph: svgCubicMorph, - SVGTransform: svgTransform, - ScrollProperty: ScrollProperty, - ShadowProperties: ShadowProperties, - TextProperties: TextProperties, - TextWriteProperties: TextWrite, - MatrixTransform: matrixTransform, - }; - - // init components - Object.keys(Components).forEach(function (component) { - var compOps = Components[component]; - Components[component] = new AnimationDevelopment(compOps); - }); - - var version = "2.2.3"; - - // @ts-ignore - - /** - * A global namespace for library version. - * @type {string} - */ - var Version = version; - - var indexExtra = { - Animation: AnimationDevelopment, - Components: Components, - - // Tween Interface - Tween: TweenExtra, - fromTo: fromTo, - to: to, - // Tween Collection - TweenCollection: TweenCollection, - ProgressBar: ProgressBar, - allFromTo: allFromTo, - allTo: allTo, - // Tween Interface - - Objects: Objects, - Util: Util, - Easing: Easing, - CubicBezier: CubicBezier, - Render: Render, - Interpolate: interpolate, - Process: Process, - Internals: internals, - Selector: selector, - Version: Version, - }; - - return indexExtra; - -})); diff --git a/demo/src/kute-extra.min.js b/demo/src/kute-extra.min.js deleted file mode 100644 index b592e58..0000000 --- a/demo/src/kute-extra.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// KUTE.js Extra v2.2.3 | thednp © 2021 | MIT-License -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=e()}(this,(function(){"use strict";var t=function(t,e,n,r,a){var i=this;this.cx=3*t,this.bx=3*(n-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(r-e)-this.cy,this.ay=1-this.cy-this.by;var o=function(t){return i.sampleCurveY(i.solveCurveX(t))};return Object.defineProperty(o,"name",{writable:!0}),o.name=a||"cubic-bezier("+[t,e,n,r]+")",o};t.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},t.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},t.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},t.prototype.solveCurveX=function(t){var e,n,r,a,i,o,s=1e-5;for(r=t,o=0;o<32;o+=1){if(a=this.sampleCurveX(r)-t,Math.abs(a)(n=1))return n;for(;ea?e=r:n=r,r=.5*(n-e)+e}return r};Object.assign(t,{Version:"1.0.18"});var e={},n=[],r="undefined"!=typeof global?global:"undefined"!=typeof window?window.self:{},a={},i={},o="undefined"==typeof self&&"undefined"!=typeof process&&process.hrtime?function(){var t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:"undefined"!=typeof self&&void 0!==self.performance&&void 0!==self.performance.now?self.performance.now.bind(self.performance):"undefined"!=typeof Date&&Date.now?Date.now:function(){return(new Date).getTime()},s={};s.now=o;var u=0,c=function(t){for(var e=0;e1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.map((function(t){return t.start()})),!1)},I.tween=V;var N=function(t){function n(){for(var e=this,n=[],r=arguments.length;r--;)n[r]=arguments[r];t.apply(this,n),this.valuesStart={},this.valuesEnd={};var a=n.slice(1),i=a[0],o=a[1],s=a[2];return _.call(this,o,"end"),this._resetStart?this.valuesStart=i:_.call(this,i,"start"),this._resetStart||Object.keys(m).forEach((function(t){Object.keys(m[t]).forEach((function(n){m[t][n].call(e,n)}))})),this.paused=!1,this._pauseTime=null,this._repeat=s.repeat||d.repeat,this._repeatDelay=s.repeatDelay||d.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=s.yoyo||d.yoyo,this._reversed=!1,this}return t&&(n.__proto__=t),n.prototype=Object.create(t&&t.prototype),n.prototype.constructor=n,n.prototype.start=function(e){var n=this;return this._resetStart&&(this.valuesStart=this._resetStart,C.call(this),Object.keys(m).forEach((function(t){Object.keys(m[t]).forEach((function(e){m[t][e].call(n,e)}))}))),this.paused=!1,this._yoyo&&Object.keys(this.valuesEnd).forEach((function(t){n.valuesRepeat[t]=n.valuesStart[t]})),t.prototype.start.call(this,e),this},n.prototype.stop=function(){return t.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return t.prototype.close.call(this),this._repeatOption>0&&(this._repeat=this._repeatOption),this._yoyo&&!0===this._reversed&&(this.reverse(),this._reversed=!1),this},n.prototype.resume=function(){return this.paused&&this.playing&&(this.paused=!1,void 0!==this._onResume&&this._onResume.call(this),L.call(this),this._startTime+=e.Time()-this._pauseTime,x(this),u||c()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(S(this),this.paused=!0,this._pauseTime=e.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){var t=this;Object.keys(this.valuesEnd).forEach((function(e){var n=t.valuesRepeat[e];t.valuesRepeat[e]=t.valuesEnd[e],t.valuesEnd[e]=n,t.valuesStart[e]=t.valuesRepeat[e]}))},n.prototype.update=function(t){var n,r=this,a=void 0!==t?t:e.Time();if(a1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(Number.isFinite(this._repeat)&&(this._repeat-=1),this._startTime=a,Number.isFinite(this._repeat)&&this._yoyo&&!this._reversed&&(this._startTime+=this._repeatDelay),this._yoyo&&(this._reversed=!this._reversed,this.reverse()),!0):(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.forEach((function(t){return t.start()})),!1))},n}(V);I.tween=N;var R=function(t){function e(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return t.apply(this,e),this}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.on=function(t,e){return["start","stop","update","complete","pause","resume"].indexOf(t)>-1&&(this["_on"+(t.charAt(0).toUpperCase()+t.slice(1))]=e),this},e.prototype.option=function(t,e){return this["_"+t]=e,this},e}(N);I.tween=R;var U=function(t,e,n,r){var a=this,i=I.tween;this.tweens=[];var o=r||{};o.delay=o.delay||d.delay;var s=[];return Array.from(t).forEach((function(t,r){if(s[r]=o||{},s[r].delay=r>0?o.delay+(o.offset||d.offset):o.delay,!(t instanceof Element))throw Error("KUTE - "+t+" is not instanceof Element");a.tweens.push(new i(t,e,n,s[r]))})),this.length=this.tweens.length,this};U.prototype.start=function(t){var n=void 0===t?e.Time():t;return this.tweens.map((function(t){return t.start(n)})),this},U.prototype.stop=function(){return this.tweens.map((function(t){return t.stop()})),this},U.prototype.pause=function(){return this.tweens.map((function(t){return t.pause()})),this},U.prototype.resume=function(){return this.tweens.map((function(t){return t.resume()})),this},U.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof U)e.chain(t.tweens);else{if(!(t instanceof I.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},U.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},U.prototype.removeTweens=function(){this.tweens=[]},U.prototype.getMaxDuration=function(){var t=[];return this.tweens.forEach((function(e){t.push(e._duration+e._delay+e._repeat*e._repeatDelay)})),Math.max(t)};var F=function(t,e){var n;if(this.element=P(t),this.element.tween=e,this.element.tween.toolbar=this.element,this.element.toolbar=this,n=this.element.parentNode.getElementsByTagName("OUTPUT"),this.element.output=n[0],!(this.element instanceof HTMLInputElement))throw TypeError("Target element is not [HTMLInputElement]");if("range"!==this.element.type)throw TypeError("Target element is not a range input");if(!(e instanceof I.tween))throw TypeError("tween parameter is not ["+I.tween+"]");this.element.setAttribute("value",0),this.element.setAttribute("min",0),this.element.setAttribute("max",1),this.element.setAttribute("step",1e-4),this.element.tween._onUpdate=this.updateBar,this.element.addEventListener("mousedown",this.downAction,!1)};F.prototype.updateBar=function(){var t,n=this.toolbar.output;(t=this.paused?this.toolbar.value:(e.Time()-this._startTime)/this._duration)>.9999&&(t=1),t<.01&&(t=0);var r=this._reversed?1-t:t;this.toolbar.value=r,n&&(n.value=(1e4*r>>0)/100+"%")},F.prototype.toggleEvents=function(t){this.element[t+"EventListener"]("mousemove",this.moveAction,!1),this.element[t+"EventListener"]("mouseup",this.upAction,!1)},F.prototype.updateTween=function(){var t=(this.tween._reversed?1-this.value:this.value)*this.tween._duration-1e-4;this.tween._startTime=0,this.tween.update(t)},F.prototype.moveAction=function(){this.toolbar.updateTween.call(this)},F.prototype.downAction=function(){this.tween.playing||this.tween.start(),this.tween.paused||(this.tween.pause(),this.toolbar.toggleEvents("add"),e.Tick=cancelAnimationFrame(e.Ticker))},F.prototype.upAction=function(){this.tween.paused&&(this.tween.paused&&this.tween.resume(),this.tween._startTime=e.Time()-(this.tween._reversed?1-this.value:this.value)*this.tween._duration,this.toolbar.toggleEvents("remove"),e.Tick=requestAnimationFrame(e.Ticker))};var D=I.tween;var H=I.tween;var q=function(t){try{if(t.component in h)throw Error("KUTE - "+t.component+" already registered");if(t.property in f)throw Error("KUTE - "+t.property+" already registered")}catch(t){throw Error(t)}var e=this,n=t.component,r={prepareProperty:v,prepareStart:g,onStart:i,onComplete:y,crossCheck:m},o=t.category,s=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;return h[n]=t.properties||t.subProperties||t.property,"defaultValue"in t?(f[s]=t.defaultValue,e.supports=s+" property"):t.defaultValues&&(Object.keys(t.defaultValues).forEach((function(e){f[e]=t.defaultValues[e]})),e.supports=(u||s)+" "+(s||o)+" properties"),t.defaultOptions&&Object.assign(d,t.defaultOptions),t.functions&&Object.keys(r).forEach((function(e){e in t.functions&&("function"==typeof t.functions[e]?(r[e][n]||(r[e][n]={}),r[e][n][o||s]||(r[e][n][o||s]=t.functions[e])):Object.keys(t.functions[e]).forEach((function(a){r[e][n]||(r[e][n]={}),r[e][n][a]||(r[e][n][a]=t.functions[e][a])})))})),t.Interpolate&&(Object.keys(t.Interpolate).forEach((function(e){var n=t.Interpolate[e];"function"!=typeof n||a[e]?Object.keys(n).forEach((function(t){"function"!=typeof n[t]||a[e]||(a[e]=n[t])})):a[e]=n})),b[n]=t.Interpolate),t.Util&&Object.keys(t.Util).forEach((function(e){E[e]||(E[e]=t.Util[e])})),e},B=function(t){function e(e){t.call(this,e);var n=this,r={prepareProperty:v,prepareStart:g,onStart:i,onComplete:y,crossCheck:m},o=e.category,s=e.property,u=e.properties&&e.properties.length||e.subProperties&&e.subProperties.length;return"defaultValue"in e?(n.supports=s+" property",n.defaultValue=(""+e.defaultValue).length?"YES":"not set or incorrect"):e.defaultValues&&(n.supports=(u||s)+" "+(s||o)+" properties",n.defaultValues=Object.keys(e.defaultValues).length===u?"YES":"Not set or incomplete"),e.defaultOptions&&(n.extends=[],Object.keys(e.defaultOptions).forEach((function(t){n.extends.push(t)})),n.extends.length?n.extends="with <"+n.extends.join(", ")+"> new option(s)":delete n.extends),e.functions&&(n.interface=[],n.render=[],n.warning=[],Object.keys(r).forEach((function(t){t in e.functions?("prepareProperty"===t&&n.interface.push("fromTo()"),"prepareStart"===t&&n.interface.push("to()"),"onStart"===t&&(n.render="can render update")):("prepareProperty"===t&&n.warning.push("fromTo()"),"prepareStart"===t&&n.warning.push("to()"),"onStart"===t&&(n.render="no function to render update"))})),n.interface.length?n.interface=(o||s)+" can use ["+n.interface.join(", ")+"] method(s)":delete n.uses,n.warning.length?n.warning=(o||s)+" can't use ["+n.warning.join(", ")+"] method(s) because values aren't processed":delete n.warning),e.Interpolate?(n.uses=[],n.adds=[],Object.keys(e.Interpolate).forEach((function(t){var r=e.Interpolate[t];"function"==typeof r?(a[t]||n.adds.push(""+t),n.uses.push(""+t)):Object.keys(r).forEach((function(e){"function"!=typeof r[e]||a[t]||n.adds.push(""+e),n.uses.push(""+e)}))})),n.uses.length?n.uses="["+n.uses.join(", ")+"] interpolation function(s)":delete n.uses,n.adds.length?n.adds="new ["+n.adds.join(", ")+"] interpolation function(s)":delete n.adds):n.critical="For "+(s||o)+" no interpolation function[s] is set",e.Util&&(n.hasUtil=Object.keys(e.Util).join(",")),n}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(q);function Q(t,e,n){return+t+(e-t)*n}var z=function(t,e){for(var n,r=parseInt(t,10)||0,a=["px","%","deg","rad","em","rem","vh","vw"],i=0;i>0)/100+"% "+(100*Q(n[1],r[1],a)>>0)/100+"%"})}},Y={component:"backgroundPositionProp",property:"backgroundPosition",defaultValue:[50,50],Interpolate:{numbers:Q},functions:X,Util:{trueDimension:z}};function W(t,e,n,r){return+t+(e-t)*r+n}function $(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=W(n.v,r.v,r.u,a)})}var G={};["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"].forEach((function(t){G[t]=$}));var Z=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],K={};Z.forEach((function(t){K[t]=0}));var J={};Z.forEach((function(t){J[t]=$}));var tt={component:"borderRadiusProperties",category:"borderRadius",properties:Z,defaultValues:K,Interpolate:{units:W},functions:{prepareStart:function(t){return M(this.element,t)||f[t]},prepareProperty:function(t,e){return z(e)},onStart:J},Util:{trueDimension:z}};function et(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=(a>.99||a<.01?(10*Q(n,r,a)>>0)/10:Q(n,r,a)>>0)+"px"})}var nt={};["top","left","width","height"].forEach((function(t){nt[t]=et}));var rt=["top","left","width","height","right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","paddingTop","paddingBottom","paddingLeft","paddingRight","margin","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],at={};rt.forEach((function(t){at[t]=0}));var it={};rt.forEach((function(t){it[t]=et}));var ot={component:"boxModelProperties",category:"boxModel",properties:rt,defaultValues:at,Interpolate:{numbers:Q},functions:{prepareStart:function(t){return M(this.element,t)||f[t]},prepareProperty:function(t,e){var n=z(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:it}};var st={prepareStart:function(t){var e=this.element,n=M(e,t),r=M(e,"width"),a=M(e,"height");return/rect/.test(n)?n:[0,r,a,0]},prepareProperty:function(t,e){if(e instanceof Array)return e.map((function(t){return z(t)}));var n=e.replace(/rect|\(|\)/g,"");return(n=/,/g.test(n)?n.split(","):n.split(/\s/)).map((function(t){return z(t)}))},onStart:function(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(t,e,n,r){for(var a=0,i=[];a<4;a+=1){var o=e[a].v,s=n[a].v,u=n[a].u||"px";i[a]=(100*Q(o,s,r)>>0)/100+u}t.style.clip="rect("+i+")"})}},ut={component:"clipProperty",property:"clip",defaultValue:[0,0,0,0],Interpolate:{numbers:Q},functions:st,Util:{trueDimension:z}},ct=function(t){var e;if(/rgb|rgba/.test(t)){var n=t.replace(/\s|\)/,"").split("(")[1].split(","),r=n[3]?n[3]:null;r||(e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10)}),e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10),a:parseFloat(r)}}if(/^#/.test(t)){var a=function(t){var e=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r})),n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return n?{r:parseInt(n[1],16),g:parseInt(n[2],16),b:parseInt(n[3],16)}:null}(t);e={r:a.r,g:a.g,b:a.b}}if(/transparent|none|initial|inherit/.test(t)&&(e={r:0,g:0,b:0,a:0}),!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var o=getComputedStyle(i,null).color;o=/rgb/.test(o)?o.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",e={r:parseInt(o[0],10),g:parseInt(o[1],10),b:parseInt(o[2],10)}}return e};function lt(t,e,n){var r={},a=",";return Object.keys(e).forEach((function(a){"a"!==a?r[a]=Q(t[a],e[a],n)>>0||0:t[a]&&e[a]&&(r[a]=(100*Q(t[a],e[a],n)>>0)/100)})),r.a?"rgba("+r.r+a+r.g+a+r.b+a+r.a+")":"rgb("+r.r+a+r.g+a+r.b+")"}function pt(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=lt(n,r,a)})}var ht={};["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"].forEach((function(t){ht[t]=pt}));var ft=["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],dt={};ft.forEach((function(t){dt[t]="#000"}));var vt={};ft.forEach((function(t){vt[t]=pt}));var gt={component:"colorProperties",category:"colors",properties:ft,defaultValues:dt,Interpolate:{numbers:Q,colors:lt},functions:{prepareStart:function(t){return M(this.element,t)||f[t]},prepareProperty:function(t,e){return ct(e)},onStart:vt},Util:{trueColor:ct}};function mt(t,e,n){for(var r=[],a=0;a<3;a+=1)r[a]=(100*Q(t[a],e[a],n)>>0)/100+"px";return"drop-shadow("+r.concat(lt(t[3],e[3],n)).join(" ")+")"}function yt(t){return t.replace("-r","R").replace("-s","S")}function bt(t){var e;3===t.length?e=[t[0],t[1],0,t[2]]:4===t.length&&(e=[t[0],t[1],t[2],t[3]]);for(var n=0;n<3;n+=1)e[n]=parseFloat(e[n]);return e[3]=ct(e[3]),e}function wt(t){var e={},n=t.match(/(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g),r="none"!==t?n:"none";if(r instanceof Array)for(var a=0,i=r.length;a>0)/100+"%)":"")+(n.blur||r.blur?"blur("+(100*Q(n.blur,r.blur,a)>>0)/100+"em)":"")+(n.saturate||r.saturate?"saturate("+(100*Q(n.saturate,r.saturate,a)>>0)/100+"%)":"")+(n.invert||r.invert?"invert("+(100*Q(n.invert,r.invert,a)>>0)/100+"%)":"")+(n.grayscale||r.grayscale?"grayscale("+(100*Q(n.grayscale,r.grayscale,a)>>0)/100+"%)":"")+(n.hueRotate||r.hueRotate?"hue-rotate("+(100*Q(n.hueRotate,r.hueRotate,a)>>0)/100+"deg)":"")+(n.sepia||r.sepia?"sepia("+(100*Q(n.sepia,r.sepia,a)>>0)/100+"%)":"")+(n.brightness||r.brightness?"brightness("+(100*Q(n.brightness,r.brightness,a)>>0)/100+"%)":"")+(n.contrast||r.contrast?"contrast("+(100*Q(n.contrast,r.contrast,a)>>0)/100+"%)":"")+(n.dropShadow||r.dropShadow?mt(n.dropShadow,r.dropShadow,a):"")})},crossCheck:function(t){var e=this;this.valuesEnd[t]&&Object.keys(this.valuesStart[t]).forEach((function(n){e.valuesEnd[t][n]||(e.valuesEnd[t][n]=e.valuesStart[t][n])}))}},xt={component:"filterEffects",property:"filter",defaultValue:{opacity:100,blur:0,saturate:100,grayscale:0,brightness:100,contrast:100,sepia:0,invert:0,hueRotate:0,dropShadow:[0,0,0,{r:0,g:0,b:0}],url:""},Interpolate:{opacity:Q,blur:Q,saturate:Q,grayscale:Q,brightness:Q,contrast:Q,sepia:Q,invert:Q,hueRotate:Q,dropShadow:{numbers:Q,colors:lt,dropshadow:mt}},functions:Et,Util:{parseDropShadow:bt,parseFilterString:wt,replaceDashNamespace:yt,trueColor:ct}},St={},kt="htmlAttributes",Tt=["fill","stroke","stop-color"];function Ot(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var Mt={prepareStart:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(t){var e=Ot(t).replace(/_+[a-z]+/,""),a=n.element.getAttribute(e);r[e]=Tt.includes(e)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(t)?1:0)})),r},prepareProperty:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(a){var o=Ot(a),s=/(%|[a-z]+)$/,u=n.element.getAttribute(o.replace(/_+[a-z]+/,""));if(Tt.includes(o))i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in St)&&(St[e]=function(t,e,n,r,a){t.setAttribute(e,lt(n,r,a))})},r[o]=ct(e[a])||f.htmlAttributes[a];else if(null!==u&&s.test(u)){var c=z(u).u||z(e[a]).u,l=/%/.test(c)?"_percent":"_"+c;i.htmlAttributes[o+l]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in St)&&(St[e]=function(t,e,n,r,a){var i=e.replace(l,"");t.setAttribute(i,(1e3*Q(n.v,r.v,a)>>0)/1e3+r.u)})},r[o+l]=z(e[a])}else s.test(e[a])&&null!==u&&(null===u||s.test(u))||(i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in St)&&(St[e]=function(t,e,n,r,a){t.setAttribute(e,(1e3*Q(n,r,a)>>0)/1e3)})},r[o]=parseFloat(e[a]))})),r},onStart:{attr:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,n,r,a){Object.keys(r).forEach((function(i){e.attributes[i](t,i,n[i],r[i],a)}))})},attributes:function(t){!e[t]&&this.valuesEnd.attr&&(e[t]=St)}}},_t={component:kt,property:"attr",subProperties:["fill","stroke","stop-color","fill-opacity","stroke-opacity"],defaultValue:{fill:"rgb(0,0,0)",stroke:"rgb(0,0,0)","stop-color":"rgb(0,0,0)",opacity:1,"stroke-opacity":1,"fill-opacity":1},Interpolate:{numbers:Q,colors:lt},functions:Mt,Util:{replaceUppercase:Ot,trueColor:ct,trueDimension:z}};var Ct={prepareStart:function(t){return M(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=(1e3*Q(n,r,a)>>0)/1e3})}},jt={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:Q},functions:Ct};function It(t,e){return parseFloat(t)/100*e}function At(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Pt(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");return 2!==e.length||Number.isNaN(1*e[0])||Number.isNaN(1*e[1])?0:[parseFloat(e[0]),parseFloat(e[1])]},a=function(t,e){return void 0!==t&&void 0!==e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var i=0;i>0)/100,i=0-(100*Q(e.s,n.s,r)>>0)/100,o=(100*Q(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=i+"px",t.style.strokeDasharray=(100*(o<1?0:o)>>0)/100+"px, "+a+"px"})}},Dt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:Q},functions:Ft,Util:{getRectLength:At,getPolyLength:Pt,getLineLength:Lt,getCircleLength:Vt,getEllipseLength:Nt,getTotalLength:Rt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Ut,percent:It}},Ht={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function qt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;for("m"===n&&r.length>2&&(t.segments.push([e,r[0],r[1]]),r=r.slice(2),n="l",e="m"===e?"l":"L");r.length>=Ht[n]&&(t.segments.push([e].concat(r.splice(0,Ht[n]))),Ht[n]););}var Bt="Invalid path value";function Qt(t){var e=t.index,n=t.pathValue.charCodeAt(e);return 48===n?(t.param=0,void(t.index+=1)):49===n?(t.param=1,void(t.index+=1)):void(t.err=Bt+': invalid Arc flag "'+n+'", expecting 0 or 1 at index '+e)}function zt(t){return t>=48&&t<=57}function Xt(t){var e,n=t.max,r=t.pathValue,a=t.index,i=a,o=!1,s=!1,u=!1,c=!1;if(i>=n)t.err=Bt+" at "+i+": missing param "+r[i];else if(43!==(e=r.charCodeAt(i))&&45!==e||(e=(i+=1)=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index+=1}function Wt(t){return t>=48&&t<=57||43===t||45===t||46===t}function $t(t){var e=t.max,n=t.pathValue,r=t.index,a=n.charCodeAt(r),i=Ht[n[r].toLowerCase()];if(t.segmentStart=r,function(t){switch(32|t){case 109:case 122:case 108:case 104:case 118:case 99:case 115:case 113:case 116:case 97:return!0;default:return!1}}(a))if(t.index+=1,Yt(t),t.data=[],i){for(;;){for(var o=i;o>0;o-=1){if(97!=(32|a)||3!==o&&4!==o?Xt(t):Qt(t),t.err.length)return;t.data.push(t.param),Yt(t),t.index=t.max)break;if(!Wt(n.charCodeAt(t.index)))break}qt(t)}else qt(t);else t.err=Bt+": "+n[r]+" not a path command"}function Gt(t){return t.map((function(t){return Array.isArray(t)?[].concat(t):t}))}function Zt(t){this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""}function Kt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ht[e]===t.length-1&&"achlmqstvz".includes(e)}))}function Jt(t){if(Kt(t))return Gt(t);var e=new Zt(t);for(Yt(e);e.index7){t[n].shift();for(var r=t[n],a=n;r.length;)e[n]="A",t.splice(a+=1,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}function re(t,e,n){var r=t[0],a=e.x1,i=e.y1,o=e.x2,s=e.y2,u=t.slice(1).map(Number),c=t;if("TQ".includes(r)||(e.qx=null,e.qy=null),"H"===r)c=["L",t[1],i];else if("V"===r)c=["L",a,t[1]];else if("S"===r){var l=function(t,e,n,r,a){return"CS".includes(a)?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(a,i,o,s,n),p=l.x1,h=l.y1;e.x1=p,e.y1=h,c=["C",p,h].concat(u)}else if("T"===r){var f=function(t,e,n,r,a){return"QT".includes(a)?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(a,i,e.qx,e.qy,n),d=f.qx,v=f.qy;e.qx=d,e.qy=v,c=["Q",d,v].concat(u)}else if("Q"===r){var g=u[0],m=u[1];e.qx=g,e.qy=m}return c}var ae={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null};function ie(t){if(function(t){return te(t)&&t.every((function(t){return"ACLMQZ".includes(t[0])}))}(t))return Gt(t);for(var e=ee(t),n=Object.assign({},ae),r=[],a=e.length,i="",o="",s=0;s1&&(y*=M=Math.sqrt(M),b*=M);var _=y*y,C=b*b,j=(i===o?-1:1)*Math.sqrt(Math.abs((_*C-_*O*O-C*T*T)/(_*O*O+C*T*T)));d=j*y*O/b+(g+w)/2,v=j*-b*T/y+(m+E)/2,h=(Math.asin((m-v)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),f=(Math.asin((E-v)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),h=gf&&(h-=2*Math.PI),!o&&f>h&&(f-=2*Math.PI)}var I=f-h;if(Math.abs(I)>x){var A=f,P=w,L=E;f=h+x*(o&&f>h?1:-1),k=ue(w=d+y*Math.cos(f),E=v+b*Math.sin(f),y,b,a,0,o,P,L,[f,A,d,v])}I=f-h;var V=Math.cos(h),N=Math.sin(h),R=Math.cos(f),U=Math.sin(f),F=Math.tan(I/4),D=4/3*y*F,H=4/3*b*F,q=[g,m],B=[g+D*N,m-H*V],Q=[w+D*U,E-H*R],z=[w,E];if(B[0]=2*q[0]-B[0],B[1]=2*q[1]-B[1],c)return B.concat(Q,z,k);for(var X=[],Y=0,W=(k=B.concat(Q,z,k)).length;Yi+.001)return{x:n,y:r};var o=le([t,e],[n,r],a/i);return{x:o[0],y:o[1]}}return i}function fe(t,e,n,r){var a=.5,i=[t,e],o=[n,r],s=le(i,o,a),u=le(o,s,a),c=le(s,u,a),l=le(u,c,a),p=le(c,l,a),h=i.concat(s,c,p,[a]),f=he.apply(void 0,h),d=p.concat(l,u,o,[0]),v=he.apply(void 0,d);return[f.x,f.y,v.x,v.y,n,r]}function de(t,e){var n,r=t[0],a=t.slice(1).map((function(t){return+t})),i=a[0],o=a[1],s=e.x1,u=e.y1,c=e.x,l=e.y;switch("TQ".includes(r)||(e.qx=null,e.qy=null),r){case"M":return e.x=i,e.y=o,t;case"A":return n=[s,u].concat(a),["C"].concat(ue.apply(void 0,n));case"Q":return e.qx=i,e.qy=o,n=[s,u].concat(a),["C"].concat(ce.apply(void 0,n));case"L":return["C"].concat(fe(s,u,i,o));case"Z":return["C"].concat(fe(s,u,c,l))}return t}function ve(t){if(function(t){return Kt(t)&&t.every((function(t){return"MC".includes(t[0])}))}(t))return Gt(t);for(var e=oe(ie(t)),n=Object.assign({},ae),r=[],a="",i=e.length,o=0;o=1?e:n)>=1?Math.pow(10,n):1;return t.map((function(t){var e=t.slice(1).map(Number).map((function(t){return t%1==0?t:Math.round(t*r)/r}));return[t[0]].concat(e)}))}(t,e).map((function(t){return t[0]+t.slice(1).join(" ")})).join("")}function ye(t){var e=t.slice(1).map((function(e,n,r){return n?r[n-1].slice(-2).concat(e.slice(1)):t[0].slice(1).concat(e.slice(1))})).map((function(t){return t.map((function(e,n){return t[t.length-n-2*(1-n%2)]}))})).reverse();return[["M"].concat(e[0].slice(0,2))].concat(e.map((function(t){return["C"].concat(t.slice(2))})))}function be(t,e,n,r,a,i,o,s){return 3*((s-e)*(n+a)-(o-t)*(r+i)+r*(t-a)-n*(e-i)+s*(a+t/3)-o*(i+e/3))/20}function we(t){return function(t){var e=0,n=0,r=0;return ve(t).map((function(t){var a,i;return"M"===t[0]?(e=(a=t)[1],n=a[2],0):(r=be.apply(void 0,[e,n].concat(t.slice(1))),i=t.slice(-2),e=i[0],n=i[1],r)})).reduce((function(t,e){return t+e}),0)}(ve(t))>=0}function Ee(t){var e=.5,n=t.slice(0,2),r=t.slice(2,4),a=t.slice(4,6),i=t.slice(6,8),o=le(n,r,e),s=le(r,a,e),u=le(a,i,e),c=le(o,s,e),l=le(s,u,e),p=le(c,l,e);return[["C"].concat(o,c,p),["C"].concat(l,u,i)]}function xe(t){return me(ee(t),0).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t}))}function Se(t,e,n,r,a,i,o,s,u){var c=1-u;return{x:Math.pow(c,3)*t+3*Math.pow(c,2)*u*n+3*c*Math.pow(u,2)*a+Math.pow(u,3)*o,y:Math.pow(c,3)*e+3*Math.pow(c,2)*u*r+3*c*Math.pow(u,2)*i+Math.pow(u,3)*s}}function ke(t,e,n,r,a,i,o,s,u){var c,l=t,p=e,h=0,f=[t,e,h],d=[t,e];if("number"==typeof u&&u<.001)return{x:l,y:p};for(var v=0;v<=100;v+=1){if(h+=pe(d,[l=(c=Se(t,e,n,r,a,i,o,s,v/100)).x,p=c.y]),d=[l,p],"number"==typeof u&&h>=u){var g=(h-u)/(h-f[2]);return{x:d[0]*(1-g)+f[0]*g,y:d[1]*(1-g)+f[1]*g}}f=[l,p,h]}return"number"==typeof u&&u>=h?{x:o,y:s}:h}function Te(t){return ve(xe(t)[0]).map((function(t,e,n){var r=e&&n[e-1].slice(-2).concat(t.slice(1)),a=e?ke.apply(void 0,r):0;return{s:t,ss:e?a?Ee(r):[t,t]:[t],l:a}}))}function Oe(t,e,n){var r=Te(t),a=Te(e),i=r.length,o=a.length,s=r.filter((function(t){return t.l})).length,u=a.filter((function(t){return t.l})).length,c=r.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/s||0,l=a.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/u||0,p=n||Math.max(i,o),h=[c,l],f=[p-i,p-o],d=0,v=[r,a].map((function(t,e){return t.l===p?t.map((function(t){return t.s})):t.map((function(t,n){return d=n&&f[e]&&t.l>=h[e],f[e]-=d?1:0,d?t.ss:[t.s]})).flat()}));return v[0].length===v[1].length?v:Oe(v[0],v[1],p)}function Me(t){var e=t.length,n=e-1;return t.map((function(r,a){return t.map((function(r,i){var o,s=a+i;return 0===i||t[s]&&"M"===t[s][0]?(o=t[s],["M"].concat(o.slice(-2))):(s>=e&&(s-=n),t[s])}))}))}function _e(t,e){var n=t.length-1,r=[],a=0,i=Me(t);return i.forEach((function(i,o){t.slice(1).forEach((function(r,i){a+=pe(t[(o+i)%n].slice(-2),e[i%n].slice(-2))})),r[o]=a,a=0})),i[r.indexOf(Math.min.apply(null,r))]}var Ce={prepareStart:function(){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=new RegExp("\\n","ig"),a=null;return e instanceof SVGElement?a=e:/^\.|^#/.test(e)&&(a=P(e)),"object"==typeof e&&e.curve?e:(a&&/path|glyph/.test(a.tagName)?n.original=a.getAttribute("d").replace(r,""):a||"string"!=typeof e||(n.original=e.replace(r,"")),n)},onStart:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,e,n,r){for(var a=[],i=e.curve,o=n.curve,s=0,u=o.length;s>0)/1e3)}t.setAttribute("d",1===r?n.original:me(a))})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].curve,n=this.valuesEnd[t].curve;if(!e||!n||e&&n&&"M"===e[0][0]&&e.length!==n.length){var r=Oe(this.valuesStart[t].original,this.valuesEnd[t].original),a=we(r[0])!==we(r[1])?ye(r[0]):Gt(r[0]);this.valuesStart[t].curve=a,this.valuesEnd[t].curve=_e(r[1],a)}}}},je={component:"svgCubicMorph",property:"path",defaultValue:[],Interpolate:{numbers:Q,pathToString:me},functions:Ce,Util:{pathToCurve:ve,pathToAbsolute:ee,pathToString:me,parsePathString:Jt,getRotatedCurve:_e,getRotations:Me,equalizeSegments:Oe,reverseCurve:ye,clonePath:Gt,getDrawDirection:we,segmentCubicFactory:ke,splitCubic:Ee,splitPath:xe,fixPath:oe,getCurveArray:Te}};function Ie(t,e){var n=e.x,r=e.width;return/[a-z]/i.test(t)&&!/px/.test(t)?t.replace(/top|left/,0).replace(/right|bottom/,100).replace(/center|middle/,50):/%/.test(t)?n+parseFloat(t)*r/100:parseFloat(t)}function Ae(t){var e={},n=t&&/\)/.test(t)?t.substring(0,t.length-1).split(/\)\s|\)/):"none";if(n instanceof Array)for(var r=0,a=n.length;r>0)/1e3+(i?","+(1e3*i>>0)/1e3:"")+")":"")+(u?"rotate("+(1e3*u>>0)/1e3+")":"")+(p?"skewX("+(1e3*p>>0)/1e3+")":"")+(h?"skewY("+(1e3*h>>0)/1e3+")":"")+(1!==s?"scale("+(1e3*s>>0)/1e3+")":""))})},crossCheck:function(t){if(this._resetStart&&this.valuesEnd[t]){var e=this.valuesStart[t],n=this.valuesEnd[t],r=Pe.call(this,t,Ae(this.element.getAttribute("transform")));Object.keys(r).forEach((function(t){e[t]=r[t]}));var a=this.element.ownerSVGElement,i=a.createSVGTransformFromMatrix(a.createSVGMatrix().translate(-e.origin[0],-e.origin[1]).translate("translate"in e?e.translate[0]:0,"translate"in e?e.translate[1]:0).rotate(e.rotate||0).skewX(e.skewX||0).skewY(e.skewY||0).scale(e.scale||1).translate(+e.origin[0],+e.origin[1]));e.translate=[i.matrix.e,i.matrix.f],Object.keys(e).forEach((function(t){t in n&&"origin"!==t||(n[t]=e[t])}))}}},Ve={component:"svgTransformProperty",property:"svgTransform",defaultOptions:{transformOrigin:"50% 50%"},defaultValue:{translate:0,rotate:0,skewX:0,skewY:0,scale:1},Interpolate:{numbers:Q},functions:Le,Util:{parseStringOrigin:Ie,parseTransformString:Ae,parseTransformSVG:Pe}},Ne=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){return t=!0}});document.addEventListener("DOMContentLoaded",(function t(){document.removeEventListener("DOMContentLoaded",t,e)}),e)}catch(t){throw Error("Passive events are not supported")}return t}()&&{passive:!0},Re="onmouseleave"in document?["mouseenter","mouseleave"]:["mouseover","mouseout"],Ue="ontouchstart"in window||"msMaxTouchPoints"in navigator?"touchstart":"mousewheel",Fe=navigator&&/(EDGE|Mac)/i.test(navigator.userAgent)?document.body:document.documentElement;function De(t){this.scrolling&&t.preventDefault()}function He(){var t=this.element;return t===Fe?{el:document,st:document.body}:{el:t,st:t}}function qe(t,e){e[t](Re[0],De,Ne),e[t](Ue,De,Ne)}function Be(){var t=He.call(this);"scroll"in this.valuesEnd&&!t.el.scrolling&&(t.el.scrolling=1,qe("addEventListener",t.el),t.st.style.pointerEvents="none")}function Qe(){var t=He.call(this);"scroll"in this.valuesEnd&&t.el.scrolling&&(t.el.scrolling=0,qe("removeEventListener",t.el),t.st.style.pointerEvents="")}var ze={prepareStart:function(){return this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Fe,this.element===Fe?window.pageYOffset||Fe.scrollTop:this.element.scrollTop},prepareProperty:function(t,e){return parseInt(e,10)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Fe,Be.call(this),e[t]=function(t,e,n,r){t.scrollTop=Q(e,n,r)>>0})},onComplete:function(){Qe.call(this)}},Xe={component:"scrollProperty",property:"scroll",defaultValue:0,Interpolate:{numbers:Q},functions:ze,Util:{preventScroll:De,scrollIn:Be,scrollOut:Qe,getScrollTargets:He,toggleScrollEvents:qe}};function Ye(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){for(var i=[],o="textShadow"===t?3:4,s=3===o?n[3]:n[4],u=3===o?r[3]:r[4],c=!!(n[5]&&"none"!==n[5]||r[5]&&"none"!==r[5])&&" inset",l=0;l>0)/1e3+"px");e.style[t]=c?lt(s,u,a)+i.join(" ")+c:lt(s,u,a)+i.join(" ")})}var We={};["boxShadow","textShadow"].forEach((function(t){We[t]=Ye}));var $e=["boxShadow","textShadow"];function Ge(t,e){var n;3===t.length?n=[t[0],t[1],0,0,t[2],"none"]:4===t.length?n=/inset|none/.test(t[3])?[t[0],t[1],0,0,t[2],t[3]]:[t[0],t[1],t[2],0,t[3],"none"]:5===t.length?n=/inset|none/.test(t[4])?[t[0],t[1],t[2],0,t[3],t[4]]:[t[0],t[1],t[2],t[3],t[4],"none"]:6===t.length&&(n=t);for(var r=0;r<4;r+=1)n[r]=parseFloat(n[r]);return n[4]=ct(n[4]),n="boxShadow"===e?n:n.filter((function(t,e){return[0,1,2,4].includes(e)})),n}var Ze={};$e.forEach((function(t){Ze[t]=Ye}));var Ke={component:"shadowProperties",properties:$e,defaultValues:{boxShadow:"0px 0px 0px 0px rgb(0,0,0)",textShadow:"0px 0px 0px rgb(0,0,0)"},Interpolate:{numbers:Q,colors:lt},functions:{prepareStart:function(t){var e=M(this.element,t);return/^none$|^initial$|^inherit$|^inset$/.test(e)?f[t]:e},prepareProperty:function(t,e){var n=e;if("string"==typeof n){var r="none",a=n.match(/(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi);r=/inset/.test(n)?"inset":r,n=Ge(n=(n=/inset/.test(n)?n.replace(/(\s+inset|inset+\s)/g,""):n).replace(a[0],"").split(" ").concat([a[0].replace(/\s/g,"")],[r]),t)}else n instanceof Array&&(n=Ge(n,t));return n},onStart:Ze},Util:{processShadowArray:Ge,trueColor:ct}},Je={};function tn(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=W(n.v,r.v,r.u,a)})}["fontSize","lineHeight","letterSpacing","wordSpacing"].forEach((function(t){Je[t]=tn}));var en=["fontSize","lineHeight","letterSpacing","wordSpacing"],nn={};en.forEach((function(t){nn[t]=tn}));var rn={component:"textProperties",category:"textProperties",properties:en,defaultValues:{fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},Interpolate:{units:W},functions:{prepareStart:function(t){return M(this.element,t)||f[t]},prepareProperty:function(t,e){return z(e)},onStart:nn},Util:{trueDimension:z}},an=String("abcdefghijklmnopqrstuvwxyz").split(""),on=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),sn=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),un=String("0123456789").split(""),cn=an.concat(on,un),ln=cn.concat(sn),pn={alpha:an,upper:on,symbols:sn,numeric:un,alphanumeric:cn,all:ln},hn={text:function(t){if(!e[t]&&this.valuesEnd[t]){var n=this._textChars,r=pn[d.textChars];n in pn?r=pn[n]:n&&n.length&&(r=n),e[t]=function(t,e,n,a){var i="",o="",s=""===n?" ":n,u=e.substring(0),c=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(o=c.substring(Math.min(a*c.length,c.length)>>0,0),t.innerHTML=a<1?o+l:s):" "===n?(i=u.substring(0,Math.min((1-a)*u.length,u.length)>>0),t.innerHTML=a<1?i+l:s):(i=u.substring(u.length,Math.min(a*u.length,u.length)>>0),o=c.substring(0,Math.min(a*c.length,c.length)>>0),t.innerHTML=a<1?o+l+i:s)}}},number:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(t,e,n,r){t.innerHTML=Q(e,n,r)>>0})}};function fn(t,e){var n,r;if("string"==typeof t)return(r=document.createElement("SPAN")).innerHTML=t,r.className=e,r;if(!t.children.length||t.children.length&&t.children[0].className!==e){var a=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=a,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function dn(t,e){var n=[],r=t.children.length;if(r){for(var a,i=[],o=t.innerHTML,s=0,u=void 0,c=void 0,l=void 0;s>0)/1e3;return r}var gn="undefined"!=typeof DOMMatrix?DOMMatrix:null,mn="transformMatrix";var yn={BackgroundPosition:Y,BorderRadius:tt,BoxModel:ot,ClipProperty:ut,ColorProperties:gt,FilterEffects:xt,HTMLAttributes:_t,OpacityProperty:jt,SVGDraw:Dt,SVGCubicMorph:je,SVGTransform:Ve,ScrollProperty:Xe,ShadowProperties:Ke,TextProperties:rn,TextWriteProperties:{component:"textWriteProperties",category:"textWrite",properties:["text","number"],defaultValues:{text:" ",number:"0"},defaultOptions:{textChars:"alpha"},Interpolate:{numbers:Q},functions:{prepareStart:function(){return this.element.innerHTML},prepareProperty:function(t,e){return"number"===t?parseFloat(e):""===e?" ":e},onStart:hn},Util:{charSet:pn,createTextTweens:function(t,e,n){if(t.playing)return!1;var r=n||{};r.duration=1e3,"auto"===n.duration?r.duration="auto":Number.isFinite(1*n.duration)&&(r.duration=1*n.duration);var a=I.tween,i=function(t,e){var n=dn(t,"text-part"),r=dn(fn(e),"text-part");return t.innerHTML="",t.innerHTML+=n.map((function(t){return t.className+=" oldText",t.outerHTML})).join(""),t.innerHTML+=r.map((function(t){return t.className+=" newText",t.outerHTML.replace(t.innerHTML,"")})).join(""),[n,r]}(t,e),o=i[0],s=i[1],u=[].slice.call(t.getElementsByClassName("oldText")).reverse(),c=[].slice.call(t.getElementsByClassName("newText")),l=[],p=0;return(l=(l=l.concat(u.map((function(t,e){return r.duration="auto"===r.duration?75*o[e].innerHTML.length:r.duration,r.delay=p,r.onComplete=null,p+=r.duration,new a(t,{text:t.innerHTML},{text:""},r)})))).concat(c.map((function(n,i){return r.duration="auto"===r.duration?75*s[i].innerHTML.length:r.duration,r.delay=p,r.onComplete=i===s.length-1?function(){t.innerHTML=e,t.playing=!1}:null,p+=r.duration,new a(n,{text:""},{text:s[i].innerHTML},r)})))).start=function(){t.playing||(l.forEach((function(t){return t.start()})),t.playing=!0)},l}}},MatrixTransform:{component:mn,property:"transform",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:{prepareStart:function(t,e){var n={},r=this.element.transformMatrix;return r?Object.keys(r).forEach((function(t){n[t]=r[t]})):Object.keys(e).forEach((function(t){n[t]="perspective"===t?e[t]:f.transform[t]})),n},prepareProperty:function(t,e){if("object"==typeof e&&!e.length){var n,r={},a={},i={},o={},s={},u=[{translate3d:a},{rotate3d:i},{skew:s},{scale3d:o}];return Object.keys(e).forEach((function(t){if(/3d/.test(t)&&"object"==typeof e[t]&&e[t].length)n=e[t].map((function(e){return"scale3d"===t?parseFloat(e):parseInt(e,10)})),r[t]="scale3d"===t?[n[0]||1,n[1]||1,n[2]||1]:[n[0]||0,n[1]||0,n[2]||0];else if(/[XYZ]/.test(t)){var u={};/translate/.test(t)?u=a:/rotate/.test(t)?u=i:/scale/.test(t)?u=o:/skew/.test(t)&&(u=s),u[t.replace(/translate|rotate|scale|skew/,"").toLowerCase()]=/scale/.test(t)?parseFloat(e[t]):parseInt(e[t],10)}else"skew"===t?(n=e[t].map((function(t){return parseInt(t,10)||0})),r[t]=[n[0]||0,n[1]||0]):r[t]=parseInt(e[t],10)})),u.forEach((function(t){var e=Object.keys(t)[0],n=t[e];Object.keys(n).length&&!r[e]&&(r[e]="scale3d"===e?[n.x||1,n.y||1,n.z||1]:"skew"===e?[n.x||0,n.y||0]:[n.x||0,n.y||0,n.z||0])})),r}throw Error('KUTE.js - "'+e+'" is not valid/supported transform function')},onStart:{transform:function(t){gn&&this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){var i=new gn,o={};Object.keys(r).forEach((function(t){o[t]="perspective"===t?Q(n[t],r[t],a):vn(n[t],r[t],a)})),o.perspective&&(i.m34=-1/o.perspective),i=o.translate3d?i.translate(o.translate3d[0],o.translate3d[1],o.translate3d[2]):i,i=o.rotate3d?i.rotate(o.rotate3d[0],o.rotate3d[1],o.rotate3d[2]):i,o.skew&&(i=o.skew[0]?i.skewX(o.skew[0]):i,i=o.skew[1]?i.skewY(o.skew[1]):i),i=o.scale3d?i.scale(o.scale3d[0],o.scale3d[1],o.scale3d[2]):i,e.style[t]=i.toString()})},CSS3Matrix:function(t){gn&&this.valuesEnd.transform&&(e[t]||(e[t]=gn))}},onComplete:function(t){this.valuesEnd[t]&&(this.element.transformMatrix=Object.assign({},this.valuesEnd[t]))},crossCheck:function(t){this.valuesEnd[t]&&this.valuesEnd[t].perspective&&!this.valuesStart[t].perspective&&(this.valuesStart[t].perspective=this.valuesEnd[t].perspective)}},Interpolate:{perspective:Q,translate3d:vn,rotate3d:vn,skew:vn,scale3d:vn}}};Object.keys(yn).forEach((function(t){var e=yn[t];yn[t]=new B(e)}));return{Animation:B,Components:yn,Tween:R,fromTo:function(t,e,n,r){var a=r||{};return new H(P(t),e,n,a)},to:function(t,e,n){var r=n||{};return r.resetStart=e,new D(P(t),e,e,r)},TweenCollection:U,ProgressBar:F,allFromTo:function(t,e,n,r){var a=r||{};return new U(P(t,!0),e,n,a)},allTo:function(t,e,n){var r=n||{};return r.resetStart=e,new U(P(t,!0),e,e,r)},Objects:w,Util:E,Easing:A,CubicBezier:t,Render:p,Interpolate:a,Process:j,Internals:T,Selector:P,Version:"2.2.3"}})); diff --git a/demo/src/kute.min.js b/demo/src/kute.min.js deleted file mode 100644 index f0c3fa3..0000000 --- a/demo/src/kute.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// KUTE.js Standard v2.2.3 | thednp © 2021 | MIT-License -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=e()}(this,(function(){"use strict";var t=function(t,e,n,r,a){var i=this;this.cx=3*t,this.bx=3*(n-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(r-e)-this.cy,this.ay=1-this.cy-this.by;var o=function(t){return i.sampleCurveY(i.solveCurveX(t))};return Object.defineProperty(o,"name",{writable:!0}),o.name=a||"cubic-bezier("+[t,e,n,r]+")",o};t.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},t.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},t.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},t.prototype.solveCurveX=function(t){var e,n,r,a,i,o,s=1e-5;for(r=t,o=0;o<32;o+=1){if(a=this.sampleCurveX(r)-t,Math.abs(a)(n=1))return n;for(;ea?e=r:n=r,r=.5*(n-e)+e}return r};Object.assign(t,{Version:"1.0.18"});var e={},n=[],r="undefined"!=typeof global?global:"undefined"!=typeof window?window.self:{},a={},i={},o="undefined"==typeof self&&"undefined"!=typeof process&&process.hrtime?function(){var t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:"undefined"!=typeof self&&void 0!==self.performance&&void 0!==self.performance.now?self.performance.now.bind(self.performance):"undefined"!=typeof Date&&Date.now?Date.now:function(){return(new Date).getTime()},s={};s.now=o;var u=0,c=function(t){for(var e=0;e1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.map((function(t){return t.start()})),!1)},j.tween=N;var q=function(t){function n(){for(var e=this,n=[],r=arguments.length;r--;)n[r]=arguments[r];t.apply(this,n),this.valuesStart={},this.valuesEnd={};var a=n.slice(1),i=a[0],o=a[1],s=a[2];return T.call(this,o,"end"),this._resetStart?this.valuesStart=i:T.call(this,i,"start"),this._resetStart||Object.keys(g).forEach((function(t){Object.keys(g[t]).forEach((function(n){g[t][n].call(e,n)}))})),this.paused=!1,this._pauseTime=null,this._repeat=s.repeat||d.repeat,this._repeatDelay=s.repeatDelay||d.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=s.yoyo||d.yoyo,this._reversed=!1,this}return t&&(n.__proto__=t),n.prototype=Object.create(t&&t.prototype),n.prototype.constructor=n,n.prototype.start=function(e){var n=this;return this._resetStart&&(this.valuesStart=this._resetStart,S.call(this),Object.keys(g).forEach((function(t){Object.keys(g[t]).forEach((function(e){g[t][e].call(n,e)}))}))),this.paused=!1,this._yoyo&&Object.keys(this.valuesEnd).forEach((function(t){n.valuesRepeat[t]=n.valuesStart[t]})),t.prototype.start.call(this,e),this},n.prototype.stop=function(){return t.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return t.prototype.close.call(this),this._repeatOption>0&&(this._repeat=this._repeatOption),this._yoyo&&!0===this._reversed&&(this.reverse(),this._reversed=!1),this},n.prototype.resume=function(){return this.paused&&this.playing&&(this.paused=!1,void 0!==this._onResume&&this._onResume.call(this),L.call(this),this._startTime+=e.Time()-this._pauseTime,E(this),u||c()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(M(this),this.paused=!0,this._pauseTime=e.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){var t=this;Object.keys(this.valuesEnd).forEach((function(e){var n=t.valuesRepeat[e];t.valuesRepeat[e]=t.valuesEnd[e],t.valuesEnd[e]=n,t.valuesStart[e]=t.valuesRepeat[e]}))},n.prototype.update=function(t){var n,r=this,a=void 0!==t?t:e.Time();if(a1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(Number.isFinite(this._repeat)&&(this._repeat-=1),this._startTime=a,Number.isFinite(this._repeat)&&this._yoyo&&!this._reversed&&(this._startTime+=this._repeatDelay),this._yoyo&&(this._reversed=!this._reversed,this.reverse()),!0):(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.forEach((function(t){return t.start()})),!1))},n}(N);j.tween=q;var V=function(t,e,n,r){var a=this,i=j.tween;this.tweens=[];var o=r||{};o.delay=o.delay||d.delay;var s=[];return Array.from(t).forEach((function(t,r){if(s[r]=o||{},s[r].delay=r>0?o.delay+(o.offset||d.offset):o.delay,!(t instanceof Element))throw Error("KUTE - "+t+" is not instanceof Element");a.tweens.push(new i(t,e,n,s[r]))})),this.length=this.tweens.length,this};V.prototype.start=function(t){var n=void 0===t?e.Time():t;return this.tweens.map((function(t){return t.start(n)})),this},V.prototype.stop=function(){return this.tweens.map((function(t){return t.stop()})),this},V.prototype.pause=function(){return this.tweens.map((function(t){return t.pause()})),this},V.prototype.resume=function(){return this.tweens.map((function(t){return t.resume()})),this},V.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof V)e.chain(t.tweens);else{if(!(t instanceof j.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},V.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},V.prototype.removeTweens=function(){this.tweens=[]},V.prototype.getMaxDuration=function(){var t=[];return this.tweens.forEach((function(e){t.push(e._duration+e._delay+e._repeat*e._repeatDelay)})),Math.max(t)};var H=j.tween;var Q=j.tween;var F=function(t){try{if(t.component in f)throw Error("KUTE - "+t.component+" already registered");if(t.property in h)throw Error("KUTE - "+t.property+" already registered")}catch(t){throw Error(t)}var e=this,n=t.component,r={prepareProperty:y,prepareStart:v,onStart:i,onComplete:m,crossCheck:g},o=t.category,s=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;return f[n]=t.properties||t.subProperties||t.property,"defaultValue"in t?(h[s]=t.defaultValue,e.supports=s+" property"):t.defaultValues&&(Object.keys(t.defaultValues).forEach((function(e){h[e]=t.defaultValues[e]})),e.supports=(u||s)+" "+(s||o)+" properties"),t.defaultOptions&&Object.assign(d,t.defaultOptions),t.functions&&Object.keys(r).forEach((function(e){e in t.functions&&("function"==typeof t.functions[e]?(r[e][n]||(r[e][n]={}),r[e][n][o||s]||(r[e][n][o||s]=t.functions[e])):Object.keys(t.functions[e]).forEach((function(a){r[e][n]||(r[e][n]={}),r[e][n][a]||(r[e][n][a]=t.functions[e][a])})))})),t.Interpolate&&(Object.keys(t.Interpolate).forEach((function(e){var n=t.Interpolate[e];"function"!=typeof n||a[e]?Object.keys(n).forEach((function(t){"function"!=typeof n[t]||a[e]||(a[e]=n[t])})):a[e]=n})),b[n]=t.Interpolate),t.Util&&Object.keys(t.Util).forEach((function(e){w[e]||(w[e]=t.Util[e])})),e},U=function(t,e){for(var n,r=parseInt(t,10)||0,a=["px","%","deg","rad","em","rem","vh","vw"],i=0;i.99||a<.01?(10*D(n,r,a)>>0)/10:D(n,r,a)>>0)+"px"})}var Z={};["top","left","width","height"].forEach((function(t){Z[t]=X}));var B=["top","left","width","height"],R={};B.forEach((function(t){R[t]=X}));var Y={component:"essentialBoxModel",category:"boxModel",properties:B,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:D},functions:{prepareStart:function(t){return O(this.element,t)||h[t]},prepareProperty:function(t,e){var n=U(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:R},Util:{trueDimension:U}},z=function(t){var e;if(/rgb|rgba/.test(t)){var n=t.replace(/\s|\)/,"").split("(")[1].split(","),r=n[3]?n[3]:null;r||(e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10)}),e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10),a:parseFloat(r)}}if(/^#/.test(t)){var a=function(t){var e=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r})),n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return n?{r:parseInt(n[1],16),g:parseInt(n[2],16),b:parseInt(n[3],16)}:null}(t);e={r:a.r,g:a.g,b:a.b}}if(/transparent|none|initial|inherit/.test(t)&&(e={r:0,g:0,b:0,a:0}),!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var o=getComputedStyle(i,null).color;o=/rgb/.test(o)?o.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",e={r:parseInt(o[0],10),g:parseInt(o[1],10),b:parseInt(o[2],10)}}return e};function K(t,e,n){var r={},a=",";return Object.keys(e).forEach((function(a){"a"!==a?r[a]=D(t[a],e[a],n)>>0||0:t[a]&&e[a]&&(r[a]=(100*D(t[a],e[a],n)>>0)/100)})),r.a?"rgba("+r.r+a+r.g+a+r.b+a+r.a+")":"rgb("+r.r+a+r.g+a+r.b+")"}function $(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=K(n,r,a)})}var W={};["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"].forEach((function(t){W[t]=$}));var G=["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],J={};G.forEach((function(t){J[t]="#000"}));var tt={};G.forEach((function(t){tt[t]=$}));var et={component:"colorProperties",category:"colors",properties:G,defaultValues:J,Interpolate:{numbers:D,colors:K},functions:{prepareStart:function(t){return O(this.element,t)||h[t]},prepareProperty:function(t,e){return z(e)},onStart:tt},Util:{trueColor:z}},nt={},rt="htmlAttributes",at=["fill","stroke","stop-color"];function it(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var ot={prepareStart:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(t){var e=it(t).replace(/_+[a-z]+/,""),a=n.element.getAttribute(e);r[e]=at.includes(e)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(t)?1:0)})),r},prepareProperty:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(a){var o=it(a),s=/(%|[a-z]+)$/,u=n.element.getAttribute(o.replace(/_+[a-z]+/,""));if(at.includes(o))i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){t.setAttribute(e,K(n,r,a))})},r[o]=z(e[a])||h.htmlAttributes[a];else if(null!==u&&s.test(u)){var c=U(u).u||U(e[a]).u,l=/%/.test(c)?"_percent":"_"+c;i.htmlAttributes[o+l]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){var i=e.replace(l,"");t.setAttribute(i,(1e3*D(n.v,r.v,a)>>0)/1e3+r.u)})},r[o+l]=U(e[a])}else s.test(e[a])&&null!==u&&(null===u||s.test(u))||(i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){t.setAttribute(e,(1e3*D(n,r,a)>>0)/1e3)})},r[o]=parseFloat(e[a]))})),r},onStart:{attr:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,n,r,a){Object.keys(r).forEach((function(i){e.attributes[i](t,i,n[i],r[i],a)}))})},attributes:function(t){!e[t]&&this.valuesEnd.attr&&(e[t]=nt)}}},st={component:rt,property:"attr",subProperties:["fill","stroke","stop-color","fill-opacity","stroke-opacity"],defaultValue:{fill:"rgb(0,0,0)",stroke:"rgb(0,0,0)","stop-color":"rgb(0,0,0)",opacity:1,"stroke-opacity":1,"fill-opacity":1},Interpolate:{numbers:D,colors:K},functions:ot,Util:{replaceUppercase:it,trueColor:z,trueDimension:U}};var ut={prepareStart:function(t){return O(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=(1e3*D(n,r,a)>>0)/1e3})}},ct={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:D},functions:ut},lt=String("abcdefghijklmnopqrstuvwxyz").split(""),pt=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),ft=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ht=String("0123456789").split(""),dt=lt.concat(pt,ht),yt=dt.concat(ft),vt={alpha:lt,upper:pt,symbols:ft,numeric:ht,alphanumeric:dt,all:yt},gt={text:function(t){if(!e[t]&&this.valuesEnd[t]){var n=this._textChars,r=vt[d.textChars];n in vt?r=vt[n]:n&&n.length&&(r=n),e[t]=function(t,e,n,a){var i="",o="",s=""===n?" ":n,u=e.substring(0),c=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(o=c.substring(Math.min(a*c.length,c.length)>>0,0),t.innerHTML=a<1?o+l:s):" "===n?(i=u.substring(0,Math.min((1-a)*u.length,u.length)>>0),t.innerHTML=a<1?i+l:s):(i=u.substring(u.length,Math.min(a*u.length,u.length)>>0),o=c.substring(0,Math.min(a*c.length,c.length)>>0),t.innerHTML=a<1?o+l+i:s)}}},number:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(t,e,n,r){t.innerHTML=D(e,n,r)>>0})}};function mt(t,e){var n,r;if("string"==typeof t)return(r=document.createElement("SPAN")).innerHTML=t,r.className=e,r;if(!t.children.length||t.children.length&&t.children[0].className!==e){var a=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=a,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function bt(t,e){var n=[],r=t.children.length;if(r){for(var a,i=[],o=t.innerHTML,s=0,u=void 0,c=void 0,l=void 0;s>0)/1e3+n+")"}function wt(t,e,n,r){for(var a=[],i=0;i<3;i+=1)a[i]=(t[i]||e[i]?(1e3*(t[i]+(e[i]-t[i])*r)>>0)/1e3:0)+n;return"translate3d("+a.join(",")+")"}function Et(t,e,n,r){var a="";return a+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",a+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",a+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function Mt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function _t(t,e,n,r){var a=[];return a[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,a[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+a.join(",")+")"}function kt(t,e){return parseFloat(t)/100*e}function Ct(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Ot(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");return 2!==e.length||Number.isNaN(1*e[0])||Number.isNaN(1*e[1])?0:[parseFloat(e[0]),parseFloat(e[1])]},a=function(t,e){return void 0!==t&&void 0!==e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var i=0;i>0)/100,i=0-(100*D(e.s,n.s,r)>>0)/100,o=(100*D(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=i+"px",t.style.strokeDasharray=(100*(o<1?0:o)>>0)/100+"px, "+a+"px"})}};function Lt(t,e,n){if(t[n].length>7){t[n].shift();for(var r=t[n],a=n;r.length;)e[n]="A",t.splice(a+=1,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Nt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function qt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;for("m"===n&&r.length>2&&(t.segments.push([e,r[0],r[1]]),r=r.slice(2),n="l",e="m"===e?"l":"L");r.length>=Nt[n]&&(t.segments.push([e].concat(r.splice(0,Nt[n]))),Nt[n]););}var Vt="Invalid path value";function Ht(t){var e=t.index,n=t.pathValue.charCodeAt(e);return 48===n?(t.param=0,void(t.index+=1)):49===n?(t.param=1,void(t.index+=1)):void(t.err=Vt+': invalid Arc flag "'+n+'", expecting 0 or 1 at index '+e)}function Qt(t){return t>=48&&t<=57}function Ft(t){var e,n=t.max,r=t.pathValue,a=t.index,i=a,o=!1,s=!1,u=!1,c=!1;if(i>=n)t.err=Vt+" at "+i+": missing param "+r[i];else if(43!==(e=r.charCodeAt(i))&&45!==e||(e=(i+=1)=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index+=1}function Dt(t){return t>=48&&t<=57||43===t||45===t||46===t}function Xt(t){var e=t.max,n=t.pathValue,r=t.index,a=n.charCodeAt(r),i=Nt[n[r].toLowerCase()];if(t.segmentStart=r,function(t){switch(32|t){case 109:case 122:case 108:case 104:case 118:case 99:case 115:case 113:case 116:case 97:return!0;default:return!1}}(a))if(t.index+=1,Ut(t),t.data=[],i){for(;;){for(var o=i;o>0;o-=1){if(97!=(32|a)||3!==o&&4!==o?Ft(t):Ht(t),t.err.length)return;t.data.push(t.param),Ut(t),t.index=t.max)break;if(!Dt(n.charCodeAt(t.index)))break}qt(t)}else qt(t);else t.err=Vt+": "+n[r]+" not a path command"}function Zt(t){return t.map((function(t){return Array.isArray(t)?[].concat(t):t}))}function Bt(t){this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""}function Rt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Nt[e]===t.length-1&&"achlmqstvz".includes(e)}))}function Yt(t){if(Rt(t))return Zt(t);var e=new Bt(t);for(Ut(e);e.index1&&(m*=O=Math.sqrt(O),b*=O);var T=m*m,S=b*b,I=(i===o?-1:1)*Math.sqrt(Math.abs((T*S-T*C*C-S*k*k)/(T*C*C+S*k*k)));d=I*m*C/b+(v+x)/2,y=I*-b*k/m+(g+w)/2,f=(Math.asin((g-y)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),h=(Math.asin((w-y)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),f=vh&&(f-=2*Math.PI),!o&&h>f&&(h-=2*Math.PI)}var j=h-f;if(Math.abs(j)>E){var A=h,P=x,L=w;h=f+E*(o&&h>f?1:-1),_=ee(x=d+m*Math.cos(h),w=y+b*Math.sin(h),m,b,a,0,o,P,L,[h,A,d,y])}j=h-f;var N=Math.cos(f),q=Math.sin(f),V=Math.cos(h),H=Math.sin(h),Q=Math.tan(j/4),F=4/3*m*Q,U=4/3*b*Q,D=[v,g],X=[v+F*q,g-U*N],Z=[x+F*H,w-U*V],B=[x,w];if(X[0]=2*D[0]-X[0],X[1]=2*D[1]-X[1],c)return X.concat(Z,B,_);for(var R=[],Y=0,z=(_=X.concat(Z,B,_)).length;Yi+.001)return{x:n,y:r};var o=re([t,e],[n,r],a/i);return{x:o[0],y:o[1]}}return i}function oe(t,e,n,r){var a=.5,i=[t,e],o=[n,r],s=re(i,o,a),u=re(o,s,a),c=re(s,u,a),l=re(u,c,a),p=re(c,l,a),f=i.concat(s,c,p,[a]),h=ie.apply(void 0,f),d=p.concat(l,u,o,[0]),y=ie.apply(void 0,d);return[h.x,h.y,y.x,y.y,n,r]}function se(t,e){var n,r=t[0],a=t.slice(1).map((function(t){return+t})),i=a[0],o=a[1],s=e.x1,u=e.y1,c=e.x,l=e.y;switch("TQ".includes(r)||(e.qx=null,e.qy=null),r){case"M":return e.x=i,e.y=o,t;case"A":return n=[s,u].concat(a),["C"].concat(ee.apply(void 0,n));case"Q":return e.qx=i,e.qy=o,n=[s,u].concat(a),["C"].concat(ne.apply(void 0,n));case"L":return["C"].concat(oe(s,u,i,o));case"Z":return["C"].concat(oe(s,u,c,l))}return t}var ue=4;function ce(t,e){var n=ue;if(!1===e||!1===n)return Zt(t);var r=(n=e>=1?e:n)>=1?Math.pow(10,n):1;return t.map((function(t){var e=t.slice(1).map(Number).map((function(t){return t%1==0?t:Math.round(t*r)/r}));return[t[0]].concat(e)}))}function le(t,e){return ce(t,e).map((function(t){return t[0]+t.slice(1).join(" ")})).join("")}function pe(t,e,n,r,a,i,o,s,u){var c=1-u;return{x:Math.pow(c,3)*t+3*Math.pow(c,2)*u*n+3*c*Math.pow(u,2)*a+Math.pow(u,3)*o,y:Math.pow(c,3)*e+3*Math.pow(c,2)*u*r+3*c*Math.pow(u,2)*i+Math.pow(u,3)*s}}function fe(t,e,n,r,a,i,o,s,u){var c,l=t,p=e,f=0,h=[t,e,f],d=[t,e];if("number"==typeof u&&u<.001)return{x:l,y:p};for(var y=0;y<=100;y+=1){if(f+=ae(d,[l=(c=pe(t,e,n,r,a,i,o,s,y/100)).x,p=c.y]),d=[l,p],"number"==typeof u&&f>=u){var v=(f-u)/(f-h[2]);return{x:d[0]*(1-v)+h[0]*v,y:d[1]*(1-v)+h[1]*v}}h=[l,p,f]}return"number"==typeof u&&u>=f?{x:o,y:s}:f}function he(t,e,n,r,a,i,o,s,u,c){var l,p=[t,e],f=p[0],h=p[1],d=ee(t,e,n,r,a,i,o,s,u),y=0,v=[],g=[],m=0;if("number"==typeof c&&c<.001)return{x:f,y:h};for(var b=0,x=d.length;b=c)return fe.apply(void 0,g.concat([c-y]));y+=m,f=(l=v.slice(-2))[0],h=l[1]}return"number"==typeof c&&c>=y?{x:s,y:u}:y}function de(t,e,n,r,a,i,o){var s=1-o;return{x:Math.pow(s,2)*t+2*s*o*n+Math.pow(o,2)*a,y:Math.pow(s,2)*e+2*s*o*r+Math.pow(o,2)*i}}function ye(t,e,n,r,a,i,o){var s,u=t,c=e,l=0,p=[t,e,l],f=[t,e];if("number"==typeof o&&o<.001)return{x:u,y:c};for(var h=0;h<=100;h+=1){if(l+=ae(f,[u=(s=de(t,e,n,r,a,i,h/100)).x,c=s.y]),f=[u,c],"number"==typeof o&&l>=o){var d=(l-o)/(l-p[2]);return{x:f[0]*(1-d)+p[0]*d,y:f[1]*(1-d)+p[1]*d}}p=[u,c,l]}return"number"==typeof o&&o>=l?{x:a,y:i}:l}function ve(t,e){for(var n,r,a,i=0,o=!0,s=[],u="M",c=0,l=0,p=0,f=0,h=0,d=Jt(Gt(t)),y=0,v=d.length;y=e)return ie.apply(void 0,s.concat([e-i]));i+=c}else if("A"===u){if(c=he.apply(void 0,s),e&&i+c>=e)return he.apply(void 0,s.concat([e-i]));i+=c}else if("C"===u){if(c=fe.apply(void 0,s),e&&i+c>=e)return fe.apply(void 0,s.concat([e-i]));i+=c}else if("Q"===u){if(c=ye.apply(void 0,s),e&&i+c>=e)return ye.apply(void 0,s.concat([e-i]));i+=c}else if("Z"===u){if(s=[l,p,f,h],c=ie.apply(void 0,s),e&&i+c>=e)return ie.apply(void 0,s.concat([e-i]));i+=c}l=(r="Z"!==u?a.slice(-2):[f,h])[0],p=r[1]}return e&&e>=i?{x:l,y:p}:i}function ge(t){return ve(t)}function me(t,e){return ve(t,e)}function be(t){for(var e,n=t.length,r=-1,a=t[n-1],i=0;++r>0)/1e3)}return a}function we(t,e){var n,r,a=Gt((n=le(t),le(Kt(n),0).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0]),i=ge(a),o=[],s=3;e&&!Number.isNaN(e)&&+e>0&&(s=Math.max(s,Math.ceil(i/e)));for(var u=0;u0&&o.reverse(),{polygon:o,skipBisect:!0}}function Ee(t,e){var n=Gt(t);return function(t){var e=[],n=t.length,r=[],a="";if(!t.length||"M"!==t[0][0])return!1;for(var i=0;ie;)r=re(n,r,.5),t.splice(a+1,0,r)}function Ce(t){return Array.isArray(t)&&t.every((function(t){return Array.isArray(t)&&2===t.length&&!Number.isNaN(t[0])&&!Number.isNaN(t[1])}))}function Oe(t,e){var n,r,a;if("string"==typeof t)a=(n=Ee(t,e)).polygon,r=n.skipBisect;else if(!Array.isArray(t))throw Error(Vt+": "+t);var i=[].concat(a);if(!Ce(i))throw Error(Vt+": "+i);return i.length>1&&ae(i[0],i[i.length-1])<1e-9&&i.pop(),!r&&e&&!Number.isNaN(e)&&+e>0&&ke(i,e),i}function Te(t,e,n){var r=n||d.morphPrecision,a=Oe(t,r),i=Oe(e,r),o=a.length-i.length;return _e(a,o<0?-1*o:0),_e(i,o>0?o:0),Me(a,i),[ce(a),ce(i)]}var Se={prepareStart:function(){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=new RegExp("\\n","ig"),a=null;return e instanceof SVGPathElement?a=e:/^\.|^#/.test(e)&&(a=P(e)),"object"==typeof e&&e.polygon?e:(a&&["path","glyph"].includes(a.tagName)?n.original=a.getAttribute("d").replace(r,""):a||"string"!=typeof e||(n.original=e.replace(r,"")),n)},onStart:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,e,n,r){var a=e.polygon,i=n.polygon,o=i.length;t.setAttribute("d",1===r?n.original:"M"+xe(a,i,o,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].polygon,n=this.valuesEnd[t].polygon;if(!e||!n||e&&n&&e.length!==n.length){var r=Te(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision,10):d.morphPrecision),a=r[0],i=r[1];this.valuesStart[t].polygon=a,this.valuesEnd[t].polygon=i}}}},Ie={EssentialBoxModel:Y,ColorsProperties:et,HTMLAttributes:st,OpacityProperty:ct,TextWriteProp:{component:"textWriteProperties",category:"textWrite",properties:["text","number"],defaultValues:{text:" ",number:"0"},defaultOptions:{textChars:"alpha"},Interpolate:{numbers:D},functions:{prepareStart:function(){return this.element.innerHTML},prepareProperty:function(t,e){return"number"===t?parseFloat(e):""===e?" ":e},onStart:gt},Util:{charSet:vt,createTextTweens:function(t,e,n){if(t.playing)return!1;var r=n||{};r.duration=1e3,"auto"===n.duration?r.duration="auto":Number.isFinite(1*n.duration)&&(r.duration=1*n.duration);var a=j.tween,i=function(t,e){var n=bt(t,"text-part"),r=bt(mt(e),"text-part");return t.innerHTML="",t.innerHTML+=n.map((function(t){return t.className+=" oldText",t.outerHTML})).join(""),t.innerHTML+=r.map((function(t){return t.className+=" newText",t.outerHTML.replace(t.innerHTML,"")})).join(""),[n,r]}(t,e),o=i[0],s=i[1],u=[].slice.call(t.getElementsByClassName("oldText")).reverse(),c=[].slice.call(t.getElementsByClassName("newText")),l=[],p=0;return(l=(l=l.concat(u.map((function(t,e){return r.duration="auto"===r.duration?75*o[e].innerHTML.length:r.duration,r.delay=p,r.onComplete=null,p+=r.duration,new a(t,{text:t.innerHTML},{text:""},r)})))).concat(c.map((function(n,i){return r.duration="auto"===r.duration?75*s[i].innerHTML.length:r.duration,r.delay=p,r.onComplete=i===s.length-1?function(){t.innerHTML=e,t.playing=!1}:null,p+=r.duration,new a(n,{text:""},{text:s[i].innerHTML},r)})))).start=function(){t.playing||(l.forEach((function(t){return t.start()})),t.playing=!0)},l}}},TransformFunctions:{component:"transformFunctions",property:"transform",subProperties:["perspective","translate3d","translateX","translateY","translateZ","translate","rotate3d","rotateX","rotateY","rotateZ","rotate","skewX","skewY","skew","scale"],defaultValues:{perspective:400,translate3d:[0,0,0],translateX:0,translateY:0,translateZ:0,translate:[0,0],rotate3d:[0,0,0],rotateX:0,rotateY:0,rotateZ:0,rotate:0,skewX:0,skewY:0,skew:[0,0],scale:1},functions:{prepareStart:function(t){var e=C(this.element);return e[t]?e[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},a=[],i=[],o=[],s=["translate3d","translate","rotate3d","skew"];return Object.keys(e).forEach((function(t){var u="object"==typeof e[t]&&e[t].length?e[t].map((function(t){return parseInt(t,10)})):parseInt(e[t],10);if(s.includes(t)){var c="translate"===t||"rotate"===t?t+"3d":t;r[c]="skew"===t?u.length?[u[0]||0,u[1]||0]:[u||0,0]:"translate"===t?u.length?[u[0]||0,u[1]||0,u[2]||0]:[u||0,0,0]:[u[0]||0,u[1]||0,u[2]||0]}else if(/[XYZ]/.test(t)){var l=t.replace(/[XYZ]/,""),p="skew"===l?l:l+"3d",f="skew"===l?2:3,h=[];"translate"===l?h=a:"rotate"===l?h=i:"skew"===l&&(h=o);for(var d=0;d>0)/1e3)+n,a[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+a.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:Mt,skew:_t}},SVGDraw:{component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:D},functions:Pt,Util:{getRectLength:Ct,getPolyLength:Ot,getLineLength:Tt,getCircleLength:St,getEllipseLength:It,getTotalLength:jt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:At,percent:kt}},SVGMorph:{component:"svgMorph",property:"path",defaultValue:[],Interpolate:xe,defaultOptions:{morphPrecision:10},functions:Se,Util:{addPoints:_e,bisect:ke,getPolygon:Oe,validPolygon:Ce,getInterpolationPoints:Te,pathStringToPolygon:Ee,distanceSquareRoot:ae,midPoint:re,approximatePolygon:we,rotatePolygon:Me,pathToString:le,pathToCurve:function(t){if(function(t){return Rt(t)&&t.every((function(t){return"MC".includes(t[0])}))}(t))return Zt(t);for(var e=Jt(Gt(t)),n=Object.assign({},Wt),r=[],a="",i=e.length,o=0;o0?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>>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>>0,o=0;o>>0;if("function"!=typeof r&&"[object Function]"!==Object.prototype.toString.call(r))throw new TypeError;for(arguments.length>1&&(n=t),e=0;e=0?e=i:(e=n+i)<0&&(e=0);e0?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=0?n=o:(n=e+o)<0&&(n=0);n - - - - - - - - - - - - - - KUTE.js SVG Cubic Morph - - - - - - - - - - - - - -
- - - -
-

SVG Cubic Morph

-

The component that also covers SVG morphing, with similar functionality as for the SVG Morph component, but with a different - implementation for value processing and animation setup.

-
- -
-
-
-
-

Overview

-

Animate SVG paths with cubic-bezier path commands and improved performance.

-
-
-

The KUTE.js SVG Cubic Morph component enables animation for the d (description) presentation attribute and is the latest in all the SVG - components.

-

The component will process paths and out of the box will provide the closest possible interpolation by default. It also implements a series of solutions from - Paper.js to determine paths draw direction and automatically reverse one of them for most accurate presentation and as a result - the previously featured options reverseFirstPath and reverseSecondPath have been deprecated.

-

The main difference with the SVG Morph component is the fact that this components is converting all path commands to cubicBezierTo, giving it - the upper hand over the original morph component in many regards. While the other component will spend time to process the path data and create polygons, this component should - deliver the animation faster and using considerably less power.

-

All path processing is powered by our SVGPathCommander starting KUTE.js version 2.0.14, which aims to modernize and - improve the path processing and enable transition from closed to and from un-closed shapes.

-
-
-
-
- - -
-

Basic Example

-

The first morphing animation example is a transition from a rectangle into a star, just like for the other component.

- -
<svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
-<path id="rectangle" class="bg-lime" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531 c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
-<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"/>
-</svg>
-
- -

Now we can apply both .to() and fromTo() methods:

- -
// the fromTo() method
-var tween = KUTE.fromTo('#rectangle', {path: '#rectangle' }, { path: '#star' }).start();
-// OR
-// the to() method will take the path's d attribute value and use it as start value
-var tween = KUTE.to('#rectangle', { path: '#star' }).start();
-// OR
-// simply pass in a valid path string without the need to have two paths in your SVG
-var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011' }).start();
-
- -

By default, the component will process the paths as authored and deliver its best without any option required, like for the first red rectangle below which applies to any of the above invocations:

- -
- - - - - - - - -
- Start -
-
- -

Some takeaways:

-
    -
  • The olive shape and its corresponding end shape are both the originals, un-edited shapes.
  • -
  • The blue shape and its corresponding end shape have been edited by removing their Z path commands and by adding additional curve points using a vector graphics editor to match - the amount of points in both shapes.
  • -
-

In this example we focus on experimentation to discover ways to optimize the morph animation so that the points travel optimal distance. Keep in mind that the Z path command is actually a shorthand - for L (line path command), sometimes it's required to close the shape, however the path processing tools will remove it or replace it when converting path segments to C cubic-bezier.

-

Each morph animation as well as each pair of shapes can have its own quirks. You can use the technique on your shapes to optimize the animation to your style. Chris Coyier wrote - an excelent article in which he explains the terminology and workflow on how SVG morphing animation works with simple examples.

- - -

Morphing Unclosed Shapes To Closed Shapes

-

The next set of morphing animations is a transition from a line into a circle and showcases the component's behavior when both shapes are closed (they have the Z path command) or one or another is not, - but first let's create the necessary markup and scripting:

- -
<svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
-<path id="line" fill="transparent" stroke="orange" stroke-linejoin="round" stroke-width="10" d="M10 300 L580 300"/>
-<path id="star" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
-</svg>
-
- -
// the fromTo() method
-var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
-// OR
-// the to() method will take the path's d attribute value and use it as start value
-var tween = KUTE.to('#line', { path: '#circle' }).start();
-
- -
- - - - - - - - -
- Start -
-
- -

As you can see, the functionality of this component is very different from the svgMorph component in the sense that it will - morph shapes as authored. If you replay the above animations, here are a few takeaways:

-
    -
  • the orange line is closed, this makes the last Z path command behave like a regular line;
  • -
  • the green line is not closed, and the presentation looks quite different compared to the other example as well as - the other cubicMorph component.
  • -
-

This is the visual presentation you can expect with this component. Keep in mind that stroke attributes like stroke-linejoin such can have - a small impact on your animation, particularly on start and end points.

- - -

Subpath Example

-

In other cases, you may want to morph paths that have subpaths. Let's have a look at the following SVG:

- -
<svg id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
-<path id="w1" d="M412.23 511.914c-47.708-24.518-94.086-36.958-137.88-36.958-5.956 0-11.952 0.18-17.948 0.708-55.88 4.624-106.922 19.368-139.75 30.828-8.708 3.198-17.634 6.576-26.83 10.306l-89.822 311.394c61.702-22.832 116.292-33.938 166.27-33.938 80.846 0 139.528 30.208 187.992 61.304 22.962-77.918 78.044-266.09 94.482-322.324-11.95-7.284-24.076-14.57-36.514-21.32z 
-  m116.118 79.156l-90.446 314.148c26.832 15.372 117.098 64.05 186.212 64.05 55.792 0 118.252-14.296 190.834-43.792l86.356-301.976c-58.632 18.922-114.876 28.52-167.464 28.52-95.95 0-163.114-31.098-205.492-60.95z 
-  m-235.526-222.28c77.118 0.798 134.152 30.208 181.416 60.502l92.752-317.344c-19.546-11.196-70.806-39.094-107.858-48.6-24.386-5.684-50.02-8.616-77.204-8.616-51.796 0.976-108.388 13.946-172.888 39.8l-88.44 310.596c64.808-24.436 120.644-36.34 172.086-36.34 0.046 0.002 0.136 0.002 0.136 0.002z 
-  m731.178-170.666c-58.814 22.832-116.208 34.466-171.028 34.466-91.686 0-159.292-31.802-203.094-62.366l-91.95 318.236c61.746 39.708 128.29 59.878 198.122 59.878 56.948 0 115.94-13.68 175.462-40.688l-0.182-2.222 3.734-0.886 88.936-306.418z"/>
-<path id="w2" d="M0 187.396l367.2-50.6v354.798h-367.2v-304.2z 
-  m0 649.2v-299.798h367.2v350.398z 
-  m407.6 56v-355.798h488.4v423.2z 
-  m0-761.2l488.4-67.4v427.6h-488.4v-360.2z"/>
-</svg>
-
- -

Similar to the svgMorph component, this component doesn't provide multipath processing so we should split the sub-paths into multiple <path> shapes, analyze and associate them - in a way that corresponding shapes are close and their points travel the least possible distance.

- -

Now since we've worked with these paths before, the first example below showcases how the svgCubicMorph component handles it by default. The following example was made possible by editing the shapes with a vector - graphics editor. The last example showcases a creative use of association between starting and end shapes. Let's have a look:

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Start -
-
-

Make sure to check the markup here as well as the svgCubicMorph.js for a full code review.

- -

Intersecting Paths Example

-

The same preparation apply here, however the outcome is a bit different with cubic-bezier path commands, as shown in the first example. For the next two examples, the shapes have been edited for a better outcome. - Let's have a look:

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Start -
-
- -

So the technique involves creating <mask> elements, splitting multipath shapes into multiple <path> shapes, matching the amount of starting and ending shapes by duplicating - an existing shape or by sampling another shape for the same purpose, editing shapes for more accurate point-to-point animation, as well as various options to optimize the visual presentation.

- -

That's it, you now mastered the SVG Cubic Morph component.

- -

Notes

-
    -
  • Starting with KUTE.js version 2.0.14 the component implements SVGPathCommander for path processing, solving previous issues with over-optimized - path strings among other issues. You can try the SVGPathCommander demo page to prepare your path strings.
  • -
  • Since animation works only with path SVGElements, you might need a shapeToPath utility.
  • -
  • Both SVG morph components will always animate first sub-path from both starting and ending shapes, and for any case hopefully this demo will guide you in mastering the technique.
  • -
  • In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or SVGPathCommander - to apply a scale transformation to your shapes' path commands.
  • -
  • The SVG Cubic Morph component WILL NOT animate paths with sub-paths as of KUTE.js version 2.0.14, hopefuly this guide will help you break the ice.
  • -
  • Compared to svgMorph, this component can be more memory efficient, as we're dealing with significantly less interpolation points which translates directly - into better performance and the shapes never show any sign of "polygon artifacts".
  • -
  • Some shapes can be broken even if the browser won't throw any error so make sure you double check with your SVG editor of choice.
  • -
  • In some cases the duplicated curve bezier points don't produce the best morphing animation, but you can edit the shapes and add your own additional path commands between the existing ones - so that the component will work with actual points that travel less and produce a much more "natural" morphing animation.
  • -
  • The edited shapes can be found in the assets/img folder of this demo, make sure to check them out.
  • -
  • Make sure to check the svgCubicMorph.js for a full code review.
  • -
  • This component is affected by the the fill-rule="evenodd" specific SVG attribute, you must make sure you check your shapes in that regard as well.
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • -
-
- - - - -
- - - - - - - - - - - - - diff --git a/demo/svgDraw.html b/demo/svgDraw.html deleted file mode 100644 index 4855c12..0000000 --- a/demo/svgDraw.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - - - KUTE.js SVG Draw - - - - - - - - - - - - -
- - - -
-

SVG Draw

-

The component that animates the stroke of any SVGElement and updates the style attribute of the target.

-
- -
-
-
-
-

Overview

-

Animate the stroke for most SVGElement shapes, with a very easy to use coordinates system.

-
-
-

The KUTE.js SVG Draw component enables animation for the stroke-dasharray and stroke-dashoffset properties via CSS style.

-

The component uses the SVG standard .getTotalLength() method for <path> shapes, while for the other shapes it uses some helper methods to calculate the values - required for animation.

-

It can work with <path>, <glyph>, <circle>, <ellipse>, <rect>, <line>, <polyline> and <polygon> - shapes. It uses a very simple to use coordinates system so you can set up animations right away.

-

As you will see in the examples below, there is alot of flexibility in terms of input values.

-
-
-
-
- -
-

Examples

- -
// draw the stroke from 0-10% to 90-100%
-var tween1 = KUTE.fromTo('selector1',{draw:'0% 10%'}, {draw:'90% 100%'});
-
-// draw the stroke from zero to full path length
-var tween2 = KUTE.fromTo('selector1',{draw:'0% 0%'}, {draw:'0% 100%'});
-
-// draw the stroke from full length to 50%
-var tween3 = KUTE.fromTo('selector1',{draw:'0% 100%'}, {draw:'50% 50%'});
-
- - -

Based on the above sample code, let's see some animation going on:

- -
- - - - - - - -
- Start -
-
- - -

Notes

-
    -
  • Remember that the draw property also accepts absolute values, eg. draw: '0 150'; the .to() method takes 0% 100% - as start value for your tweens when stroke-dasharray and stroke-dashoffset properties are not set.
  • -
  • Sometimes the stroke on some shapes may not completely close, you might want to consider values outside the [0-100] percent range.
  • -
  • The SVG Draw component can be combined with any other SVG based component to create even more complex animations for SVG elements.
  • -
  • This component is bundled with the default distribution kute.js and the demo/src/kute-extra.js file.
  • -
-
- - - - - -
- - - - - - - - - - - - - - - diff --git a/demo/svgMorph.html b/demo/svgMorph.html deleted file mode 100644 index a23fdf1..0000000 --- a/demo/svgMorph.html +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - - - - - - - - - KUTE.js SVG Morph - - - - - - - - - - - - -
- - - -
-

SVG Morph

-

The component that covers SVG morphing, an animation that's close to impossible with CSS3 transitions and not supported in some legacy browsers. It comes packed - with tools and options to improve performance and visual presentation.

-
- -
-
-
-
-

Overview

-

Animate SVG paths with line-to path commands, improve visual presentation and optimize performance on any device.

-
-
-

The KUTE.js SVG Morph component enables animation for the d (description) presentation attribute and is one of the most important in all the - SVG components.

-

It only works with inline SVGPathElement shapes and the presentation is always the same when shapes are closed or not (their d attribute ends with Z path command). - On initialization or animation start, depending on the chosen KUTE.js method, it will sample a number of points - along the two paths based on a default / given sample size and will create two arrays of coordinates we need for interpolation.

-

This component was originally inspired by a D3.js path morphing example and now implements a set of - D3 polygon geometric operations and other functionalities from flubber to - produce the coordinates for a very consistent morphing animation.

-

While in some cases you might be able to create SVG morphing animations via CSS3 transition, this component was developed to provide various solutions for working - with complex shapes, bringing convenience, resources and clarity to one of the most complex types of animation.

-

All path processing is powered by our SVGPathCommander starting KUTE.js version 2.0.14, which aims to modernize and - improve the path processing and enable you to prepare your path strings in Node.js.

-
-
- -
-
-

Options

-

The easy way to optimize morphing animation for every device in a single option.

-
-
-

The SVG Morph component comes with a simple option to optimize animation on every device. Previous versions used to have additional options required for processing, - but now the component will handle all that for you.

- -
    -
  • morphPrecision: Number option allows you to set the sampling size of the shapes in pixels. The lesser value the better visual but the more power consumption - and less performance. The default value is 10 but the processing functions will determine the best possible outcome depending on shapes' path commands.
  • -
-
-
-
-
- -
- -

Basic Example

-

The first morphing animation example is a transition from a rectangle into a star, the first path is the start shape and the second is the end shape; we can also add some ID to the - paths so we can easily target them with our code.

- -
<svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
-  <path id="rectangle" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531 c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"/>
-  <path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808 l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"/>
-</svg>
-
- -

Now we can apply both .to() and fromTo() methods:

- -
// the fromTo() method
-var tween = KUTE.fromTo('#rectangle', {path: '#rectangle' }, { path: '#star' }).start();
-// OR
-// the to() method will take the path's d attribute value and use it as start value
-var tween = KUTE.to('#rectangle', { path: '#star' }).start();
-// OR
-// simply pass in a valid path string without the need to have two paths in your SVG
-var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011' }).start();
-
- -

For all the above tween objects the animation should look like this:

- -
- - - - -
- Start -
-
- -

That's it, let move on to the next example.

- -

Morphing Unclosed Shapes To Closed Shapes

-

The next morphing animation example is a transition from a line into a circle and this example showcases the component's behavior when one of the paths is not closed (it doesn't have the Z path command), - while the other is closed. In all cases, the component will always consider shapes to be closed, so let's have a look at the example:

- -
<svg id="morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
-  <path id="line" fill="transparent" stroke="orange" stroke-linejoin="round" stroke-width="10" d="M10 300L590 300"/>
-  <path id="circle" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
-</svg>
-
- -

Now we can apply both .to() and fromTo() methods:

- -
// the fromTo() method
-var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
-// OR
-// the to() method will take the path's d attribute value and use it as start value
-var tween = KUTE.to('#line', { path: '#circle' }).start();
-
- -
- - - - - - - - -
- Start -
-
- -

The functionality of this component is different from the svgCubicMorph component in the sense that it will animate the shapes as if they are both and always closed. - In the above example, the orange line is closed while the green line is not, and the animation is the same.

- - -

Polygon Paths

-

When your paths are only lineto, vertical-lineto and horizontal-lineto based shapes (the d attribute consists of only L, V and - H path commands), the SVG Morph component will work differently from previous versions, it will sample points as for any other non-polygon shapes. In this case you can set a higher - morphPrecision value to optimize performance.

- -
// let's morph a triangle into a star
-var tween1 = KUTE.to('#triangle', { path: '#star' }).start();
-
-// or same path into a square
-var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
-
- -
- - - - - - - - - - - - - -
- Start -
-
-

Did you catch the cat?

- - -

Subpath Example

-

In other cases, you may want to morph paths that have subpaths. Let's have a look at the following paths:

-
<svg id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
-  <path id="w1" d="M412.23 511.914c-47.708-24.518-94.086-36.958-137.88-36.958-5.956 0-11.952 0.18-17.948 0.708-55.88 4.624-106.922 19.368-139.75 30.828-8.708 3.198-17.634 6.576-26.83 10.306l-89.822 311.394c61.702-22.832 116.292-33.938 166.27-33.938 80.846 0 139.528 30.208 187.992 61.304 22.962-77.918 78.044-266.09 94.482-322.324-11.95-7.284-24.076-14.57-36.514-21.32z 
-  m116.118 79.156l-90.446 314.148c26.832 15.372 117.098 64.05 186.212 64.05 55.792 0 118.252-14.296 190.834-43.792l86.356-301.976c-58.632 18.922-114.876 28.52-167.464 28.52-95.95 0-163.114-31.098-205.492-60.95z 
-  m-235.526-222.28c77.118 0.798 134.152 30.208 181.416 60.502l92.752-317.344c-19.546-11.196-70.806-39.094-107.858-48.6-24.386-5.684-50.02-8.616-77.204-8.616-51.796 0.976-108.388 13.946-172.888 39.8l-88.44 310.596c64.808-24.436 120.644-36.34 172.086-36.34 0.046 0.002 0.136 0.002 0.136 0.002z 
-  m731.178-170.666c-58.814 22.832-116.208 34.466-171.028 34.466-91.686 0-159.292-31.802-203.094-62.366l-91.95 318.236c61.746 39.708 128.29 59.878 198.122 59.878 56.948 0 115.94-13.68 175.462-40.688l-0.182-2.222 3.734-0.886 88.936-306.418z"/>
-  <path id="w2" d="M0 187.396l367.2-50.6v354.798h-367.2v-304.2z 
-  m0 649.2v-299.798h367.2v350.398z 
-  m407.6 56v-355.798h488.4v423.2z 
-  m0-761.2l488.4-67.4v427.6h-488.4v-360.2z"/>
-</svg>
-
-

As you can see, both these paths have subpaths, and this component will only animate the first subpath from both paths. To animate them all there are a few easy steps required in preparation for - the animation, so here's a quick guide:

-
    -
  1. Use the SVGPathCommander demo page to split your path string into multiple sub-path strings. It's important to do this to avoid - inconsistencies with shapes having relative sub-path commands. You can also use the utility to reverse paths if required.
  2. -
  3. Create a new <path> shape for each sub-path string from M to Z path commands. See the sample code below.
  4. -
  5. Give the new paths an id="uniqueID" attribute so you can target them easily. You could use relevant namespace to help you better understand positioning. EG: id="square-top-left" - or id="left-eye"
  6. -
  7. In the browser console inspect with your mouse all paths from both starting and ending shapes and determine which shapes should morph to which. The idea is to produce a morphing animation - where points from each shape travel the least possible distance, however this is where you can get creative, as shown in one of the examples below.
  8. -
  9. If the number of the starting and ending shapes are not equal, you can consider either duplicating one of the subpath shapes close to it's corresponding subpath shape or creating a sample - shape close to the corresponding subpath shape.
  10. -
  11. Update the id attribute for all starting and ending shapes to match positions and make it easier to work with the tween objects.
  12. -
  13. Optional: set a fill attribute for each new shape if you like, normally you coulnd't have done it with the original paths.
  14. -
  15. Create your tween objects and get to animating and tweaking.
  16. -
- -

For our example here, this is the end result markup for the shapes to be used for morphing animation:

- -
<svg id="multi-morph-example" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 550">
-  <path id="w11" d="M206.115,255.957c-23.854-12.259-47.043-18.479-68.94-18.479c-2.978,0-5.976,0.09-8.974,0.354 c-27.94,2.312-53.461,9.684-69.875,15.414c-4.354,1.599-8.817,3.288-13.415,5.152L0,414.096 c30.851-11.416,58.146-16.969,83.135-16.969c40.423,0,69.764,15.104,93.996,30.652c11.481-38.959,39.022-133.045,47.241-161.162 C218.397,262.975,212.334,259.332,206.115,255.957z"/>
-  <path id="w12" d="M264.174,295.535l-45.223,157.074c13.416,7.686,58.549,32.024,93.105,32.024 c27.896,0,59.127-7.147,95.417-21.896l43.179-150.988c-29.316,9.461-57.438,14.26-83.732,14.26 C318.945,326.01,285.363,310.461,264.174,295.535z"/>
-  <path id="w13" d="M146.411,184.395c38.559,0.399,67.076,15.104,90.708,30.251l46.376-158.672c-9.772-5.598-35.403-19.547-53.929-24.3c-12.193-2.842-25.01-4.308-38.602-4.308c-25.898,0.488-54.194,6.973-86.444,19.9 L60.3,202.564c32.404-12.218,60.322-18.17,86.043-18.17C146.366,184.395,146.411,184.395,146.411,184.395L146.411,184.395z"/>
-  <path id="w14" d="M512,99.062c-29.407,11.416-58.104,17.233-85.514,17.233c-45.844,0-79.646-15.901-101.547-31.183L278.964,244.23 c30.873,19.854,64.146,29.939,99.062,29.939c28.474,0,57.97-6.84,87.73-20.344l-0.091-1.111l1.867-0.443L512,99.062z"/>
-
-  <path id="w21" style="visibility:hidden" d="M192 471.918l-191.844-26.297-0.010-157.621h191.854z"/>
-  <path id="w22" style="visibility:hidden" d="M479.999 288l-0.063 224-255.936-36.008v-187.992z"/>
-  <path id="w23" style="visibility:hidden" d="M0.175 256l-0.175-156.037 192-26.072v182.109z"/>
-  <path id="w24" style="visibility:hidden" d="M224 69.241l255.936-37.241v224h-255.936z"/>
-</svg>
-
- -

The graphic on the left side of the below example is exactly for the above markup, no option needed out of the box nearly perfect animation, while the right side example showcases a different or - perhaps more creative example of this morph animation:

- - -
- - - - - - - - - - - - - - - - - - - - - - -
- Start -
-
- -

As you can imagine, it's quite hard if not impossible to code something that would do all this work automatically. Perhaps in the future we could have dedicated AI powered APIs to train and - program for this work, but until then, it's up to you to learn, observe, adapt and tweak in order to get the most out of this component.

- -

Intersecting Paths Example

-

The last morph example is a bit more complex as the paths have intersecting subpaths with different positions as well as different amounts of subpaths. In this case you can manually clone one or - more subpaths in a way that the number of starting shapes is equal to the number of ending shapes, as well as making sure the starting shapes are close to their corresponding ending shapes; at this point - you should be just like in the previous examples.

- -

You need to inspect the markup here in your browser console to get an idea on how the shapes have been arranged, we have used a <mask> where we included the subpaths of both start - and end shape, just to get the same visual as the original paths.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Start -
-
- -

The example on the left side showcases the cloning of one of the shapes to match the amount of starting and ending shapes, while the right side showcases - using a sample shape, somewhere close to its corresponding end shape, a much better animation, but in the end, it's up to you and your need on preparing, - analyzing as well as deciding on how to optimize these cases.

- - -

Notes

-
    -
  • Starting with KUTE.js version 2.0.14 the component implements SVGPathCommander for path processing, solving previous issues with over-optimized - path strings among other issues. You can try the SVGPathCommander demo page to prepare your path strings.
  • -
  • Since SVG Morph animation works only with path elements, you might need a convertToPath feature, so - grab one here.
  • -
  • Both SVG morph components will always animate first sub-path from both starting and ending shapes, and for any case hopefully this demo will guide you in mastering the technique.
  • -
  • In some cases your start and end shapes don't have a very close size, you can use your vector graphics editor of choice or SVGPathCommander - to apply a scale transformation to your shapes' path commands.
  • -
  • The morphing animation is expensive so try to optimize the number of morph animations that run at the same time. When morphing sub-paths/multi-paths instead of cloning shapes to have same number - of shapes in both starting and ending shapes, you should also consider a fade and/or scale animation to improve the overal animation performance, mobile devices still don't do very much, regardless - of the advertising.
  • -
  • Large displays would need best resolution possible so a small morphPrecision value (1-10) would be required, assuming performant hardware are powering the displays. For small displays - you can get quite comfortable with almost any value, including the default value.
  • -
  • With all the tools at hand, you can also try to use a morphPrecision value for every resolution. Take some time to experiement, you might find a better morphPrecision - value you can use for any particular device and / or resolution.
  • -
  • The animation performance is the same for both .to() and .fromTo() methods, but the ones that use the second method will start faster, because the values have been prepared - already and for the first method the processing of the two paths happens on tween .start() call, thus delaying the animation, so keep that in mind when working with syncing multiple tweens, - the .to() based morph will always start later. Of course this assumes the you cache the tween objects first and start the animation later, if not (you start the animation on object creation), - both methods will be delayed.
  • -
  • The SVG Morph component uses approximatelly the same algorithm as D3.js for determining the coordinates for interpolation, the visual presentation is more natural compared to the other component, - it might be a better solution for your applications.
  • -
  • Make sure to check the svgMorph.js for a full code review.
  • -
  • This component should ignore the fill-rule="evenodd" specific SVG attribute, but you can make sure you check your shapes in that regard as well.
  • -
  • This component is bundled with the official kute.js distribution file.
  • -
-
- - - - -
- - - - - - - - - - - - diff --git a/demo/svgTransform.html b/demo/svgTransform.html deleted file mode 100644 index d20d663..0000000 --- a/demo/svgTransform.html +++ /dev/null @@ -1,389 +0,0 @@ - - - - - - - - - - - - - - KUTE.js SVG Transform - - - - - - - - - - - - - -
- - - -
-

SVG Transform

-

The component that covers transform animation on SVGElement targets, solves browser inconsistencies and provides a similar visual presentation as - with other transform based components on non-SVGElements targets.

-
- -
-
-
-
-

Overview

-

Animate 2D transform functions on SVG elements on any SVG enabled browser.

-
-
-

The KUTE.js SVG Transform component enables animation for the transform presentation attribute on any SVGElement target.

-

The SVG Transform is an important part of the SVG components for some reasons:

-
    -
  • It was developed to solve most browser inconsistencies of the time for transform animation. Nowadays modern browsers are Chromium browsers that work with regular 2D - transform functions.
  • -
  • The unique way to normalize translation to produce the kind of animation that is just as consistent as for CSS3 transforms on non-SVGElement targets.
  • -
  • The value processing is consistent with the current W3 draft.
  • -
-

Keep in mind that the transform attribute accepts no measurement units such as degrees or pixels, but it expects rotation / skew angles to be in degrees, and - translations in lengths measured around the parent <svg> element viewBox attribute.

-
-
-
-
-

Options

-

Keep everything under control and handle any situation with a single option.

-
-
-

The only component that keeps the transformOrigin option because it's required to compute transform functions in the SVG - cooordinates system.

- -
    -
  • transformOrigin: ['50%','50%'] sets the much needed origin. Eg: transformOrigin:[50,50]. The default - value is 50% 50% of the target element box, which is contrary with the SVG draft.
  • -
- -

Keep in mind that the component will disregard the current SVG default origin of 0px 0px of the target's parent, even if the browsers' default - transformOrigin have been normalized over the years.

- -

The transformOrigin tween option can also be used to set coordinates of a parent <svg> element (in the second example below). - Values like top left values are also accepted, but will take the target element's box as a reference, not the parent's box.

-
-
-
-
- -
- -

2D Transform

-
    -
  • translate function applies horizontal and / or vertical translation. EG. translate:150 to translate a shape 150px to the right or - translate:[-150,200] to move the element to the left by 150px and to bottom by 200px. IE9+
  • -
  • rotate function applies rotation to a shape on the Z axis. Eg. rotate:150 will rotate a shape clockwise by 150 degrees around it's own center or around - the transformOrigin: '450 450' set tween option coordinate of the parent element. IE9+
  • -
  • skewX function used to apply a skew transformation on the X axis. Eg. skewX:25 will skew a shape by 25 degrees. IE9+
  • -
  • skewY function used to apply a skew transformation on the Y axis. Eg. skewY:25 will skew a shape by 25 degrees. IE9+
  • -
  • scale function used to apply a single value size transformation. Eg. scale:0.5 will scale a shape to half of it's initial size. IE9+
  • -
  • matrix function is not supported, but the Transform Matrix covers you there, if you'll read below.
  • -
- -

Examples

-

As explained with the Transform Matrix component, the DOMMatrix API will replace webkitCSSMatrix and SVGMatrix and on this page we intend to put - the two components head to head, the elements on the left will be using Transform Matrix component and equivalent 2D transform functions, while the elements on the right will be using 2D functions of - the SVG Transform component.

- -

The SVG Transform component comes with a reliable set of scripts that work on all browsers, making use of the SVGMatrix API for some origin calculation, the transform presentation - attribute and the svgTransform tween property with a familiar and very easy notation:

- -
// using the svgTransform property works in all SVG enabled browsers
-var tween2 = KUTE.to(
-'shape',                // target
-{                       // to
-  svgTransform: { 
-    translate: [150,100], 
-    rotate: 45, 
-    skewX: 15, skewY: 20, 
-    scale: 1.5 
-  }
-}
-);
-
-// transformMatrix can animate SVGElement targets on modern browsers
-// requires adding styling like `transform-origin:50% 50%` to the target element
-var tween1 = KUTE.to(
-'shape',            // target
-{                   // to
-  transform: { 
-    translate3d: [150,100,0], 
-    rotate3d: [0,0,45], 
-    skew: [15,20], 
-    scale3d: [1.5,1.5,1] 
-  } 
-}
-);
-
- -

Let's see some examples and explain each case.

- - -

SVG Rotation

-

Our first chapter of the SVG transform is all about rotations, perhaps the most important part here. The svgTransform will only accept single value - for the angle value rotate: 45, the rotation will go around the shape's center point by default, again, contrary to the browsers' default value and you can set a transformOrigin - tween option to override the behavior.

-

The argument for this implementation is that this is something you would expect from regular HTML elements rotation and probably most needed, not to mention the amount of savings in the codebase department. - Let's have a look at a quick demo:

- -
- - - - - -
- Start -
-
-

For the first element, the Transform Matrix creates the rotation animation via rotate3d[0,0,360] tween property around the element center coordinate, as we've set transform-origin:25% 50% - to the element's style; this animation doesn't work in IE browsers, while in older versions Firefox the animation is inconsistent. The second element uses the rotate: 360 function of the SVG Transform - component and the rotation animation is around the element's own central point without any option, an animation that DO WORK in all SVG enabled browsers.

- -

When for non-SVG elements' transform we could have used values such as center bottom as transformOrigin (also not supported in all modern browsers for SVGs), the entire processing falls - to the browser, however when it comes to SVGs our component here will compute the transformOrigin tween option value accordingly to use the shape's .getBBox() value to determine - for instance the coordinates for 25% 75% position or center top.

- -

In other cases you may want to rotate shapes around the center point of the parent <svg> or <g> element, and we use it's .getBBox() to determine the 50% 50% - coordinate, so here's how to deal with it:

- -
// rotate around parent svg's "50% 50%" coordinate as transform-origin
-// get the bounding box of the parent element
-var svgBB = element.ownerSVGElement.getBBox(); // returns an object of the parent <svg> element
-
-// we need to know the current translate position of the element [x,y]
-// in our case is:
-var translation = [580,0];
-
-// determine the X point of transform-origin for 50%
-var OriginX = svgBB.width * 50 / 100 - translation[0];
-
-// determine the Y point of transform-origin for 50%
-var OriginY = svgBB.height * 50 / 100 - translation[1];
-
-// set your rotation tween with "50% 50%" transform-origin of the parent <svg> element
-var rotationTween = KUTE.to(element, {svgTransform: {rotate: 150}}, { transformOrigin: [OriginX, OriginY]} );
-
- -
- - - - - -
- Start -
-
-

Same as the above example, the first element is rotated by the Transform Matrix component and is using transform-origin: 50% 50%; styling, while the second element is rotated by the SVG Transform - component with the above calculated transform-origin.

- -

SVG Translation

-

In this example we'll have a look at translations, so when setting translate: [150,0], the first value is X (horizontal) coordinate to which the shape will translate to and the second value is - Y (vertical) coordinate for translation. When translate: 150 notation is used, the script will understand that's the X value and the Y value is 0 just like for the regular HTML elements - transformation. Let's have a look at a quick demo:

- -
- - - - - -
- Start -
-
-

The first element uses the Transform Matrix translate3d: [580,0,0] function, while the second tween uses the translate: [0,0] as svgTransform value. - For the second example the values are unitless and are relative to the viewBox attribute.

- -

SVG Skew

-

For skews we have: skewX: 25 or skewY: -25 as SVGs don't support the skew: [X,Y] function. Here's a quick demo:

-
- - - - - -
- Start -
-
-

The first tween skews the shape on both X and Y axes in a chain via Transform Matrix skew:[-15,-15] function and the second tween skews the shape on X and Y axes via the svgTransform functions skewX:15 and - skewY:15 tween properties. You will notice translation kicking in to set the transform origin.

- -

SVG Scaling

-

Another transform example for SVGs is the scale. Unlike translations, for scale animation the component only accepts single value like scale: 1.5, for both X (horizontal) axis and Y (vertical) axis, - to keep it simple and even if SVGs do support scale(X,Y). But because the scaling on SVGs depends very much on the shape's position, the script will always try to adjust the translation to - make the animation look as we would expect. A quick demo:

-
- - - - - -
- Start -
-
-

The first tween scales the shape at scale: 1.5 via Transform Matrix component and it's scale3d:[1.5,1.5,1] function, and the second tween scales down the shape at scale: 0.5 - value via svgTransform. If you inspect the elements, you will notice for the second shape translation is involved, and this is to keep transform-origin at an expected - 50% 50% of the shape box. A similar case as with the skews.

- -

Mixed SVG Transform Functions

-

Our last transform example for SVG Transform is the mixed transformation. Just like for the other examples the component will try to adjust the rotation transform-origin to make it look as you would expect it - from regular HTML elements. Let's combine 3 functions at the same time and see what happens:

-
- - - - - -
- Start -
-
-

Both shapes are scaled at scale: 1.5, translated to translate: 250 and skewed at skewX: -15. If you inspect the elements, you will notice the second shape's translation is - different from what we've set in the tween object, and this is to keep transform-origin at an expected 50% 50% value. This means that the component will also compensate rotation transform origin - when skews are used, so that both CSS3 transform property and SVG transform attribute have an identical animation.

- -

Chained SVG Transform

-

The SVG Transform does not work with SVG specific chained transform functions right away (do not confuse with tween chain), Ana Tudor explains best here, - but if your SVG elements only use this feature to set a custom transform-origin, it should look like this:

- -
<svg>
-  <circle transform="translate(150,150) rotate(45) scale(1.2) translate(-150,-150)" r="20"></circle>
-</svg>
-
- -

In this case I would recommend using the values of the first translation as transformOrigin for your tween built with the .fromTo() method like so:

- -
// a possible workaround for animating a SVG element that uses chained transform functions
-KUTE.fromTo(element,
-  {svgTransform : { translate: 0, rotate: 45, scale: 0.5 }}, // we asume the current translation is zero on both X & Y axis
-  {svgTransform : { translate: 450, rotate: 0, scale: 1.5 }}, // we will translate the X to a 450 value and scale to 1.5
-  {transformOrigin: [150,150]} // tween options use the transform-origin of the target SVG element
-).start();
-
- -

Before you hit the Start button, make sure to check the transform attribute value. The below tween will reset the element's transform attribute to original value when the animation is complete.

-
- - - - -
- Start -
-
-

This way we make sure to count the real current transform-origin and produce a consistent animation with the SVG coordinate system, just as the above example showcases.

- -

Notes

-
    -
  • The SVG Transform component is successfuly handling all possible combinations of transform functions, and always uses same order of transform functions: translate, - rotate, skewX, skewY and scale to keep animation consistent and with same aspect as for CSS3 transforms on non-SVG elements.
  • -
  • Keep in mind that the SVG transform functionss will use the center of a shape as transform origin by default, contrary to the SVG draft.
  • -
  • Keep in mind the adjustments required for rotations, remember the .getBBox() method, it's really useful to set custom transform-origin.
  • -
  • By default browsers use overflow: hidden for <svg> so child elements are partialy/completely hidden while animating. You might want to set overflow: visible - or some browser specific tricks if that is the case.
  • -
  • When using viewBox="0 0 500 500" attribute for <svg> and no width and/or height attribute(s), means that you expect the SVG to be scalable and most - Internet Explorer versions simply don't work. You might want to check this tutorial.
  • -
  • In other cases when you need maximum control and precision or when shapes are already affected by translation, you might want to use the .fromTo() method with all proper values.
  • -
  • Also the svgTransform tween property does not support 3D transforms, because they are not supported in all SVG enabled browsers.
  • -
  • The SVG Transform component cannot work with the transformOrigin set to an SVGElement via CSS, you must always use a it's specific option.
  • -
  • The component can be combined with the HTML Attributes component to enable even more advanced/complex animations for SVG elements.
  • -
  • Keep in mind that older browsers like Internet Explorer 8 and below as well as stock browser from Android 4.3 and below do not support inline SVG - so make sure to fiter your SVG tweens properly.
  • -
  • While you can still use regular CSS3 transforms for SVG elements, everything is fine with Google Chrome, Opera and other webkit browsers, but older Firefox versions struggle with the percentage based - transformOrigin values and ALL Internet Explorer versions have no implementation for CSS3 transforms on SVG elements, which means that the SVG Transform component will become a fallback - component to handle legacy browsers in the future. Guess who's taking over :)
  • -
  • This component is bundled with the demo/src/kute-extra.js file.
  • - -
- -
- - - - -
- - - - - - - - - - - - - - - - diff --git a/demo/textProperties.html b/demo/textProperties.html deleted file mode 100644 index 8408346..0000000 --- a/demo/textProperties.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Text Properties - - - - - - - - - - - - - - -
- - - -
-

Text Properties

-

The component that animates the typographic CSS properties of a target content Element on most browsers.

-
- -
-
-
-
-

Overview

-

Animate the text size or spacing properties of a target text element.

-
-
-

The KUTE.js Text Properties component enables animation for typography related CSS properties of content element targets - on most browsers.

-

This small and simple component can be used to create various attention seekers for any content elements such as HTMLHeadingElement, - HTMLParagraphElement, HTMLUListElement or any other, as well as for entire content blocks.

-

You can either animate an entire string or content block or split your string into words or letters and create a simple animation with one or more of - the following properties:

-
-
-
-
- -
- -

Supported Properties

- -
    -
  • fontSize allows you to animate the font-size for a target element.
  • -
  • lineHeight allows you to animate the line-height for a target element.
  • -
  • letterSpacing allows you to animate the letter-spacing for a target element.
  • -
  • wordSpacing allows you to animate the word-spacing for a target element.
  • -
- -

Example

- -
let tween1 = KUTE.to('selector1',{fontSize:'200%'})
-let tween2 = KUTE.to('selector1',{lineHeight:24})
-let tween3 = KUTE.to('selector1',{letterSpacing:50})
-let tween3 = KUTE.to('selector1',{wordSpacing:50})
-
- -
-

Howdy!

- -
- -

Notes

-
    -
  • Be sure to check the textProperties.js for a more in-depth review of the above example.
  • -
  • Similar to box model properties, the text properties are also layout modifiers, they will push the layout around forcing unwanted re-paint work. To avoid re-paint, you - can use a fixed height for the target element's container, as we used in our example here, or set your text to position:absolute.
  • -
  • The component is only included in the demo/src/kute-extra.js file.
  • -
- -
- - - - -
- - - - - - - - - - - - - - diff --git a/demo/textWrite.html b/demo/textWrite.html deleted file mode 100644 index a02e592..0000000 --- a/demo/textWrite.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - KUTE.js TextWrite - - - - - - - - - - - - - - -
- - - -
-

Text Write

-

The component that enables a unique animation by manipulating the string content of Element targets on most browsers.

-
- -
-
-
-
-

Overview

-

Manipulate string contents with ease.

-
-
-

The KUTE.js Text Write component enables animation for content Element targets by manipulating their string contents.

-

The component provides two properties:

-
    -
  • number: NUMBER - interpolate the string numbers by increasing or decreasing their values
  • -
  • text: STRING - will add/remove a content string one character at a time
  • -
-

This text property comes with an additional tween option called textChars for the scrambling text character, with the following expected values:

-
    -
  • alpha use lowercase alphabetical characters, the default value
  • -
  • upper use UPPERCASE alphabetical characters
  • -
  • numeric use numerical characters
  • -
  • symbols use symbols such as #, $, %, etc.
  • -
  • all use all alpha numeric and symbols.
  • -
  • YOUR CUSTOM STRING use your own custom characters; eg: 'KUTE.JS IS #AWESOME'.
  • -
-

It's always best to wrap your target number in a <span id="uniqueID"> for the number property and content targets should be split into - multiple parts for the text property if the target has child contents, as we will see in the examples below.

-
-
-
-
- - -
- -

Examples

- -

The effect of these two properties is very popular, so let's go through some quick examples to explain the workflow for the best possible outcome. We will try to focus - on the text property a bit more because we can optimize the content targets for a great visual experience.

- -

Number Property

-

As discussed above, the target number need to be wrapped in a tag of choice with a unique ID so we can target it.

- -
// the target number is wrapped in a <span> tag with a unique ID
-<p class="text-example">Total number of lines: <span id="myNumber">0</span></p>
-
- -
// sample tween object with "number" property
-// this assumes it will start from current number which is different from 1550
-var myNumberTween = KUTE.to('#myNumber', {number: 1550}); 
-
- -

The above should work like this:

-
-

Total number of lines: 0

- -
- Start -
-
-

The button action will toggle the valuesEnd value for the number property, because tweening a number to itself would produce no effect.

- -

Text Property

-

Let's try a quick example and analyze the current outcome. Be aware that the example involves using child contents for the values, which is something we need to - handle in a special way to optimize the visual experience.

- -
// sample tween object with "text" property
-var myTextTween = KUTE.to('selector', {text: 'A text string with <span>child content</span> should do.'});
-
- -
-

Click the Start button on the right.

-
- Start -
-
- -

So targets with child elements don't animate very well it seems. We could probably split the starting content and end content into multiple parts, set a tween object - for each parth with delays and other settings, but Text Write component comes with a powerful utility you can use to ease your work in these instances.

-

The createTextTweens() utility will do it all for you: split text strings, set tween objects, but let's see some sample code:

- -
// grab the parent of the content segments
-var textTarget = document.getElementById('textExample');
-
-// make a reversed array with its child contents
-var tweenObjects = KUTE.Util.createTextTweens(
-  textTarget,
-  'This text has a <a href="index.html">link to homepage</a> inside.',
-  options
-);
-
-// start whenever you want
-tweenObjects.start();
-
- -

Now let's see how we doin:

- -
-

Click the Start button on the right.

-
- Start -
-
- -

There are some considerations for the createTextTweens(target,newText,options) utility:

-
    -
  • The utility will replace the target content with <span> parts or the children's tagNames, then for the newText content will - create similar parts but empty. Also the number of the parts of the target content doesn't have to be the same as for the new content.
  • -
  • The utility returns an Array of tween objects, which is similar but independent from tweenCollection objects.
  • -
  • The returned Array itself has a start() "method" you can call on all the tweens inside.
  • -
  • The utility will assign playing: boolean property to the target content Element to prevent unwanted animation interruptions or glitches.
  • -
  • While you can set various tween options like easing, duration or the component specific textChars option, the delay option is handled - by the utility automatically.
  • -
  • The utility has a special handling for the duration tween option. You can either set a fixed duration like 1000, which isn't recommended, or auto - which will allow the utility the ability to determine a duration for each text part
  • -
  • When the animation of the last text part is complete, the target content Element.innerHTML will be set to the original un-split newText.
  • -
  • Using yoyo tween option is not recommended because it doesn't produce a desirable effect.
  • -
  • The utility will not work properly with targets that have a deeper structure than level 1, which means that for instance - <span>Text <span>sample</span></span> may not be processed properly.
  • -
- -

Combining Both

-
-
-
-

0

-
-
-

Clicks so far

-
-
-
- Start -
-
-

In this example we've used the textChars option with symbols and all values respectively, but combining the two text properties and some other KUTE.js - features can really spice up some content. Have fun!

- -

Notes

-
    -
  • Keep in mind that the yoyo tween option will NOT un-write / delete the string character by character for the text property, but will write the previous text instead.
  • -
  • For a full code review, check out the ./assets/js/textWrite.js example source code.
  • -
  • The component is only included in the demo/src/kute-extra.js file.
  • -
- -
- - - - -
- - - - - - - - - - - - - - diff --git a/demo/transformFunctions.html b/demo/transformFunctions.html deleted file mode 100644 index 73add18..0000000 --- a/demo/transformFunctions.html +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - - - - - - - - KUTE.js Transform Functions - - - - - - - - - - - - - -
- - - -
-

Transform Functions

-

The component covers most important 2D and 3D transform functions as described in the W3 specification, - completelly reworked for improved performance and faster value processing.

-
- -
- -
- -
-
-

Overview

-

The component to cover animation for most transform functions with improved performance and faster value processing.

-
-
-

The KUTE.js Transform Functions enables animation for the CSS3 transform style on Element targets on modern browsers. For specific legacy browsers there is another - component called Transform Legacy you will find in the source folders.

-

Starting with KUTE.js version 2.0, you can set the perspective function as a tween property, while you can still rely on a parent's perspective but for less performance.

-

All the previous perspective related options have been removed. The transform CSS3 property itself no longer uses preffixes like webkit, moz or ms since all major - browsers are standardized.

-

In comparison with previous versions, the component expects that input values are already px and deg based and no longer transforms % percent based values into px based or rad - based angles into deg based. This makes the execution faster and more consistent.

-

The component will stack all transform functions for translations, rotations and skews to shorthand functions to optimize performance and minimize value processing.

-
-
-
-
- -
- -

3D Transform

-
    -
  • perspective function creates a 3D perspective for a target element transformation. EG. perspective:400 to apply a 400px perspective. IE10+
  • -
  • translateX function is for horizontal translation. EG. translateX:150 to translate an element 150px to the right. IE10+
  • -
  • translateY function is for vertical translation. EG. translateY:-250 to translate an element 250px towards the top. IE10+
  • -
  • translateZ function is for translation on the Z axis in a given 3D field. EG. translateZ:-250 to translate an element 250px away from the viewer, making it - appear smaller. This function can be combined with the perspective function to take effect or the parent's perspective; the smaller perspective value, the deeper translation. IE10+
  • -
  • translate3d function is for movement on all axes in a given 3D field. EG. translate3d:[-150,200,150] to translate an element 150px to the left, 200px - to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a perspective. IE10+
  • -
  • rotateX function rotates an element on the X axis in a given 3D field. Eg. rotateX:250 will rotate an element clockwise by 250 degrees. Requires perspective. - IE10+
  • -
  • rotateY function rotates an element on the Y axis in a given 3D field. Eg. rotateY:-150 will rotate an element counter-clockwise by 150 degrees. - Requires perspective. IE10+
  • -
  • rotateZ function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. rotateZ:-150 will rotate an element counter-clockwise by 150 degrees on X axis. - IE10+
  • -
  • rotate3d is a tween property, which combines the above rotateX, rotateY, and rotateZ functions and rotates an element on all axes. Obviously this is NOT - equivalent with the rotate3d(vectorX,vectorY,vectorZ,angle) shorthand function, this is only an optimization implemented for performance reasons and hopefully for your convenience. - Eg. rotate3d:[-150,80,90] will rotate an element counter-clockwise by 150 degrees on X axis, 80 degrees on Y axis and 90 degrees on Z axis. The X and Y axis require a perspective. - IE10+
  • -
  • matrix3d and scale3d functions are not supported by this component, but they are implemented in the transformMatrix component.
  • -
- -

2D Transform

-
    -
  • translate function is for movement on X and Y axis. EG. translate:[-150,200] to translate an element 150px to the left, 200px to the bottom. IE9+
  • -
  • rotate function rotates an element on the Z axis. Eg. rotate:250 will rotate an element clockwise by 250 degrees. IE9+
  • -
  • skewX function will apply a shear on X axis to a target element. Eg. skewX:50 will skew a target element on X axis by 50 degrees. IE9+
  • -
  • skewY function will apply a shear on X axis to a target element. Eg. skewX:50 will skew a target element on X axis by 50 degrees. IE9+
  • -
  • skew function will apply a shear on both X and Y axes to a target element. Eg. skew:[50,50] will skew a target element on X axis by 50 degrees and 50 degrees on Y axis. - IE9+
  • -
  • scale function will scale a target element on all axes. Eg. scale:1.5 will scale up a target element by 50%. IE9+
  • -
  • matrix is not supported by this component, but is implemented in the transformMatrix component.
  • -
-

As a quick note, all input values for translate, rotate or single axis translation, skew or rotation will be all stacked into translate3d, - skew and rotate3d respectivelly; this is to further improve performance on modern browsers.

- -

Translations

- -
var tween1 = KUTE.fromTo('selector1',{translate:0},{translate:250}); // or translate:[x,y] for both axes
-var tween2 = KUTE.fromTo('selector2',{translateX:0},{translateX:-250});
-var tween3 = KUTE.fromTo('selector3',{translate3d:[0,0,0]},{translate3d:[0,250,0]});
-var tween4 = KUTE.fromTo('selector4',{perspective:400,translateY:0},{perspective:200,translateY:-100});
-
- -
-
2D
-
X
-
Y
-
Z
- -
- Start -
-
- -

As you can see in your browsers console, for all animations translate3d is used, as explained above. Also the first example that's using the 2D translate for both vertical - and horizontal axis even if we only set X axis.

- -

Rotations

- -
var tween1 = KUTE.fromTo('selector1',{rotate:0},{rotate:-720});
-var tween2 = KUTE.fromTo('selector2',{rotateX:0},{rotateX:200});
-var tween3 = KUTE.fromTo('selector3',{perspective:100,rotate3d:[0,0,0]},{perspective:100,rotate3d:[0,160,0]});
-var tween4 = KUTE.fromTo('selector4',{rotateZ:0},{rotateZ:360});
-
- -
-
2D
-
X
-
Y
-
Z
-
- Start -
-
-

The rotateX and rotateY are 3D based rotations, so they require a perspective in order to make the browser render proper 3D layers, but in the example they animate different because only the second, Y axis, uses the - perspective function. The rotation on Z axis does not require a perspective. Unlike translations, you can stack all axis rotation for your animation, but we will see that in a later example.

- -

Skews

- -
var tween1 = KUTE.fromTo('selector1',{skewX:0},{skewX:20});
-var tween2 = KUTE.fromTo('selector2',{skew:[0,0]},{skew:[0,45]});
-
- -
-
X
-
Y
- -
- Start -
-
- -

Mixed Transformations

-

The current specification does not support animating different transform properties with multiple tween objects at the same time, you must stack them all together into a single object. See the example below:

- -
var tween1 = KUTE.fromTo('selector1',{rotateX:0},{rotateX:20}).start();
-var tween2 = KUTE.fromTo('selector1',{skewY:0},{skewY:45}).start();
-
-

If you check the test here, you will notice that only the skewY is going to work and no rotation. Now let's do this properly.

- -
var tween1 = KUTE.fromTo(
-'selector1', // element
-{pespective:200,translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
-{pespective:200,translateX:250, rotateX:360, rotateY:15, rotateZ:5} // to
-);
-var tween2 = KUTE.fromTo(
-'selector2', // element
-{translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
-{translateX:-250, rotateX:360, rotateY:15, rotateZ:5} // to
-);
-
- -
-
self perspective 200px
-
parent perspective 400px
- -
- Start -
-
-

Note in this example, the first tween object uses the element's perspective while the second relies on the parent's perspective.

- -

Chained Transformations

-

KUTE.js has the ability to stack transform functions in a way to improve performance and optimize your workflow. In that idea the .to() method can be the right choice for most of your - animation needs and especially to link animations together because it has the ability to check the current values of the transform functions found in the element's inline styling, mostly from previous - tween animation, and use them as start values for the next animation. OK now, let's see a side by side comparison with 4 elements:

- -
-
FROMTO
-
FROMTO
-
TO
-
TO
- -
- Start -
-
-

Observations

-
    -
  • The example hopefully demostrates what the animation looks like with different combinations of transform functions and how to combine them to optimize your workflow, size on disk as well as to how - to link animations together in a smooth continuous animation.
  • -
  • No matter the input values, the component will always stack translations into translate3d and rotations into rotate3d.
  • -
  • The first box uses a regular .fromTo() object, from point A to B and back to A, with the exact coordinates we want.
  • -
  • The second box is also using .fromTo() object, but using all values for all tweens at all times, so we gave the animation a sense of continuity.
  • -
  • The third box uses the .to() method, and will try and continue animation from last animation, but we "forgot" to keep track on the rotation of the X axis.
  • -
  • The last box also uses the .to() method, and uses all values and reproduce the animation of the second box exactly, but with nearly half the code.
  • -
- -

Notes

-
    -
  • This demo page should work with IE10+ browsers.
  • -
  • The order of the transform functions/properties is always the same: perspective, translation, rotation, skew, scale, this way we can prevent - jumpy/janky animations; one of the reasons is consistency in all transform based components and another reason is the order of execution from the draft for - matrix3d recomposition.
  • -
  • Tests reveal that an element's own perspective produce better performance than using the parent's perspective. Also having both will severelly punish the animation performance, so keep that in mind - when you work on optimizing your code.
  • -
  • Use single axis transform functions like translateX when you want to animate the Y and Z axes back to ZERO, but in a convenient way.
  • -
  • Use shorthand functions like translate3d when you want to animate / keep multiple axes.
  • -
  • Shorthand functions like translate3d or rotate3d tween property generally not only improve performance, but will also minimize the code size. Eg. translateX:150, - translateY:200, translateZ:50 => translate3d:[150,200,50] is quite the difference.
  • -
  • On larger amount of elements animating chains, the .fromTo() method is fastest, and you will have more work to do as well, but will eliminate any delay / syncronization issue that may occur.
  • -
  • This component is bundled with the demo/src/kute-base.js and the standard kute.js distribution files.
  • -
- -
- - - - -
- - - - - - - - - - - - - - - - diff --git a/demo/transformMatrix.html b/demo/transformMatrix.html deleted file mode 100644 index 7e07fd3..0000000 --- a/demo/transformMatrix.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - - KUTE.js Transform Matrix - - - - - - - - - - - - -
- - - -
-

Transform Matrix

-

The component covers all 3D transform functions and renders the update with either matrix() or matrix3d() functions, depending on the - functions used and their values. The notation is also fairly easy to use and familiar with other components.

-
- -
-
-
-
-

Overview

-

The brand new component to enable complex transform animations of the future.

-
-
-

The KUTE.js Transform Matrix component covers animation for the CSS3 transform style on Element targets but with a different implementation.

-
    -
  • The notation is a little different because we have a different supported functions/properties set, and the value processing function needs to differentiate the two components.
  • -
  • The 2D transform functions like rotate, translate or scale have been dropped to enable faster value processing and improved performance. The component is - geared towards the future of web development with this very specific purpose in mind.
  • -
  • Most importantly we have the update function which implements the DOMMatrix() API for smooth animation at no - performance cost, which is different from other libraries that use a webkitCSSMatrix polyfill and lose performance.
  • -
  • The script is robust, simple and light in size. It's simply a matter of taste when choosing between the two transform components.
  • -
-

The component was developed for more complex transform animations and comes with additional supported transform functions. According to the W3 draft, the DOMMatrix API will merge the - fallback webkitCSSMatrix API and the SVGMatrix API together, so awesome is yet to come.

-

Due to execution complexity and other performance considerations, and similar to the Transform Functions component, this component provides support for a custom - rotate3d[X,Y,Z] tween property which is different from CSS3 standard rotate3d(x,y,z,Angle) shorthand function.

-

In certain situations you can also use functions like scaleX, rotateY or translateZ for convenience, but the component will always stack translations - into translate3d, all scale axes into scale3d, all rotations into rotate3d and both skews into skew.

-
-
-
-
- -
- -

3D Transform

-
    -
  • perspective function creates a 3D perspective for a target element transformation. EG. perspective:400 to apply a 400px perspective.
  • -
  • translateX function is for horizontal translation. EG. translateX:150 to translate an element 150px to the right.
  • -
  • translateY function is for vertical translation. EG. translateY:-250 to translate an element 250px towards the top.
  • -
  • translateZ function is for translation on the Z axis in a given 3D field. EG. translateZ:-250 to translate an element 250px away from the viewer, making it - appear smaller. This function can be combined with the perspective function to take effect or the parent's perspective; the smaller perspective value, the deeper translation.
  • -
  • translate3d shorthand function is for translation on all the axes in a given 3D field. EG. translate3d:[-150,200,150] to translate an element 150px to the left, 200px - to the bottom and 150px closer to the viewer, making it larger. When third value is used, it requires using a perspective.
  • -
  • rotateX function rotates an element on the X axis in a given 3D field. Eg. rotateX:250 will rotate an element clockwise by 250 degrees on X axis. - Requires perspective.
  • -
  • rotateY function rotates an element on the Y axis in a given 3D field. Eg. rotateY:-150 will rotate an element counter-clockwise by 150 degrees on Y axis. - Requires perspective.
  • -
  • rotateZ function rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. rotateZ:90 will rotate an element clockwise by 90 degrees on Z axis.
  • -
  • rotate3d is a tween property, which combines the above rotateX, rotateY, and rotateZ functions and rotates an element on all axes. - Eg. rotate3d:[250,-150,90] will produce the same effect as the three above combined. The X and Y axes require a perspective.
  • -
  • skewX function will apply a shear to a target element on the X axis. Eg. skewX:50 will skew the element by 50 degrees on X axis.
  • -
  • skewY function will apply a shear to a target element on the Y axis. Eg. skewY:-50 will skew the element by -50 degrees on Y axis.
  • -
  • skew shorthand function will apply a shear on both X and Y axes to a target element. Eg. skew:[50,50] will skew a target element on X axis by 50 degrees and 50 degrees on Y axis.
  • -
  • scaleX function will scale the X axis of a target element. Eg. scaleX:1.5 will increase the scale of a target element on the X axis by 50%.
  • -
  • scaleY function will scale the Y axis of a target element. Eg. scaleY:0.5 will decrease the scale of a target element on the Y axis by 50%.
  • -
  • scaleZ function will scale the Z axis of a target element. Eg. scaleZ:0.75 will decrease the scale of a target element on the Z axis by 25%.
  • -
  • scale3d function will scale a target element on all axes. Eg. scale3d:[1.5,0.5,0.75] will produce the same effect as the 3 above combined.
  • -
  • matrix and matrix3d are not supported CSS3 transform functions or tween properties, but the results of the update function.
  • -
- -

Example

-

Now let's have a look at the notation and a quick example:

- -
let mx1 = KUTE.to('el1', { transform: { translate3d:[-50,-50,-50]} })
-let mx2 = KUTE.to('el2', { transform: { perspective: 100, translateX: -50, rotateX:-180} })
-let mx3 = KUTE.to('el3', { transform: { translate3d:[-50,-50,-50], skew:[-15,-15]} })
-let mx4 = KUTE.to('el4', { transform: { translate3d:[-50,-50,-50], rotate3d:[0,-360,0], scaleX:0.5 } })
-
- -
-
MX1
-
MX2
-
MX3
-
MX4
- -
- Start -
-
-

So the second element uses it's own perspective but notice that the parent perspective also apply. This case must be avoided in order to keep performance in check: one perspective is best.

- -

Chained Transformations

-

Similar to the other component the Transform Matrix component will produce the same visual experience, but with the matrix3d function.

-
-
FROMTO
-
FROMTO
-
TO
-
TO
- -
- Start -
-
- -

Notes

-
    -
  • This demo page should work with IE10+ browsers.
  • -
  • Why no support for the matrix3d function? Simple: we can of course interpolate 16 numbers super fast, but we won't be able to rotate on any axis above 360 degrees. - As explained here, surely for performance reasons the browsers won't try and compute angles above 360 degrees, but simplify - the number crunching because a 370 degree rotation is visualy identical with a 10 degree rotation.
  • -
  • The component does NOT include any scripting for matrix decomposition/unmatrix, after several years of research I came to the conclusion that there is no such thing to be reliable. - Such a feature would allow us to kick start animations directly from matrix3d string/array values, but considering the size of this component, I let you draw the conclusions.
  • -
  • Despite the "limitations", we have some tricks available: the fromTo() method will never fail and it's much better when performance and sync are a must, and for to() - method we're storing the values from previous animations to have them ready and available for the next chained animation.
  • -
  • The performance of this component is identical with the Transform Functions component, which is crazy and awesome, all that thanks to the DOMMatrix API built into our modern browsers. - If that's not good enough, the API will automatically switch from matrix3d to matrix and vice-versa whenever needed to save power. Neat?
  • -
  • The rotate3d property makes alot more sense for this component since the DOMMatrix rotate(angleX,angleY,angleZ) method works exactly the same, while the - rotate3d(vectorX,vectorY,vectorZ,angle) function is a thing of the past, according to Chris Coyier nobody use it.
  • -
  • Since the component fully utilize the DOMMatrix API, with fallback to each browser compatible API, some browsers still have in 2020 an incomplete CSS3Matrix API, for instance privacy browsers - like Tor won't work with rotations properly for some reason, other proprietary mobile browsers may suffer from same symptoms. In these cases a correction polyfill is required.
  • -
  • This component is bundled with the demo/src/kute-extra.js distribution file.
  • -
-
- - - - -
- - - - - - - - - - - - - - diff --git a/dist/kute.esm.js b/dist/kute.esm.js deleted file mode 100644 index b596539..0000000 --- a/dist/kute.esm.js +++ /dev/null @@ -1,4621 +0,0 @@ -/*! -* KUTE.js Standard v2.2.3 (http://thednp.github.io/kute.js) -* Copyright 2015-2021 © thednp -* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) -*/ -/** - * Creates cubic-bezier easing functions. - * - * @class - */ -class CubicBezier { - /** - * @constructor - * @param {number} p1x - first point horizontal position - * @param {number} p1y - first point vertical position - * @param {number} p2x - second point horizontal position - * @param {number} p2y - second point vertical position - * @param {string=} functionName - an optional function name - * @returns {(t: number) => number} a new CubicBezier easing function - */ - constructor(p1x, p1y, p2x, p2y, functionName) { - // pre-calculate the polynomial coefficients - // First and last control points are implied to be (0,0) and (1.0, 1.0) - - /** @type {number} */ - this.cx = 3.0 * p1x; - - /** @type {number} */ - this.bx = 3.0 * (p2x - p1x) - this.cx; - - /** @type {number} */ - this.ax = 1.0 - this.cx - this.bx; - - /** @type {number} */ - this.cy = 3.0 * p1y; - - /** @type {number} */ - this.by = 3.0 * (p2y - p1y) - this.cy; - - /** @type {number} */ - this.ay = 1.0 - this.cy - this.by; - - /** @type {(t: number) => number} */ - const BezierEasing = (t) => this.sampleCurveY(this.solveCurveX(t)); - - // this function needs a name - Object.defineProperty(BezierEasing, 'name', { writable: true }); - BezierEasing.name = functionName || `cubic-bezier(${[p1x, p1y, p2x, p2y]})`; - - return BezierEasing; - } - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled X value - */ - sampleCurveX(t) { - return ((this.ax * t + this.bx) * t + this.cx) * t; - } - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled Y value - */ - sampleCurveY(t) { - return ((this.ay * t + this.by) * t + this.cy) * t; - } - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled curve derivative X value - */ - sampleCurveDerivativeX(t) { - return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx; - } - - /** - * @param {number} x - progress [0-1] - * @return {number} - solved curve X value - */ - solveCurveX(x) { - let t0; - let t1; - let t2; - let x2; - let d2; - let i; - const epsilon = 1e-5; // Precision - - // First try a few iterations of Newton's method -- normally very fast. - for (t2 = x, i = 0; i < 32; i += 1) { - x2 = this.sampleCurveX(t2) - x; - if (Math.abs(x2) < epsilon) return t2; - d2 = this.sampleCurveDerivativeX(t2); - if (Math.abs(d2) < epsilon) break; - t2 -= x2 / d2; - } - - // No solution found - use bi-section - t0 = 0.0; - t1 = 1.0; - t2 = x; - - if (t2 < t0) return t0; - if (t2 > t1) return t1; - - while (t0 < t1) { - x2 = this.sampleCurveX(t2); - if (Math.abs(x2 - x) < epsilon) return t2; - if (x > x2) t0 = t2; - else t1 = t2; - - t2 = (t1 - t0) * 0.5 + t0; - } - - // Give up - return t2; - } -} - -var version$1 = "1.0.18"; - -// @ts-ignore - -/** - * A global namespace for library version. - * @type {string} - */ -const Version$1 = version$1; - -Object.assign(CubicBezier, { Version: Version$1 }); - -/** - * The KUTE.js Execution Context - */ -const KEC = {}; - -const Tweens = []; - -let gl0bal; - -if (typeof global !== 'undefined') gl0bal = global; -else if (typeof window !== 'undefined') gl0bal = window.self; -else gl0bal = {}; - -const globalObject = gl0bal; - -// KUTE.js INTERPOLATE FUNCTIONS -// ============================= -const interpolate = {}; - -// schedule property specific function on animation start -// link property update function to KUTE.js execution context -const onStart = {}; - -// Include a performance.now polyfill. -// source https://github.com/tweenjs/tween.js/blob/master/src/Now.ts -let performanceNow; - -// In node.js, use process.hrtime. -// eslint-disable-next-line -// @ts-ignore -if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { - performanceNow = () => { - // eslint-disable-next-line - // @ts-ignore - const time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; -} else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { - // In a browser, use self.performance.now if it is available. - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - performanceNow = self.performance.now.bind(self.performance); -} else if (typeof Date !== 'undefined' && Date.now) { - // Use Date.now if it is available. - performanceNow = Date.now; -} else { - // Otherwise, use 'new Date().getTime()'. - performanceNow = () => new Date().getTime(); -} - -const now = performanceNow; - -const Time = {}; -Time.now = now; - -// eslint-disable-next-line import/no-mutable-exports -- impossible to satisfy -let Tick = 0; - -/** - * - * @param {number | Date} time - */ -const Ticker = (time) => { - let i = 0; - while (i < Tweens.length) { - if (Tweens[i].update(time)) { - i += 1; - } else { - Tweens.splice(i, 1); - } - } - Tick = requestAnimationFrame(Ticker); -}; - -// stop requesting animation frame -function stop() { - setTimeout(() => { // re-added for #81 - if (!Tweens.length && Tick) { - cancelAnimationFrame(Tick); - Tick = null; - Object.keys(onStart).forEach((obj) => { - if (typeof (onStart[obj]) === 'function') { - if (KEC[obj]) delete KEC[obj]; - } else { - Object.keys(onStart[obj]).forEach((prop) => { - if (KEC[prop]) delete KEC[prop]; - }); - } - }); - - Object.keys(interpolate).forEach((i) => { - if (KEC[i]) delete KEC[i]; - }); - } - }, 64); -} - -// render update functions -// ======================= -const Render = { - Tick, Ticker, Tweens, Time, -}; -Object.keys(Render).forEach((blob) => { - if (!KEC[blob]) { - KEC[blob] = blob === 'Time' ? Time.now : Render[blob]; - } -}); - -globalObject._KUTE = KEC; - -// all supported properties -const supportedProperties = {}; - -const defaultValues = {}; - -const defaultOptions$1 = { - duration: 700, - delay: 0, - easing: 'linear', - repeat: 0, - repeatDelay: 0, - yoyo: false, - resetStart: false, - offset: 0, -}; - -// used in preparePropertiesObject -const prepareProperty = {}; - -// check current property value when .to() method is used -const prepareStart = {}; - -// checks for differences between the processed start and end values, -// can be set to make sure start unit and end unit are same, -// stack transforms, process SVG paths, -// any type of post processing the component needs -const crossCheck = {}; - -// schedule property specific function on animation complete -const onComplete = {}; - -// link properties to interpolate functions -const linkProperty = {}; - -const Objects = { - supportedProperties, - defaultValues, - defaultOptions: defaultOptions$1, - prepareProperty, - prepareStart, - crossCheck, - onStart, - onComplete, - linkProperty, -}; - -// util - a general object for utils like rgbToHex, processEasing -const Util = {}; - -/** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ -const add = (tw) => Tweens.push(tw); - -/** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ -const remove = (tw) => { - const i = Tweens.indexOf(tw); - if (i !== -1) Tweens.splice(i, 1); -}; - -/** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ -const getAll = () => Tweens; - -/** - * KUTE.removeAll() - */ -const removeAll = () => { Tweens.length = 0; }; - -/** - * linkInterpolation - * @this {KUTE.Tween} - */ -function linkInterpolation() { // DON'T change - Object.keys(linkProperty).forEach((component) => { - const componentLink = linkProperty[component]; - const componentProps = supportedProperties[component]; - - Object.keys(componentLink).forEach((fnObj) => { - if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius - && Object.keys(this.valuesEnd).some((i) => (componentProps && componentProps.includes(i)) - || (i === 'attr' && Object.keys(this.valuesEnd[i]).some((j) => componentProps && componentProps.includes(j))))) { - if (!KEC[fnObj]) KEC[fnObj] = componentLink[fnObj]; - } else { - Object.keys(this.valuesEnd).forEach((prop) => { - const propObject = this.valuesEnd[prop]; - if (propObject instanceof Object) { - Object.keys(propObject).forEach((i) => { - if (typeof (componentLink[i]) === 'function') { // transformCSS3 - if (!KEC[i]) KEC[i] = componentLink[i]; - } else { - Object.keys(componentLink[fnObj]).forEach((j) => { - if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix - if (!KEC[j]) KEC[j] = componentLink[i][j]; - } - }); - } - }); - } - }); - } - }); - }); -} - -const internals = { - add, - remove, - getAll, - removeAll, - stop, - linkInterpolation, -}; - -/** - * getInlineStyle - * Returns the transform style for element from - * cssText. Used by for the `.to()` static method. - * - * @param {Element} el target element - * @returns {object} - */ -function getInlineStyle(el) { - // if the scroll applies to `window` it returns as it has no styling - if (!el.style) return false; - // the cssText | the resulting transform object - const css = el.style.cssText.replace(/\s/g, '').split(';'); - const transformObject = {}; - const arrayFn = ['translate3d', 'translate', 'scale3d', 'skew']; - - css.forEach((cs) => { - if (/transform/i.test(cs)) { - // all transform properties - const tps = cs.split(':')[1].split(')'); - tps.forEach((tpi) => { - const tpv = tpi.split('('); - const tp = tpv[0]; - // each transform property - const tv = tpv[1]; - if (!/matrix/.test(tp)) { - transformObject[tp] = arrayFn.includes(tp) ? tv.split(',') : tv; - } - }); - } - }); - - return transformObject; -} - -/** - * getStyleForProperty - * - * Returns the computed style property for element for .to() method. - * Used by for the `.to()` static method. - * - * @param {Element} elem - * @param {string} propertyName - * @returns {string} - */ -function getStyleForProperty(elem, propertyName) { - let result = defaultValues[propertyName]; - const styleAttribute = elem.style; - const computedStyle = getComputedStyle(elem) || elem.currentStyle; - const styleValue = styleAttribute[propertyName] && !/auto|initial|none|unset/.test(styleAttribute[propertyName]) - ? styleAttribute[propertyName] - : computedStyle[propertyName]; - - if (propertyName !== 'transform' && (propertyName in computedStyle || propertyName in styleAttribute)) { - result = styleValue; - } - - return result; -} - -/** - * prepareObject - * - * Returns all processed valuesStart / valuesEnd. - * - * @param {Element} obj the values start/end object - * @param {string} fn toggles between the two - */ -function prepareObject(obj, fn) { // this, props object, type: start/end - const propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd; - - Object.keys(prepareProperty).forEach((component) => { - const prepareComponent = prepareProperty[component]; - const supportComponent = supportedProperties[component]; - - Object.keys(prepareComponent).forEach((tweenCategory) => { - const transformObject = {}; - - Object.keys(obj).forEach((tweenProp) => { - // scroll, opacity, other components - if (defaultValues[tweenProp] && prepareComponent[tweenProp]) { - propertiesObject[tweenProp] = prepareComponent[tweenProp] - .call(this, tweenProp, obj[tweenProp]); - - // transform - } else if (!defaultValues[tweenCategory] && tweenCategory === 'transform' - && supportComponent.includes(tweenProp)) { - transformObject[tweenProp] = obj[tweenProp]; - - // allow transformFunctions to work with preprocessed input values - } else if (!defaultValues[tweenProp] && tweenProp === 'transform') { - propertiesObject[tweenProp] = obj[tweenProp]; - - // colors, boxModel, category - } else if (!defaultValues[tweenCategory] - && supportComponent && supportComponent.includes(tweenProp)) { - propertiesObject[tweenProp] = prepareComponent[tweenCategory] - .call(this, tweenProp, obj[tweenProp]); - } - }); - - // we filter out older browsers by checking Object.keys - if (Object.keys(transformObject).length) { - propertiesObject[tweenCategory] = prepareComponent[tweenCategory] - .call(this, tweenCategory, transformObject); - } - }); - }); -} - -/** - * getStartValues - * - * Returns the start values for to() method. - * Used by for the `.to()` static method. - * - * @this {KUTE.Tween} the tween instance - */ -function getStartValues() { - const startValues = {}; - const currentStyle = getInlineStyle(this.element); - - Object.keys(this.valuesStart).forEach((tweenProp) => { - Object.keys(prepareStart).forEach((component) => { - const componentStart = prepareStart[component]; - - Object.keys(componentStart).forEach((tweenCategory) => { - // clip, opacity, scroll - if (tweenCategory === tweenProp && componentStart[tweenProp]) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this, tweenProp, this.valuesStart[tweenProp]); - // find in an array of properties - } else if (supportedProperties[component] - && supportedProperties[component].includes(tweenProp)) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this, tweenProp, this.valuesStart[tweenProp]); - } - }); - }); - }); - - // stack transformCSS props for .to() chains - // also add to startValues values from previous tweens - Object.keys(currentStyle).forEach((current) => { - if (!(current in this.valuesStart)) { - startValues[current] = currentStyle[current] || defaultValues[current]; - } - }); - - this.valuesStart = {}; - prepareObject.call(this, startValues, 'start'); -} - -var Process = { - getInlineStyle, - getStyleForProperty, - getStartValues, - prepareObject, -}; - -const connect = {}; -/** @type {KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra} */ -connect.tween = null; -connect.processEasing = null; - -const Easing = { - linear: new CubicBezier(0, 0, 1, 1, 'linear'), - easingSinusoidalIn: new CubicBezier(0.47, 0, 0.745, 0.715, 'easingSinusoidalIn'), - easingSinusoidalOut: new CubicBezier(0.39, 0.575, 0.565, 1, 'easingSinusoidalOut'), - easingSinusoidalInOut: new CubicBezier(0.445, 0.05, 0.55, 0.95, 'easingSinusoidalInOut'), - - easingQuadraticIn: new CubicBezier(0.550, 0.085, 0.680, 0.530, 'easingQuadraticIn'), - easingQuadraticOut: new CubicBezier(0.250, 0.460, 0.450, 0.940, 'easingQuadraticOut'), - easingQuadraticInOut: new CubicBezier(0.455, 0.030, 0.515, 0.955, 'easingQuadraticInOut'), - - easingCubicIn: new CubicBezier(0.55, 0.055, 0.675, 0.19, 'easingCubicIn'), - easingCubicOut: new CubicBezier(0.215, 0.61, 0.355, 1, 'easingCubicOut'), - easingCubicInOut: new CubicBezier(0.645, 0.045, 0.355, 1, 'easingCubicInOut'), - - easingQuarticIn: new CubicBezier(0.895, 0.03, 0.685, 0.22, 'easingQuarticIn'), - easingQuarticOut: new CubicBezier(0.165, 0.84, 0.44, 1, 'easingQuarticOut'), - easingQuarticInOut: new CubicBezier(0.77, 0, 0.175, 1, 'easingQuarticInOut'), - - easingQuinticIn: new CubicBezier(0.755, 0.05, 0.855, 0.06, 'easingQuinticIn'), - easingQuinticOut: new CubicBezier(0.23, 1, 0.32, 1, 'easingQuinticOut'), - easingQuinticInOut: new CubicBezier(0.86, 0, 0.07, 1, 'easingQuinticInOut'), - - easingExponentialIn: new CubicBezier(0.95, 0.05, 0.795, 0.035, 'easingExponentialIn'), - easingExponentialOut: new CubicBezier(0.19, 1, 0.22, 1, 'easingExponentialOut'), - easingExponentialInOut: new CubicBezier(1, 0, 0, 1, 'easingExponentialInOut'), - - easingCircularIn: new CubicBezier(0.6, 0.04, 0.98, 0.335, 'easingCircularIn'), - easingCircularOut: new CubicBezier(0.075, 0.82, 0.165, 1, 'easingCircularOut'), - easingCircularInOut: new CubicBezier(0.785, 0.135, 0.15, 0.86, 'easingCircularInOut'), - - easingBackIn: new CubicBezier(0.6, -0.28, 0.735, 0.045, 'easingBackIn'), - easingBackOut: new CubicBezier(0.175, 0.885, 0.32, 1.275, 'easingBackOut'), - easingBackInOut: new CubicBezier(0.68, -0.55, 0.265, 1.55, 'easingBackInOut'), -}; - -/** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easingfunction - */ -function processBezierEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof (Easing[fn]) === 'function') { - return Easing[fn]; - } if (/bezier/.test(fn)) { - const bz = fn.replace(/bezier|\s|\(|\)/g, '').split(','); - return new CubicBezier(bz[0] * 1, bz[1] * 1, bz[2] * 1, bz[3] * 1); // bezier easing - } - // if (/elastic|bounce/i.test(fn)) { - // throw TypeError(`KUTE - CubicBezier doesn't support ${fn} easing.`); - // } - return Easing.linear; -} - -connect.processEasing = processBezierEasing; - -/** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ -function selector(el, multi) { - try { - let requestedElem; - let itemsArray; - if (multi) { - itemsArray = el instanceof Array && el.every((x) => x instanceof Element); - requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray - ? el : document.querySelectorAll(el); - } else { - requestedElem = el instanceof Element || el === window // scroll - ? el : document.querySelector(el); - } - return requestedElem; - } catch (e) { - throw TypeError(`KUTE.js - Element(s) not found: ${el}.`); - } -} - -function queueStart() { - // fire onStart actions - Object.keys(onStart).forEach((obj) => { - if (typeof (onStart[obj]) === 'function') { - onStart[obj].call(this, obj); // easing functions - } else { - Object.keys(onStart[obj]).forEach((prop) => { - onStart[obj][prop].call(this, prop); - }); - } - }); - - // add interpolations - linkInterpolation.call(this); -} - -/** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ -class TweenBase { - /** - * @param {Element} targetElement the target element - * @param {KUTE.tweenProps} startObject the start values - * @param {KUTE.tweenProps} endObject the end values - * @param {KUTE.tweenOptions} opsObject the end values - * @returns {TweenBase} the resulting Tween object - */ - constructor(targetElement, startObject, endObject, opsObject) { - // element animation is applied to - this.element = targetElement; - - /** @type {boolean} */ - this.playing = false; - /** @type {number?} */ - this._startTime = null; - /** @type {boolean} */ - this._startFired = false; - - // type is set via KUTE.tweenProps - this.valuesEnd = endObject; - this.valuesStart = startObject; - - // OPTIONS - const options = opsObject || {}; - // internal option to process inline/computed style at start instead of init - // used by to() method and expects object : {} / false - this._resetStart = options.resetStart || 0; - // you can only set a core easing function as default - /** @type {KUTE.easingOption} */ - this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing); - /** @type {number} */ - this._duration = options.duration || defaultOptions$1.duration; // duration option | default - /** @type {number} */ - this._delay = options.delay || defaultOptions$1.delay; // delay option | default - - // set other options - Object.keys(options).forEach((op) => { - const internalOption = `_${op}`; - if (!(internalOption in this)) this[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 - const easingFnName = this._easing.name; - if (!onStart[easingFnName]) { - onStart[easingFnName] = function easingFn(prop) { - if (!KEC[prop] && prop === this._easing.name) KEC[prop] = this._easing; - }; - } - - return this; - } - - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - start(time) { - // now it's a good time to start - add(this); - this.playing = true; - - this._startTime = typeof time !== 'undefined' ? time : KEC.Time(); - this._startTime += this._delay; - - if (!this._startFired) { - if (this._onStart) { - this._onStart.call(this); - } - - queueStart.call(this); - - this._startFired = true; - } - - if (!Tick) Ticker(); - return this; - } - - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - stop() { - if (this.playing) { - remove(this); - this.playing = false; - - if (this._onStop) { - this._onStop.call(this); - } - this.close(); - } - return this; - } - - /** - * Trigger internal completion callbacks. - */ - close() { - // scroll|transformMatrix need this - Object.keys(onComplete).forEach((component) => { - Object.keys(onComplete[component]).forEach((toClose) => { - onComplete[component][toClose].call(this, toClose); - }); - }); - // when all animations are finished, stop ticking after ~3 frames - this._startFired = false; - stop.call(this); - } - - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - chain(args) { - this._chain = []; - this._chain = args.length ? args : this._chain.concat(args); - return this; - } - - /** - * Stop tweening the chained tween instances. - */ - stopChainedTweens() { - if (this._chain && this._chain.length) this._chain.forEach((tw) => tw.stop()); - } - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - update(time) { - const T = time !== undefined ? time : KEC.Time(); - - let elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - const progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach((tweenProp) => { - KEC[tweenProp](this.element, - this.valuesStart[tweenProp], - this.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.map((tw) => tw.start()); - } - - return false; - } - - return true; - } -} - -// Update Tween Interface -connect.tween = TweenBase; - -/** - * The `KUTE.Tween()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor adds additional functionality and is the default - * Tween object constructor in KUTE.js. - */ -class Tween extends TweenBase { - /** - * @param {KUTE.tweenParams} args (*target*, *startValues*, *endValues*, *options*) - * @returns {Tween} the resulting Tween object - */ - constructor(...args) { - super(...args); // this calls the constructor of TweenBase - - // reset interpolation values - this.valuesStart = {}; - this.valuesEnd = {}; - - // const startObject = args[1]; - // const endObject = args[2]; - const [startObject, endObject, options] = args.slice(1); - - // set valuesEnd - prepareObject.call(this, endObject, 'end'); - - // set valuesStart - if (this._resetStart) { - this.valuesStart = startObject; - } else { - prepareObject.call(this, startObject, 'start'); - } - - // ready for crossCheck - if (!this._resetStart) { - Object.keys(crossCheck).forEach((component) => { - Object.keys(crossCheck[component]).forEach((checkProp) => { - crossCheck[component][checkProp].call(this, checkProp); - }); - }); - } - - // set paused state - /** @type {boolean} */ - this.paused = false; - /** @type {number?} */ - this._pauseTime = null; - - // additional properties and options - /** @type {number?} */ - this._repeat = options.repeat || defaultOptions$1.repeat; - /** @type {number?} */ - this._repeatDelay = options.repeatDelay || defaultOptions$1.repeatDelay; - // we cache the number of repeats to be able to put it back after all cycles finish - /** @type {number?} */ - this._repeatOption = this._repeat; - - // yoyo needs at least repeat: 1 - /** @type {KUTE.tweenProps} */ - this.valuesRepeat = {}; // valuesRepeat - /** @type {boolean} */ - this._yoyo = options.yoyo || defaultOptions$1.yoyo; - /** @type {boolean} */ - this._reversed = false; - - // don't load extra callbacks - // this._onPause = options.onPause || defaultOptions.onPause - // this._onResume = options.onResume || defaultOptions.onResume - - // chained Tweens - // this._chain = options.chain || defaultOptions.chain; - return this; - } - - /** - * Starts tweening, extended method - * @param {number?} time the tween start time - * @returns {Tween} this instance - */ - start(time) { - // on start we reprocess the valuesStart for TO() method - if (this._resetStart) { - this.valuesStart = this._resetStart; - getStartValues.call(this); - - // this is where we do the valuesStart and valuesEnd check for fromTo() method - Object.keys(crossCheck).forEach((component) => { - Object.keys(crossCheck[component]).forEach((checkProp) => { - crossCheck[component][checkProp].call(this, checkProp); - }); - }); - } - // still not paused - this.paused = false; - - // set yoyo values - if (this._yoyo) { - Object.keys(this.valuesEnd).forEach((endProp) => { - this.valuesRepeat[endProp] = this.valuesStart[endProp]; - }); - } - - super.start(time); - - return this; - } - - /** - * Stops tweening, extended method - * @returns {Tween} this instance - */ - stop() { - super.stop(); - if (!this.paused && this.playing) { - this.paused = false; - this.stopChainedTweens(); - } - return this; - } - - /** - * Trigger internal completion callbacks. - */ - close() { - super.close(); - - if (this._repeatOption > 0) { - this._repeat = this._repeatOption; - } - if (this._yoyo && this._reversed === true) { - this.reverse(); - this._reversed = false; - } - - return this; - } - - /** - * Resume tweening - * @returns {Tween} this instance - */ - resume() { - if (this.paused && this.playing) { - this.paused = false; - if (this._onResume !== undefined) { - this._onResume.call(this); - } - // re-queue execution context - queueStart.call(this); - // update time and let it roll - this._startTime += KEC.Time() - this._pauseTime; - add(this); - // restart ticker if stopped - if (!Tick) Ticker(); - } - return this; - } - - /** - * Pause tweening - * @returns {Tween} this instance - */ - pause() { - if (!this.paused && this.playing) { - remove(this); - this.paused = true; - this._pauseTime = KEC.Time(); - if (this._onPause !== undefined) { - this._onPause.call(this); - } - } - return this; - } - - /** - * Reverses start values with end values - */ - reverse() { - Object.keys(this.valuesEnd).forEach((reverseProp) => { - const tmp = this.valuesRepeat[reverseProp]; - this.valuesRepeat[reverseProp] = this.valuesEnd[reverseProp]; - this.valuesEnd[reverseProp] = tmp; - this.valuesStart[reverseProp] = this.valuesRepeat[reverseProp]; - }); - } - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - update(time) { - const T = time !== undefined ? time : KEC.Time(); - - let elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - const progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach((tweenProp) => { - KEC[tweenProp](this.element, - this.valuesStart[tweenProp], - this.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - if (this._repeat > 0) { - if (Number.isFinite(this._repeat)) this._repeat -= 1; - - // set the right time for delay - this._startTime = T; - if (Number.isFinite(this._repeat) && this._yoyo && !this._reversed) { - this._startTime += this._repeatDelay; - } - - if (this._yoyo) { // handle yoyo - this._reversed = !this._reversed; - this.reverse(); - } - - return true; - } - - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.forEach((tw) => tw.start()); - } - - return false; - } - return true; - } -} - -// Update Tween Interface Update -connect.tween = Tween; - -/** - * The static method creates a new `Tween` object for each `HTMLElement` - * from and `Array`, `HTMLCollection` or `NodeList`. - */ -class TweenCollection { - /** - * - * @param {Element[] | HTMLCollection | NodeList} els target elements - * @param {KUTE.tweenProps} vS the start values - * @param {KUTE.tweenProps} vE the end values - * @param {KUTE.tweenOptions} Options tween options - * @returns {TweenCollection} the Tween object collection - */ - constructor(els, vS, vE, Options) { - const TweenConstructor = connect.tween; - /** @type {KUTE.twCollection[]} */ - this.tweens = []; - - const Ops = Options || {}; - /** @type {number?} */ - Ops.delay = Ops.delay || defaultOptions$1.delay; - - // set all options - const options = []; - - Array.from(els).forEach((el, i) => { - options[i] = Ops || {}; - options[i].delay = i > 0 ? Ops.delay + (Ops.offset || defaultOptions$1.offset) : Ops.delay; - if (el instanceof Element) { - this.tweens.push(new TweenConstructor(el, vS, vE, options[i])); - } else { - throw Error(`KUTE - ${el} is not instanceof Element`); - } - }); - - /** @type {number?} */ - this.length = this.tweens.length; - return this; - } - - /** - * Starts tweening, all targets - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - start(time) { - const T = time === undefined ? KEC.Time() : time; - this.tweens.map((tween) => tween.start(T)); - return this; - } - - /** - * Stops tweening, all targets and their chains - * @returns {TweenCollection} this instance - */ - stop() { - this.tweens.map((tween) => tween.stop()); - return this; - } - - /** - * Pause tweening, all targets - * @returns {TweenCollection} this instance - */ - pause() { - this.tweens.map((tween) => tween.pause()); - return this; - } - - /** - * Resume tweening, all targets - * @returns {TweenCollection} this instance - */ - resume() { - this.tweens.map((tween) => tween.resume()); - return this; - } - - /** - * Schedule another tween or collection to start after - * this one is complete. - * @param {number?} args the tween start time - * @returns {TweenCollection} this instance - */ - chain(args) { - const lastTween = this.tweens[this.length - 1]; - if (args instanceof TweenCollection) { - lastTween.chain(args.tweens); - } else if (args instanceof connect.tween) { - lastTween.chain(args); - } else { - throw new TypeError('KUTE.js - invalid chain value'); - } - return this; - } - - /** - * Check if any tween instance is playing - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - playing() { - return this.tweens.some((tw) => tw.playing); - } - - /** - * Remove all tweens in the collection - */ - removeTweens() { - this.tweens = []; - } - - /** - * Returns the maximum animation duration - * @returns {number} this instance - */ - getMaxDuration() { - const durations = []; - this.tweens.forEach((tw) => { - durations.push(tw._duration + tw._delay + tw._repeat * tw._repeatDelay); - }); - return Math.max(durations); - } -} - -const { tween: TweenConstructor$1 } = connect; - -/** - * The `KUTE.to()` static method returns a new Tween object - * for a single `HTMLElement` at its current state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ -function to(element, endObject, optionsObj) { - const options = optionsObj || {}; - options.resetStart = endObject; - return new TweenConstructor$1(selector(element), endObject, endObject, options); -} - -const { tween: TweenConstructor } = connect; - -/** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ -function fromTo(element, startObject, endObject, optionsObj) { - const options = optionsObj || {}; - return new TweenConstructor(selector(element), startObject, endObject, options); -} - -/** - * The `KUTE.allTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at their current state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenProps} optionsObj progress - * @returns {TweenCollection} the Tween object collection - */ -function allTo(elements, endObject, optionsObj) { - const options = optionsObj || {}; - options.resetStart = endObject; - return new TweenCollection(selector(elements, true), endObject, endObject, options); -} - -/** - * The `KUTE.allFromTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at a given state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {TweenCollection} the Tween object collection - */ -function allFromTo(elements, startObject, endObject, optionsObj) { - const options = optionsObj || {}; - return new TweenCollection(selector(elements, true), startObject, endObject, options); -} - -/** - * Animation Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - */ -class Animation { - /** - * @constructor - * @param {KUTE.fullComponent} Component - */ - constructor(Component) { - try { - if (Component.component in supportedProperties) { - throw Error(`KUTE - ${Component.component} already registered`); - } else if (Component.property in defaultValues) { - throw Error(`KUTE - ${Component.property} already registered`); - } - } catch (e) { - throw Error(e); - } - - const propertyInfo = this; - const ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - const Functions = { - prepareProperty, prepareStart, onStart, onComplete, crossCheck, - }; - const Category = Component.category; - const Property = Component.property; - const Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // single property - // {property,defaultvalue,defaultOptions,Interpolate,functions} - - // category colors, boxModel, borderRadius - // {category,properties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg transform, filter - // {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg htmlAttributes - // {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - defaultValues[Property] = Component.defaultValue; - - // minimal info - propertyInfo.supports = `${Property} property`; - } else if (Component.defaultValues) { - Object.keys(Component.defaultValues).forEach((dv) => { - defaultValues[dv] = Component.defaultValues[dv]; - }); - - // minimal info - propertyInfo.supports = `${Length || Property} ${Property || Category} properties`; - } - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions$1, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach((fn) => { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach((ofn) => { - // !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn]) - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][ofn]) { - Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]; - } - }); - } - } - }); - } - - // set component interpolation functions - if (Component.Interpolate) { - Object.keys(Component.Interpolate).forEach((fni) => { - const compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach((sfn) => { - if (typeof (compIntObj[sfn]) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach((fnu) => { - if (!Util[fnu]) Util[fnu] = Component.Util[fnu]; - }); - } - - return propertyInfo; - } -} - -/** - * trueDimension - * - * Returns the string value of a specific CSS property converted into a nice - * { v = value, u = unit } object. - * - * @param {string} dimValue the property string value - * @param {boolean | number} isAngle sets the utility to investigate angles - * @returns {{v: number, u: string}} the true {value, unit} tuple - */ -const trueDimension = (dimValue, isAngle) => { - const intValue = parseInt(dimValue, 10) || 0; - const mUnits = ['px', '%', 'deg', 'rad', 'em', 'rem', 'vh', 'vw']; - let theUnit; - - for (let mIndex = 0; mIndex < mUnits.length; mIndex += 1) { - if (typeof dimValue === 'string' && dimValue.includes(mUnits[mIndex])) { - theUnit = mUnits[mIndex]; break; - } - } - if (theUnit === undefined) { - theUnit = isAngle ? 'deg' : 'px'; - } - - return { v: intValue, u: theUnit }; -}; - -/** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ -function numbers(a, b, v) { - const A = +a; - const B = b - a; - // a = +a; b -= a; - return A + B * v; -} - -// Component Functions -/** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ -function boxModelOnStart(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - /* eslint-disable no-bitwise -- impossible to satisfy */ - elem.style[tweenProp] = `${v > 0.99 || v < 0.01 - ? ((numbers(a, b, v) * 10) >> 0) / 10 - : (numbers(a, b, v)) >> 0}px`; - /* eslint-enable no-bitwise */ - /* eslint-enable no-param-reassign */ - }; - } -} - -// Component Base Props -const baseBoxProps = ['top', 'left', 'width', 'height']; -const baseBoxOnStart = {}; -baseBoxProps.forEach((x) => { baseBoxOnStart[x] = boxModelOnStart; }); - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -function getBoxModel(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property name - * @returns {number} the property tween object - */ -function prepareBoxModel(tweenProp, value) { - const boxValue = trueDimension(value); - const offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; - return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v; -} - -// Component Base Props -const essentialBoxProps = ['top', 'left', 'width', 'height']; -const essentialBoxPropsValues = { - top: 0, left: 0, width: 0, height: 0, -}; - -const essentialBoxOnStart = {}; -essentialBoxProps.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; }); - -// All Component Functions -const essentialBoxModelFunctions = { - prepareStart: getBoxModel, - prepareProperty: prepareBoxModel, - onStart: essentialBoxOnStart, -}; - -// Component Essential -const BoxModelEssential = { - component: 'essentialBoxModel', - category: 'boxModel', - properties: essentialBoxProps, - defaultValues: essentialBoxPropsValues, - Interpolate: { numbers }, - functions: essentialBoxModelFunctions, - Util: { trueDimension }, -}; - -/** - * hexToRGB - * - * Converts a #HEX color format into RGB - * and returns a color object {r,g,b}. - * - * @param {string} hex the degree angle - * @returns {KUTE.colorObject | null} the radian angle - */ -const hexToRGB = (hex) => { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - const hexShorthand = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - const HEX = hex.replace(hexShorthand, (_, r, g, b) => r + r + g + g + b + b); - const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(HEX); - - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), - } : null; -}; - -/** - * trueColor - * - * Transform any color to rgba()/rgb() and return a nice RGB(a) object. - * - * @param {string} colorString the color input - * @returns {KUTE.colorObject} the {r,g,b,a} color object - */ -const trueColor = (colorString) => { - let result; - if (/rgb|rgba/.test(colorString)) { // first check if it's a rgb string - const vrgb = colorString.replace(/\s|\)/, '').split('(')[1].split(','); - const colorAlpha = vrgb[3] ? vrgb[3] : null; - if (!colorAlpha) { - result = { r: parseInt(vrgb[0], 10), g: parseInt(vrgb[1], 10), b: parseInt(vrgb[2], 10) }; - } - result = { - r: parseInt(vrgb[0], 10), - g: parseInt(vrgb[1], 10), - b: parseInt(vrgb[2], 10), - a: parseFloat(colorAlpha), - }; - } if (/^#/.test(colorString)) { - const fromHex = hexToRGB(colorString); - result = { r: fromHex.r, g: fromHex.g, b: fromHex.b }; - } if (/transparent|none|initial|inherit/.test(colorString)) { - result = { - r: 0, g: 0, b: 0, a: 0, - }; - } - // maybe we can check for web safe colors - // only works in a browser - if (!/^#|^rgb/.test(colorString)) { - const siteHead = document.getElementsByTagName('head')[0]; - siteHead.style.color = colorString; - let webColor = getComputedStyle(siteHead, null).color; - webColor = /rgb/.test(webColor) ? webColor.replace(/[^\d,]/g, '').split(',') : [0, 0, 0]; - siteHead.style.color = ''; - result = { - r: parseInt(webColor[0], 10), - g: parseInt(webColor[1], 10), - b: parseInt(webColor[2], 10), - }; - } - return result; -}; - -/** - * Color Interpolation Function. - * - * @param {KUTE.colorObject} a start color - * @param {KUTE.colorObject} b end color - * @param {number} v progress - * @returns {string} the resulting color - */ -function colors(a, b, v) { - const _c = {}; - const ep = ')'; - const cm = ','; - const rgb = 'rgb('; - const rgba = 'rgba('; - - Object.keys(b).forEach((c) => { - if (c !== 'a') { - _c[c] = numbers(a[c], b[c], v) >> 0 || 0; // eslint-disable-line no-bitwise - } else if (a[c] && b[c]) { - _c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100; // eslint-disable-line no-bitwise - } - }); - - 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; -} - -// Component Interpolation -// rgba1, rgba2, progress - -// Component Properties -// supported formats -// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) -const supportedColors$1 = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', - 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor', -]; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -function onStartColors(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = colors(a, b, v); - }; - } -} - -const colorsOnStart$1 = {}; -supportedColors$1.forEach((x) => { colorsOnStart$1[x] = onStartColors; }); - -// Component Properties -// supported formats -// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) -const supportedColors = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor', -]; - -const defaultColors = {}; -supportedColors.forEach((tweenProp) => { - defaultColors[tweenProp] = '#000'; -}); - -// Component Functions -const colorsOnStart = {}; -supportedColors.forEach((x) => { - colorsOnStart[x] = onStartColors; -}); - -/** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} property computed style - */ -function getColor(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.colorObject} the property tween object - */ -function prepareColor(/* prop, */_, value) { - return trueColor(value); -} - -// All Component Functions -const colorFunctions = { - prepareStart: getColor, - prepareProperty: prepareColor, - onStart: colorsOnStart, -}; - -// Component Full -const colorProperties = { - component: 'colorProperties', - category: 'colors', - properties: supportedColors, - defaultValues: defaultColors, - Interpolate: { numbers, colors }, - functions: colorFunctions, - Util: { trueColor }, -}; - -// Component Special -const attributes = {}; - -const onStartAttr = { - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - attr(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, vS, vE, v) => { - Object.keys(vE).forEach((oneAttr) => { - KEC.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v); - }); - }; - } - }, - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - attributes(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd.attr) { - KEC[tweenProp] = attributes; - } - }, -}; - -// Component Name -const ComponentName = 'htmlAttributes'; - -// Component Properties -const svgColors = ['fill', 'stroke', 'stop-color']; - -// Component Util -/** - * Returns non-camelcase property name. - * @param {string} a the camelcase property name - * @returns {string} the non-camelcase property name - */ -function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); } - -// Component Functions -/** - * Returns the current attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {{[x:string]: string}} attribute value - */ -function getAttr(/* tweenProp, */_, value) { - const attrStartValues = {}; - Object.keys(value).forEach((attr) => { - // get the value for 'fill-opacity' not fillOpacity - // also 'width' not the internal 'width_px' - const attribute = replaceUppercase(attr).replace(/_+[a-z]+/, ''); - const currentValue = this.element.getAttribute(attribute); - attrStartValues[attribute] = svgColors.includes(attribute) - ? (currentValue || 'rgba(0,0,0,0)') - : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); - }); - - return attrStartValues; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} attrObj the property value - * @returns {number} the property tween object - */ -function prepareAttr(tweenProp, attrObj) { // attr (string),attrObj (object) - const attributesObject = {}; - - Object.keys(attrObj).forEach((p) => { - const prop = replaceUppercase(p); - const regex = /(%|[a-z]+)$/; - const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/, '')); - - if (!svgColors.includes(prop)) { - // attributes set with unit suffixes - if (currentValue !== null && regex.test(currentValue)) { - const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - const suffix = /%/.test(unit) ? '_percent' : `_${unit}`; - - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop + suffix] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - const _p = oneAttr.replace(suffix, ''); - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - elem.setAttribute(_p, ((numbers(a.v, b.v, v) * 1000 >> 0) / 1000) + b.u); - }; - } - }; - attributesObject[prop + suffix] = trueDimension(attrObj[p]); - } else if (!regex.test(attrObj[p]) || currentValue === null - || (currentValue !== null && !regex.test(currentValue))) { - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000); - }; - } - }; - attributesObject[prop] = parseFloat(attrObj[p]); - } - } else { // colors - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - elem.setAttribute(oneAttr, colors(a, b, v)); - }; - } - }; - attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; - } - }); - - return attributesObject; -} - -// All Component Functions -const attrFunctions = { - prepareStart: getAttr, - prepareProperty: prepareAttr, - onStart: onStartAttr, -}; - -// Component Full -const htmlAttributes = { - component: ComponentName, - property: 'attr', - // the Animation class will need some values to validate this Object attribute - subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'], - defaultValue: { - fill: 'rgb(0,0,0)', - stroke: 'rgb(0,0,0)', - 'stop-color': 'rgb(0,0,0)', - opacity: 1, - 'stroke-opacity': 1, - 'fill-opacity': 1, // same here - }, - Interpolate: { numbers, colors }, - functions: attrFunctions, - // export to global for faster execution - Util: { replaceUppercase, trueColor, trueDimension }, -}; - -/* opacityProperty = { - property: 'opacity', - defaultValue: 1, - interpolators: {numbers}, - functions = { prepareStart, prepareProperty, onStart } -} */ - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -function onStartOpacity(tweenProp/* , value */) { - // opacity could be 0 sometimes, we need to check regardless - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable */ - elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000; - /* eslint-enable */ - }; - } -} - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -function getOpacity(tweenProp/* , value */) { - return getStyleForProperty(this.element, tweenProp); -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ -function prepareOpacity(/* tweenProp, */_, value) { - return parseFloat(value); // opacity always FLOAT -} - -// All Component Functions -const opacityFunctions = { - prepareStart: getOpacity, - prepareProperty: prepareOpacity, - onStart: onStartOpacity, -}; - -// Full Component -const OpacityProperty = { - component: 'opacityProperty', - property: 'opacity', - defaultValue: 1, - Interpolate: { numbers }, - functions: opacityFunctions, -}; - -// Component Values -const lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase -const upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase -const nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols -const numeric = String('0123456789').split(''); // numeric -const alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric -const allTypes = alphaNumeric.concat(nonAlpha); // all caracters - -const charSet = { - alpha: lowerCaseAlpha, // lowercase - upper: upperCaseAlpha, // uppercase - symbols: nonAlpha, // symbols - numeric, - alphanumeric: alphaNumeric, - all: allTypes, -}; - -// Component Functions -const onStartWrite = { - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - text(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - const chars = this._textChars; - let charsets = charSet[defaultOptions$1.textChars]; - - if (chars in charSet) { - charsets = charSet[chars]; - } else if (chars && chars.length) { - charsets = chars; - } - - KEC[tweenProp] = (elem, a, b, v) => { - let initialText = ''; - let endText = ''; - const finalText = b === '' ? ' ' : b; - const firstLetterA = a.substring(0); - const firstLetterB = b.substring(0); - /* eslint-disable */ - const pointer = charsets[(Math.random() * charsets.length) >> 0]; - - if (a === ' ') { - endText = firstLetterB - .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0); - elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText; - } else if (b === ' ') { - initialText = firstLetterA - .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0); - elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText; - } else { - initialText = firstLetterA - .substring(firstLetterA.length, - Math.min(v * firstLetterA.length, firstLetterA.length) >> 0); - endText = firstLetterB - .substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0); - elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText; - } - /* eslint-enable */ - }; - } - }, - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - number(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { // numbers can be 0 - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable */ - elem.innerHTML = numbers(a, b, v) >> 0; - /* eslint-enable */ - }; - } - }, -}; - -// Component Util -// utility for multi-child targets -// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class -function wrapContentsSpan(el, classNAME) { - let textWriteWrapper; - let newElem; - if (typeof (el) === 'string') { - newElem = document.createElement('SPAN'); - newElem.innerHTML = el; - newElem.className = classNAME; - return newElem; - } - if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) { - const elementInnerHTML = el.innerHTML; - textWriteWrapper = document.createElement('SPAN'); - textWriteWrapper.className = classNAME; - textWriteWrapper.innerHTML = elementInnerHTML; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - el.appendChild(textWriteWrapper); - el.innerHTML = textWriteWrapper.outerHTML; - /* eslint-enable no-param-reassign -- impossible to satisfy */ - } else if (el.children.length && el.children[0].className === classNAME) { - [textWriteWrapper] = el.children; - } - return textWriteWrapper; -} - -function getTextPartsArray(el, classNAME) { - let elementsArray = []; - const len = el.children.length; - if (len) { - const textParts = []; - let remainingMarkup = el.innerHTML; - let wrapperParts; - - for (let i = 0, currentChild, childOuter, unTaggedContent; i < len; i += 1) { - currentChild = el.children[i]; - childOuter = currentChild.outerHTML; - wrapperParts = remainingMarkup.split(childOuter); - - if (wrapperParts[0] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0], ''); - } else if (wrapperParts[1] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], ''); - } - - if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME); - textParts.push(currentChild); - remainingMarkup = remainingMarkup.replace(childOuter, ''); - } - - if (remainingMarkup !== '') { - const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME); - textParts.push(unTaggedRemaining); - } - - elementsArray = elementsArray.concat(textParts); - } else { - elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]); - } - return elementsArray; -} - -function setSegments(target, newText) { - const oldTargetSegs = getTextPartsArray(target, 'text-part'); - const newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part'); - - /* eslint-disable no-param-reassign */ - target.innerHTML = ''; - target.innerHTML += oldTargetSegs.map((s) => { s.className += ' oldText'; return s.outerHTML; }).join(''); - target.innerHTML += newTargetSegs.map((s) => { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join(''); - /* eslint-enable no-param-reassign */ - - return [oldTargetSegs, newTargetSegs]; -} - -function createTextTweens(target, newText, ops) { - if (target.playing) return false; - - const options = ops || {}; - options.duration = 1000; - - if (ops.duration === 'auto') { - options.duration = 'auto'; - } else if (Number.isFinite(ops.duration * 1)) { - options.duration = ops.duration * 1; - } - - const TweenContructor = connect.tween; - const segs = setSegments(target, newText); - const oldTargetSegs = segs[0]; - const newTargetSegs = segs[1]; - const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); - const newTargets = [].slice.call(target.getElementsByClassName('newText')); - - let textTween = []; - let totalDelay = 0; - - textTween = textTween.concat(oldTargets.map((el, i) => { - options.duration = options.duration === 'auto' - ? oldTargetSegs[i].innerHTML.length * 75 - : options.duration; - options.delay = totalDelay; - options.onComplete = null; - - totalDelay += options.duration; - return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options); - })); - textTween = textTween.concat(newTargets.map((el, i) => { - function onComplete() { - /* eslint-disable no-param-reassign */ - target.innerHTML = newText; - target.playing = false; - /* eslint-enable no-param-reassign */ - } - - options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; - options.delay = totalDelay; - options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null; - totalDelay += options.duration; - - return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options); - })); - - textTween.start = function startTweens() { - if (!target.playing) { - textTween.forEach((tw) => tw.start()); - // eslint-disable-next-line no-param-reassign - target.playing = true; - } - }; - - return textTween; -} - -// Component Functions -/** - * Returns the current element `innerHTML`. - * @returns {string} computed style for property - */ -function getWrite(/* tweenProp, value */) { - return this.element.innerHTML; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number | string} the property tween object - */ -function prepareText(tweenProp, value) { - if (tweenProp === 'number') { - return parseFloat(value); - } - // empty strings crash the update function - return value === '' ? ' ' : value; -} - -// All Component Functions -const textWriteFunctions = { - prepareStart: getWrite, - prepareProperty: prepareText, - onStart: onStartWrite, -}; - -// Full Component -const TextWrite = { - component: 'textWriteProperties', - category: 'textWrite', - properties: ['text', 'number'], - defaultValues: { text: ' ', number: '0' }, - defaultOptions: { textChars: 'alpha' }, - Interpolate: { numbers }, - functions: textWriteFunctions, - // export to global for faster execution - Util: { charSet, createTextTweens }, -}; - -/** - * Perspective Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the perspective function in string format - */ -function perspective(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `perspective(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} - -/** - * Translate 3D Interpolation Function. - * - * @param {number[]} a start [x,y,z] position - * @param {number[]} b end [x,y,z] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D translation string - */ -function translate3d(a, b, u, v) { - const translateArray = []; - for (let ax = 0; ax < 3; ax += 1) { - translateArray[ax] = (a[ax] || b[ax] - // eslint-disable-next-line no-bitwise - ? ((a[ax] + (b[ax] - a[ax]) * v) * 1000 >> 0) / 1000 : 0) + u; - } - return `translate3d(${translateArray.join(',')})`; -} - -/** - * 3D Rotation Interpolation Function. - * - * @param {number} a start [x,y,z] angles - * @param {number} b end [x,y,z] angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D rotation string - */ -function rotate3d(a, b, u, v) { - let rotateStr = ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[0] || b[0] ? `rotateX(${((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000}${u})` : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[1] || b[1] ? `rotateY(${((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000}${u})` : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[2] || b[2] ? `rotateZ(${((a[2] + (b[2] - a[2]) * v) * 1000 >> 0) / 1000}${u})` : ''; - return rotateStr; -} - -/** - * Translate 2D Interpolation Function. - * - * @param {number[]} a start [x,y] position - * @param {number[]} b end [x,y] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 2D translation string - */ -function translate(a, b, u, v) { - const translateArray = []; - // eslint-disable-next-line no-bitwise - translateArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')})`; -} - -/** - * 2D Rotation Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated rotation - */ -function rotate(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `rotate(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} - -/** - * Scale Interpolation Function. - * - * @param {number} a start scale - * @param {number} b end scale - * @param {number} v progress - * @returns {string} the interpolated scale - */ -function scale(a, b, v) { - // eslint-disable-next-line no-bitwise - return `scale(${((a + (b - a) * v) * 1000 >> 0) / 1000})`; -} - -/** - * Skew Interpolation Function. - * - * @param {number} a start {x,y} angles - * @param {number} b end {x,y} angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated string value of skew(s) - */ -function skew(a, b, u, v) { - const skewArray = []; - // eslint-disable-next-line no-bitwise - skewArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')})`; -} - -// Component Functions -/** - * Sets the property update function. - * * same to svgTransform, htmlAttributes - * @param {string} tweenProp the property name - */ -function onStartTransform(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0 - + (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z] - + (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z] - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } -} - -// same to svg transform, attr -// the component developed for modern browsers supporting non-prefixed transform - -// Component Functions -/** - * Returns the current property inline style. - * @param {string} tweenProp the property name - * @returns {string} inline style for property - */ -function getTransform(tweenProp/* , value */) { - const currentStyle = getInlineStyle(this.element); - return currentStyle[tweenProp] ? currentStyle[tweenProp] : defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ -function prepareTransform(/* prop, */_, obj) { - const prepAxis = ['X', 'Y', 'Z']; // coordinates - const transformObject = {}; - const translateArray = []; const rotateArray = []; const skewArray = []; - const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew']; - - Object.keys(obj).forEach((x) => { - const pv = typeof obj[x] === 'object' && obj[x].length - ? obj[x].map((v) => parseInt(v, 10)) - : parseInt(obj[x], 10); - - if (arrayFunctions.includes(x)) { - const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x; - - if (x === 'skew') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0] - : [pv || 0, 0]; - } else if (x === 'translate') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0, pv[2] || 0] - : [pv || 0, 0, 0]; - } else { // translate3d | rotate3d - transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0]; - } - } else if (/[XYZ]/.test(x)) { - const fn = x.replace(/[XYZ]/, ''); - const fnId = fn === 'skew' ? fn : `${fn}3d`; - const fnLen = fn === 'skew' ? 2 : 3; - let fnArray = []; - - if (fn === 'translate') { - fnArray = translateArray; - } else if (fn === 'rotate') { - fnArray = rotateArray; - } else if (fn === 'skew') { - fnArray = skewArray; - } - - for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) { - const fnAxis = prepAxis[fnIndex]; - fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0; - } - transformObject[fnId] = fnArray; - } else if (x === 'rotate') { // rotate - transformObject.rotate3d = [0, 0, pv]; - } else { // scale | perspective - transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv; - } - }); - - return transformObject; -} - -/** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ -function crossCheckTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } - } -} - -// All Component Functions -const transformFunctions = { - prepareStart: getTransform, - prepareProperty: prepareTransform, - onStart: onStartTransform, - crossCheck: crossCheckTransform, -}; - -const supportedTransformProperties = [ - 'perspective', - 'translate3d', 'translateX', 'translateY', 'translateZ', 'translate', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate', - 'skewX', 'skewY', 'skew', - 'scale', -]; - -const defaultTransformValues = { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - translate: [0, 0], - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - rotate: 0, - skewX: 0, - skewY: 0, - skew: [0, 0], - scale: 1, -}; - -// Full Component -const TransformFunctions = { - component: 'transformFunctions', - property: 'transform', - subProperties: supportedTransformProperties, - defaultValues: defaultTransformValues, - functions: transformFunctions, - Interpolate: { - perspective, - translate3d, - rotate3d, - translate, - rotate, - scale, - skew, - }, -}; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -function onStartDraw(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable no-bitwise -- impossible to satisfy */ - const pathLength = (a.l * 100 >> 0) / 100; - const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100; - const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100; - const offset = 0 - start; - const dashOne = end + offset; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDashoffset = `${offset}px`; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`; - /* eslint-disable no-bitwise -- impossible to satisfy */ - }; - } -} - -// Component Util -/** - * Convert a `` length percent value to absolute. - * @param {string} v raw value - * @param {number} l length value - * @returns {number} the absolute value - */ -function percent(v, l) { - return (parseFloat(v) / 100) * l; -} - -/** - * Returns the `` length. - * It doesn't compute `rx` and / or `ry` of the element. - * @see http://stackoverflow.com/a/30376660 - * @param {SVGRectElement} el target element - * @returns {number} the `` length - */ -function getRectLength(el) { - const w = el.getAttribute('width'); - const h = el.getAttribute('height'); - return (w * 2) + (h * 2); -} - -/** - * Returns the `` / `` length. - * @param {SVGPolylineElement | SVGPolygonElement} el target element - * @returns {number} the element length - */ -function getPolyLength(el) { - const points = el.getAttribute('points').split(' '); - - let len = 0; - if (points.length > 1) { - const coord = (p) => { - const c = p.split(','); - if (c.length !== 2) { return 0; } // return undefined - if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; } - return [parseFloat(c[0]), parseFloat(c[1])]; - }; - - const dist = (c1, c2) => { - if (c1 !== undefined && c2 !== undefined) { - return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2); - } - return 0; - }; - - if (points.length > 2) { - for (let i = 0; i < points.length - 1; i += 1) { - len += dist(coord(points[i]), coord(points[i + 1])); - } - } - len += el.tagName === 'polygon' - ? dist(coord(points[0]), coord(points[points.length - 1])) : 0; - } - return len; -} - -/** - * Returns the `` length. - * @param {SVGLineElement} el target element - * @returns {number} the element length - */ -function getLineLength(el) { - const x1 = el.getAttribute('x1'); - const x2 = el.getAttribute('x2'); - const y1 = el.getAttribute('y1'); - const y2 = el.getAttribute('y2'); - return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); -} - -/** - * Returns the `` length. - * @param {SVGCircleElement} el target element - * @returns {number} the element length - */ -function getCircleLength(el) { - const r = el.getAttribute('r'); - return 2 * Math.PI * r; -} - -// returns the length of an ellipse -/** - * Returns the `` length. - * @param {SVGEllipseElement} el target element - * @returns {number} the element length - */ -function getEllipseLength(el) { - const rx = el.getAttribute('rx'); - const ry = el.getAttribute('ry'); - const len = 2 * rx; - const wid = 2 * ry; - return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; -} - -/** - * Returns the shape length. - * @param {SVGPathCommander.shapeTypes} el target element - * @returns {number} the element length - */ -function getTotalLength$1(el) { - if (el.tagName === 'rect') { - return getRectLength(el); - } if (el.tagName === 'circle') { - return getCircleLength(el); - } if (el.tagName === 'ellipse') { - return getEllipseLength(el); - } if (['polygon', 'polyline'].includes(el.tagName)) { - return getPolyLength(el); - } if (el.tagName === 'line') { - return getLineLength(el); - } - // ESLint - return 0; -} - -/** - * Returns the property tween object. - * @param {SVGPathCommander.shapeTypes} element the target element - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ -function getDraw(element, value) { - const length = /path|glyph/.test(element.tagName) - ? element.getTotalLength() - : getTotalLength$1(element); - let start; - let end; - let dasharray; - let offset; - - if (value instanceof Object && Object.keys(value).every((v) => ['s', 'e', 'l'].includes(v))) { - return value; - } if (typeof value === 'string') { - const v = value.split(/,|\s/); - start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]); - end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]); - } else if (typeof value === 'undefined') { - offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset')); - dasharray = getStyleForProperty(element, 'stroke-dasharray').split(','); - - start = 0 - offset; - end = parseFloat(dasharray[0]) + start || length; - } - return { s: start, e: end, l: length }; -} - -/** - * Reset CSS properties associated with the `draw` property. - * @param {SVGPathCommander.shapeTypes} element target - */ -function resetDraw(elem) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - elem.style.strokeDashoffset = ''; - elem.style.strokeDasharray = ''; - /* eslint-disable no-param-reassign -- impossible to satisfy */ -} - -// Component Functions -/** - * Returns the property tween object. - * @returns {KUTE.drawObject} the property tween object - */ -function getDrawValue(/* prop, value */) { - return getDraw(this.element); -} -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ -function prepareDraw(_, value) { - return getDraw(this.element, value); -} - -// All Component Functions -const svgDrawFunctions = { - prepareStart: getDrawValue, - prepareProperty: prepareDraw, - onStart: onStartDraw, -}; - -// Component Full -const SvgDrawProperty = { - component: 'svgDraw', - property: 'draw', - defaultValue: '0% 0%', - Interpolate: { numbers }, - functions: svgDrawFunctions, - // Export to global for faster execution - Util: { - getRectLength, - getPolyLength, - getLineLength, - getCircleLength, - getEllipseLength, - getTotalLength: getTotalLength$1, - resetDraw, - getDraw, - percent, - }, -}; - -/** - * Splits an extended A (arc-to) segment into two cubic-bezier segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` this segment belongs to - * @param {string[]} allPathCommands all previous path commands - * @param {number} i the segment index - */ - -function fixArc(path, allPathCommands, i) { - if (path[i].length > 7) { - path[i].shift(); - const segment = path[i]; - let ni = i; // ESLint - while (segment.length) { - // if created multiple C:s, their original seg is saved - allPathCommands[i] = 'A'; - // @ts-ignore - path.splice(ni += 1, 0, ['C', ...segment.splice(0, 6)]); - } - path.splice(i, 1); - } -} - -/** - * Segment params length - * @type {Record} - */ -const paramsCount = { - a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0, -}; - -/** - * Breaks the parsing of a pathString once a segment is finalized. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ -function finalizeSegment(path) { - let pathCommand = path.pathValue[path.segmentStart]; - let LK = pathCommand.toLowerCase(); - let { data } = path; - - // Process duplicated commands (without comand name) - if (LK === 'm' && data.length > 2) { - // @ts-ignore - path.segments.push([pathCommand, data[0], data[1]]); - data = data.slice(2); - LK = 'l'; - pathCommand = pathCommand === 'm' ? 'l' : 'L'; - } - - // @ts-ignore - while (data.length >= paramsCount[LK]) { - // path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK]))); - // @ts-ignore - path.segments.push([pathCommand, ...data.splice(0, paramsCount[LK])]); - // @ts-ignore - if (!paramsCount[LK]) { - break; - } - } -} - -const invalidPathValue = 'Invalid path value'; - -/** - * Validates an A (arc-to) specific path command value. - * Usually a `large-arc-flag` or `sweep-flag`. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ -function scanFlag(path) { - const { index } = path; - const ch = path.pathValue.charCodeAt(index); - - if (ch === 0x30/* 0 */) { - path.param = 0; - path.index += 1; - return; - } - - if (ch === 0x31/* 1 */) { - path.param = 1; - path.index += 1; - return; - } - - path.err = `${invalidPathValue}: invalid Arc flag "${ch}", expecting 0 or 1 at index ${index}`; -} - -/** - * Checks if a character is a digit. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ -function isDigit(code) { - return (code >= 48 && code <= 57); // 0..9 -} - -/** - * Validates every character of the path string, - * every path command, negative numbers or floating point numbers. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ -function scanParam(path) { - const { max, pathValue, index: start } = path; - let index = start; - let zeroFirst = false; - let hasCeiling = false; - let hasDecimal = false; - let hasDot = false; - let ch; - - if (index >= max) { - // path.err = 'SvgPath: missed param (at pos ' + index + ')'; - path.err = `${invalidPathValue} at ${index}: missing param ${pathValue[index]}`; - return; - } - ch = pathValue.charCodeAt(index); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - // This logic is shamelessly borrowed from Esprima - // https://github.com/ariya/esprimas - if (!isDigit(ch) && ch !== 0x2E/* . */) { - // path.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')'; - path.err = `${invalidPathValue} at index ${index}: ${pathValue[index]} is not a number`; - return; - } - - if (ch !== 0x2E/* . */) { - zeroFirst = (ch === 0x30/* 0 */); - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - - if (zeroFirst && index < max) { - // decimal number starts with '0' such as '09' is illegal. - if (ch && isDigit(ch)) { - // path.err = 'SvgPath: numbers started with `0` such as `09` - // are illegal (at pos ' + start + ')'; - path.err = `${invalidPathValue} at index ${start}: ${pathValue[start]} illegal number`; - return; - } - } - - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasCeiling = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x2E/* . */) { - hasDot = true; - index += 1; - while (isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasDecimal = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x65/* e */ || ch === 0x45/* E */) { - if (hasDot && !hasCeiling && !hasDecimal) { - path.err = `${invalidPathValue} at index ${index}: ${pathValue[index]} invalid float exponent`; - return; - } - - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - } - if (index < max && isDigit(pathValue.charCodeAt(index))) { - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - } - } else { - // path.err = 'SvgPath: invalid float exponent (at pos ' + index + ')'; - path.err = `${invalidPathValue} at index ${index}: ${pathValue[index]} invalid float exponent`; - return; - } - } - - path.index = index; - path.param = +path.pathValue.slice(start, index); -} - -/** - * Checks if the character is a space. - * - * @param {number} ch the character to check - * @returns {boolean} check result - */ -function isSpace(ch) { - const specialSpaces = [ - 0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, - 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF]; - return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029) // Line terminators - // White spaces - || (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) - || (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); -} - -/** - * Points the parser to the next character in the - * path string every time it encounters any kind of - * space character. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ -function skipSpaces(path) { - const { pathValue, max } = path; - while (path.index < max && isSpace(pathValue.charCodeAt(path.index))) { - path.index += 1; - } -} - -/** - * Checks if the character is a path command. - * - * @param {any} code the character to check - * @returns {boolean} check result - */ -function isPathCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - switch (code | 0x20) { - case 0x6D/* m */: - case 0x7A/* z */: - case 0x6C/* l */: - case 0x68/* h */: - case 0x76/* v */: - case 0x63/* c */: - case 0x73/* s */: - case 0x71/* q */: - case 0x74/* t */: - case 0x61/* a */: - // case 0x72/* r */: - return true; - default: - return false; - } -} - -/** - * Checks if the character is or belongs to a number. - * [0-9]|+|-|. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ -function isDigitStart(code) { - return (code >= 48 && code <= 57) /* 0..9 */ - || code === 0x2B /* + */ - || code === 0x2D /* - */ - || code === 0x2E; /* . */ -} - -/** - * Checks if the character is an A (arc-to) path command. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ -function isArcCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - return (code | 0x20) === 0x61; -} - -/** - * Scans every character in the path string to determine - * where a segment starts and where it ends. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ -function scanSegment(path) { - const { max, pathValue, index } = path; - const cmdCode = pathValue.charCodeAt(index); - const reqParams = paramsCount[pathValue[index].toLowerCase()]; - - path.segmentStart = index; - - if (!isPathCommand(cmdCode)) { - path.err = `${invalidPathValue}: ${pathValue[index]} not a path command`; - return; - } - - path.index += 1; - skipSpaces(path); - - path.data = []; - - if (!reqParams) { - // Z - finalizeSegment(path); - return; - } - - for (;;) { - for (let i = reqParams; i > 0; i -= 1) { - if (isArcCommand(cmdCode) && (i === 3 || i === 4)) scanFlag(path); - else scanParam(path); - - if (path.err.length) { - return; - } - path.data.push(path.param); - - skipSpaces(path); - - // after ',' param is mandatory - if (path.index < max && pathValue.charCodeAt(path.index) === 0x2C/* , */) { - path.index += 1; - skipSpaces(path); - } - } - - if (path.index >= path.max) { - break; - } - - // Stop on next segment - if (!isDigitStart(pathValue.charCodeAt(path.index))) { - break; - } - } - - finalizeSegment(path); -} - -/** - * Returns a clone of an existing `pathArray`. - * - * @param {SVGPathCommander.pathArray | SVGPathCommander.pathSegment} path the source `pathArray` - * @returns {any} the cloned `pathArray` - */ -function clonePath(path) { - return path.map((x) => (Array.isArray(x) ? [...x] : x)); -} - -/** - * The `PathParser` is used by the `parsePathString` static method - * to generate a `pathArray`. - * - * @param {string} pathString - */ -function PathParser(pathString) { - /** @type {SVGPathCommander.pathArray} */ - // @ts-ignore - this.segments = []; - /** @type {string} */ - this.pathValue = pathString; - /** @type {number} */ - this.max = pathString.length; - /** @type {number} */ - this.index = 0; - /** @type {number} */ - this.param = 0.0; - /** @type {number} */ - this.segmentStart = 0; - /** @type {any} */ - this.data = []; - /** @type {string} */ - this.err = ''; -} - -/** - * Iterates an array to check if it's an actual `pathArray`. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ -function isPathArray(path) { - return Array.isArray(path) && path.every((seg) => { - const lk = seg[0].toLowerCase(); - return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk); - }); -} - -/** - * Parses a path string value and returns an array - * of segments we like to call `pathArray`. - * - * @param {SVGPathCommander.pathArray | string} pathInput the string to be parsed - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` - */ -function parsePathString(pathInput) { - if (isPathArray(pathInput)) { - // @ts-ignore -- isPathArray also checks if it's an `Array` - return clonePath(pathInput); - } - - // @ts-ignore -- pathInput is now string - const path = new PathParser(pathInput); - - skipSpaces(path); - - while (path.index < path.max && !path.err.length) { - scanSegment(path); - } - - if (path.err.length) { - // @ts-ignore - path.segments = []; - } else if (path.segments.length) { - if (!'mM'.includes(path.segments[0][0])) { - path.err = `${invalidPathValue}: missing M/m`; - // @ts-ignore - path.segments = []; - } else { - path.segments[0][0] = 'M'; - } - } - - return path.segments; -} - -/** - * Iterates an array to check if it's a `pathArray` - * with all absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ -function isAbsoluteArray(path) { - return isPathArray(path) - // @ts-ignore -- `isPathArray` also checks if it's `Array` - && path.every((x) => x[0] === x[0].toUpperCase()); -} - -/** - * Parses a path string value or object and returns an array - * of segments, all converted to absolute values. - * - * @param {string | SVGPathCommander.pathArray} pathInput the path string | object - * @returns {SVGPathCommander.absoluteArray} the resulted `pathArray` with absolute values - */ -function pathToAbsolute(pathInput) { - if (isAbsoluteArray(pathInput)) { - // @ts-ignore -- `isAbsoluteArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - const path = parsePathString(pathInput); - let x = 0; let y = 0; - let mx = 0; let my = 0; - - // @ts-ignore -- the `absoluteSegment[]` is for sure an `absolutePath` - return path.map((segment) => { - const values = segment.slice(1).map(Number); - const [pathCommand] = segment; - /** @type {SVGPathCommander.absoluteCommand} */ - // @ts-ignore - const absCommand = pathCommand.toUpperCase(); - - if (pathCommand === 'M') { - [x, y] = values; - mx = x; - my = y; - return ['M', x, y]; - } - /** @type {SVGPathCommander.absoluteSegment} */ - // @ts-ignore - let absoluteSegment = []; - - if (pathCommand !== absCommand) { - switch (absCommand) { - case 'A': - absoluteSegment = [ - absCommand, values[0], values[1], values[2], - values[3], values[4], values[5] + x, values[6] + y]; - break; - case 'V': - absoluteSegment = [absCommand, values[0] + y]; - break; - case 'H': - absoluteSegment = [absCommand, values[0] + x]; - break; - default: { - // use brakets for `eslint: no-case-declaration` - // https://stackoverflow.com/a/50753272/803358 - const absValues = values.map((n, j) => n + (j % 2 ? y : x)); - // @ts-ignore for n, l, c, s, q, t - absoluteSegment = [absCommand, ...absValues]; - } - } - } else { - // @ts-ignore - absoluteSegment = [absCommand, ...values]; - } - - const segLength = absoluteSegment.length; - switch (absCommand) { - case 'Z': - x = mx; - y = my; - break; - case 'H': - // @ts-ignore - [, x] = absoluteSegment; - break; - case 'V': - // @ts-ignore - [, y] = absoluteSegment; - break; - default: - // @ts-ignore - x = absoluteSegment[segLength - 2]; - // @ts-ignore - y = absoluteSegment[segLength - 1]; - - if (absCommand === 'M') { - mx = x; - my = y; - } - } - return absoluteSegment; - }); -} - -/** - * Returns the missing control point from an - * T (shorthand quadratic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {string} prevCommand the previous path command - * @returns {{qx: number, qy: number}}} the missing control point - */ -function shorthandToQuad(x1, y1, qx, qy, prevCommand) { - return 'QT'.includes(prevCommand) - ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy } - : { qx: x1, qy: y1 }; -} - -/** - * Returns the missing control point from an - * S (shorthand cubic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @param {string} prevCommand the previous path command - * @returns {{x1: number, y1: number}}} the missing control point - */ -function shorthandToCubic(x1, y1, x2, y2, prevCommand) { - return 'CS'.includes(prevCommand) - ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2 } - : { x1, y1 }; -} - -/** - * Normalizes a single segment of a `pathArray` object. - * - * @param {SVGPathCommander.pathSegment} segment the segment object - * @param {any} params the coordinates of the previous segment - * @param {string} prevCommand the path command of the previous segment - * @returns {SVGPathCommander.normalSegment} the normalized segment - */ -function normalizeSegment(segment, params, prevCommand) { - const [pathCommand] = segment; - const { - x1: px1, y1: py1, x2: px2, y2: py2, - } = params; - const values = segment.slice(1).map(Number); - let result = segment; - - if (!'TQ'.includes(pathCommand)) { - // optional but good to be cautious - params.qx = null; - params.qy = null; - } - - if (pathCommand === 'H') { - result = ['L', segment[1], py1]; - } else if (pathCommand === 'V') { - result = ['L', px1, segment[1]]; - } else if (pathCommand === 'S') { - const { x1, y1 } = shorthandToCubic(px1, py1, px2, py2, prevCommand); - params.x1 = x1; - params.y1 = y1; - // @ts-ignore - result = ['C', x1, y1, ...values]; - } else if (pathCommand === 'T') { - const { qx, qy } = shorthandToQuad(px1, py1, params.qx, params.qy, prevCommand); - params.qx = qx; - params.qy = qy; - // @ts-ignore - result = ['Q', qx, qy, ...values]; - } else if (pathCommand === 'Q') { - const [nqx, nqy] = values; - params.qx = nqx; - params.qy = nqy; - } - - // @ts-ignore -- we-re switching `pathSegment` type - return result; -} - -/** - * Iterates an array to check if it's a `pathArray` - * with all segments are in non-shorthand notation - * with absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ -function isNormalizedArray(path) { - // @ts-ignore -- `isAbsoluteArray` also checks if it's `Array` - return isAbsoluteArray(path) && path.every((seg) => 'ACLMQZ'.includes(seg[0])); -} - -/** - * @type {SVGPathCommander.parserParams} - */ -const paramsParser = { - x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null, -}; - -/** - * Normalizes a `path` object for further processing: - * * convert segments to absolute values - * * convert shorthand path commands to their non-shorthand notation - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.normalArray} the normalized `pathArray` - */ -function normalizePath(pathInput) { - if (isNormalizedArray(pathInput)) { - // @ts-ignore -- `isNormalizedArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - /** @type {SVGPathCommander.normalArray} */ - // @ts-ignore -- `absoluteArray` will become a `normalArray` - const path = pathToAbsolute(pathInput); - const params = { ...paramsParser }; - const allPathCommands = []; - const ii = path.length; - let pathCommand = ''; - let prevCommand = ''; - - for (let i = 0; i < ii; i += 1) { - [pathCommand] = path[i]; - - // Save current path command - allPathCommands[i] = pathCommand; - // Get previous path command - if (i) prevCommand = allPathCommands[i - 1]; - // Previous path command is used to normalizeSegment - // @ts-ignore -- expected on normalization - path[i] = normalizeSegment(path[i], params, prevCommand); - - const segment = path[i]; - const seglen = segment.length; - - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - return path; -} - -/** - * Checks a `pathArray` for an unnecessary `Z` segment - * and returns a new `pathArray` without it. - * - * The `pathInput` must be a single path, without - * sub-paths. For multi-path `` elements, - * use `splitPath` first and apply this utility on each - * sub-path separately. - * - * @param {SVGPathCommander.pathArray | string} pathInput the `pathArray` source - * @return {SVGPathCommander.pathArray} a fixed `pathArray` - */ -function fixPath(pathInput) { - const pathArray = parsePathString(pathInput); - const normalArray = normalizePath(pathArray); - const { length } = pathArray; - const isClosed = normalArray.slice(-1)[0][0] === 'Z'; - const segBeforeZ = isClosed ? length - 2 : length - 1; - - const [mx, my] = normalArray[0].slice(1); - const [x, y] = normalArray[segBeforeZ].slice(-2); - - if (isClosed && mx === x && my === y) { - // @ts-ignore -- `pathSegment[]` is quite a `pathArray` - return pathArray.slice(0, -1); - } - return pathArray; -} - -/** - * Iterates an array to check if it's a `pathArray` - * with all C (cubic bezier) segments. - * - * @param {string | SVGPathCommander.pathArray} path the `Array` to be checked - * @returns {boolean} iteration result - */ -function isCurveArray(path) { - // @ts-ignore -- `isPathArray` also checks if it's `Array` - return isPathArray(path) && path.every((seg) => 'MC'.includes(seg[0])); -} - -/** - * Returns an {x,y} vector rotated by a given - * angle in radian. - * - * @param {number} x the initial vector x - * @param {number} y the initial vector y - * @param {number} rad the radian vector angle - * @returns {{x: number, y: number}} the rotated vector - */ -function rotateVector(x, y, rad) { - const X = x * Math.cos(rad) - y * Math.sin(rad); - const Y = x * Math.sin(rad) + y * Math.cos(rad); - return { x: X, y: Y }; -} - -/** - * Converts A (arc-to) segments to C (cubic-bezier-to). - * - * For more information of where this math came from visit: - * http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - * - * @param {number} X1 the starting x position - * @param {number} Y1 the starting y position - * @param {number} RX x-radius of the arc - * @param {number} RY y-radius of the arc - * @param {number} angle x-axis-rotation of the arc - * @param {number} LAF large-arc-flag of the arc - * @param {number} SF sweep-flag of the arc - * @param {number} X2 the ending x position - * @param {number} Y2 the ending y position - * @param {number[]=} recursive the parameters needed to split arc into 2 segments - * @return {number[]} the resulting cubic-bezier segment(s) - */ -function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) { - let x1 = X1; let y1 = Y1; let rx = RX; let ry = RY; let x2 = X2; let y2 = Y2; - // for more information of where this Math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - const d120 = (Math.PI * 120) / 180; - - const rad = (Math.PI / 180) * (+angle || 0); - /** @type {number[]} */ - let res = []; - let xy; - let f1; - let f2; - let cx; - let cy; - - if (!recursive) { - xy = rotateVector(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotateVector(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - - const x = (x1 - x2) / 2; - const y = (y1 - y2) / 2; - let h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = Math.sqrt(h); - rx *= h; - ry *= h; - } - const rx2 = rx * rx; - const ry2 = ry * ry; - - const k = (LAF === SF ? -1 : 1) - * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) - / (rx2 * y * y + ry2 * x * x))); - - cx = ((k * rx * y) / ry) + ((x1 + x2) / 2); - cy = ((k * -ry * x) / rx) + ((y1 + y2) / 2); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f1 = (Math.asin((((y1 - cy) / ry))) * (10 ** 9) >> 0) / (10 ** 9); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f2 = (Math.asin((((y2 - cy) / ry))) * (10 ** 9) >> 0) / (10 ** 9); - - f1 = x1 < cx ? Math.PI - f1 : f1; - f2 = x2 < cx ? Math.PI - f2 : f2; - if (f1 < 0) (f1 = Math.PI * 2 + f1); - if (f2 < 0) (f2 = Math.PI * 2 + f2); - if (SF && f1 > f2) { - f1 -= Math.PI * 2; - } - if (!SF && f2 > f1) { - f2 -= Math.PI * 2; - } - } else { - [f1, f2, cx, cy] = recursive; - } - let df = f2 - f1; - if (Math.abs(df) > d120) { - const f2old = f2; - const x2old = x2; - const y2old = y2; - f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1); - x2 = cx + rx * Math.cos(f2); - y2 = cy + ry * Math.sin(f2); - res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - const c1 = Math.cos(f1); - const s1 = Math.sin(f1); - const c2 = Math.cos(f2); - const s2 = Math.sin(f2); - const t = Math.tan(df / 4); - const hx = (4 / 3) * rx * t; - const hy = (4 / 3) * ry * t; - const m1 = [x1, y1]; - const m2 = [x1 + hx * s1, y1 - hy * c1]; - const m3 = [x2 + hx * s2, y2 - hy * c2]; - const m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return [...m2, ...m3, ...m4, ...res]; - } - res = [...m2, ...m3, ...m4, ...res]; - const newres = []; - for (let i = 0, ii = res.length; i < ii; i += 1) { - newres[i] = i % 2 - ? rotateVector(res[i - 1], res[i], rad).y - : rotateVector(res[i], res[i + 1], rad).x; - } - return newres; -} - -/** - * Converts a Q (quadratic-bezier) segment to C (cubic-bezier). - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @returns {number[]} the cubic-bezier segment - */ -function quadToCubic(x1, y1, qx, qy, x2, y2) { - const r13 = 1 / 3; - const r23 = 2 / 3; - return [ - r13 * x1 + r23 * qx, // cpx1 - r13 * y1 + r23 * qy, // cpy1 - r13 * x2 + r23 * qx, // cpx2 - r13 * y2 + r23 * qy, // cpy2 - x2, y2, // x,y - ]; -} - -/** - * Returns the coordinates of a specified distance - * ratio between two points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @param {number} t the ratio - * @returns {[number, number]} the midpoint coordinates - */ -function midPoint(a, b, t) { - const [ax, ay] = a; const [bx, by] = b; - return [ax + (bx - ax) * t, ay + (by - ay) * t]; -} - -/** - * Returns the square root of the distance - * between two given points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @returns {number} the distance value - */ -function distanceSquareRoot(a, b) { - return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) - + (a[1] - b[1]) * (a[1] - b[1]), - ); -} - -/** - * Returns the length of a line (L,V,H,Z) segment, - * or a point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the distance to point - * @returns {{x: number, y: number} | number} the segment length or point - */ -function segmentLineFactory(x1, y1, x2, y2, distance) { - const length = distanceSquareRoot([x1, y1], [x2, y2]); - const margin = 0.001; - - if (typeof distance === 'number') { - if (distance < margin) { - return { x: x1, y: y1 }; - } - if (distance > length + margin) { - return { x: x2, y: y2 }; - } - const [x, y] = midPoint([x1, y1], [x2, y2], distance / length); - return { x, y }; - } - return length; -} - -/** - * Converts an L (line-to) segment to C (cubic-bezier). - * - * @param {number} x1 line start x - * @param {number} y1 line start y - * @param {number} x2 line end x - * @param {number} y2 line end y - * @returns {number[]} the cubic-bezier segment - */ -function lineToCubic(x1, y1, x2, y2) { - const t = 0.5; - /** @type {[number, number]} */ - const p0 = [x1, y1]; - /** @type {[number, number]} */ - const p1 = [x2, y2]; - const p2 = midPoint(p0, p1, t); - const p3 = midPoint(p1, p2, t); - const p4 = midPoint(p2, p3, t); - const p5 = midPoint(p3, p4, t); - const p6 = midPoint(p4, p5, t); - const seg1 = [...p0, ...p2, ...p4, ...p6, t]; - // @ts-ignore - const cp1 = segmentLineFactory(...seg1); - const seg2 = [...p6, ...p5, ...p3, ...p1, 0]; - // @ts-ignore - const cp2 = segmentLineFactory(...seg2); - - // @ts-ignore - return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2]; -} - -/** - * Converts any segment to C (cubic-bezier). - * - * @param {SVGPathCommander.pathSegment} segment the source segment - * @param {SVGPathCommander.parserParams} params the source segment parameters - * @returns {SVGPathCommander.cubicSegment | SVGPathCommander.MSegment} the cubic-bezier segment - */ -function segmentToCubic(segment, params) { - const [pathCommand] = segment; - const values = segment.slice(1).map((n) => +n); - const [x, y] = values; - let args; - const { - x1: px1, y1: py1, x: px, y: py, - } = params; - - if (!'TQ'.includes(pathCommand)) { - params.qx = null; - params.qy = null; - } - - switch (pathCommand) { - case 'M': - params.x = x; - params.y = y; - return segment; - case 'A': - args = [px1, py1, ...values]; - // @ts-ignore -- relax, the utility will return 6 numbers - return ['C', ...arcToCubic(...args)]; - case 'Q': - params.qx = x; - params.qy = y; - args = [px1, py1, ...values]; - // @ts-ignore -- also returning 6 numbers - return ['C', ...quadToCubic(...args)]; - case 'L': - // @ts-ignore -- also returning 6 numbers - return ['C', ...lineToCubic(px1, py1, x, y)]; - case 'Z': - // @ts-ignore -- also returning 6 numbers - return ['C', ...lineToCubic(px1, py1, px, py)]; - } - // @ts-ignore -- we're switching `pathSegment` type - return segment; -} - -/** - * Parses a path string value or 'pathArray' and returns a new one - * in which all segments are converted to cubic-bezier. - * - * In addition, un-necessary `Z` segment is removed if previous segment - * extends to the `M` segment. - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.curveArray} the resulted `pathArray` converted to cubic-bezier - */ -function pathToCurve(pathInput) { - if (isCurveArray(pathInput)) { - // @ts-ignore -- `isCurveArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - const path = fixPath(normalizePath(pathInput)); - const params = { ...paramsParser }; - const allPathCommands = []; - let pathCommand = ''; // ts-lint - let ii = path.length; - - for (let i = 0; i < ii; i += 1) { - [pathCommand] = path[i]; - allPathCommands[i] = pathCommand; - - path[i] = segmentToCubic(path[i], params); - - fixArc(path, allPathCommands, i); - ii = path.length; - - const segment = path[i]; - const seglen = segment.length; - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - // @ts-ignore - return path; -} - -/** - * SVGPathCommander default options - * @type {SVGPathCommander.options} - */ -const defaultOptions = { - origin: [0, 0, 0], - round: 4, -}; - -/** - * Rounds the values of a `pathArray` instance to - * a specified amount of decimals and returns it. - * - * @param {SVGPathCommander.pathArray} path the source `pathArray` - * @param {number | boolean} roundOption the amount of decimals to round numbers to - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` with rounded values - */ -function roundPath(path, roundOption) { - let { round } = defaultOptions; - if (roundOption === false || round === false) return clonePath(path); - round = roundOption >= 1 ? roundOption : round; - // to round values to the power - // the `round` value must be integer - // @ts-ignore - const pow = round >= 1 ? (10 ** round) : 1; - - // @ts-ignore -- `pathSegment[]` is `pathArray` - return path.map((pi) => { - const values = pi.slice(1).map(Number) - .map((n) => (n % 1 === 0 ? n : Math.round(n * pow) / pow)); - return [pi[0], ...values]; - }); -} - -/** - * Returns a valid `d` attribute string value created - * by rounding values and concatenating the `pathArray` segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` object - * @param {any} round amount of decimals to round values to - * @returns {string} the concatenated path string - */ -function pathToString(path, round) { - return roundPath(path, round) - .map((x) => x[0] + x.slice(1).join(' ')).join(''); -} - -/** - * Split a path into an `Array` of sub-path strings. - * - * In the process, values are converted to absolute - * for visual consistency. - * - * @param {SVGPathCommander.pathArray | string} pathInput the source `pathArray` - * @return {string[]} an array with all sub-path strings - */ -function splitPath(pathInput) { - return pathToString(pathToAbsolute(pathInput), 0) - .replace(/(m|M)/g, '|$1') - .split('|') - .map((s) => s.trim()) - .filter((s) => s); -} - -/** - * Returns a point at a given length of a C (cubic-bezier) segment. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number} t a [0-1] ratio - * @returns {{x: number, y: number}} the cubic-bezier segment length - */ -function getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t) { - const t1 = 1 - t; - return { - x: (t1 ** 3) * x1 - + 3 * (t1 ** 2) * t * c1x - + 3 * t1 * (t ** 2) * c2x - + (t ** 3) * x2, - y: (t1 ** 3) * y1 - + 3 * (t1 ** 2) * t * c1y - + 3 * t1 * (t ** 2) * c2y - + (t ** 3) * y2, - }; -} - -/** - * Returns the length of a C (cubic-bezier) segment, - * or an {x,y} point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the point distance - * @returns {{x: number, y: number} | number} the segment length or point - */ -function segmentCubicFactory(x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance) { - let x = x1; let y = y1; - const lengthMargin = 0.001; - let totalLength = 0; - let prev = [x1, y1, totalLength]; - /** @type {[number, number]} */ - let cur = [x1, y1]; - let t = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x, y }; - } - - const n = 100; - for (let j = 0; j <= n; j += 1) { - t = j / n; - - ({ x, y } = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t)); - totalLength += distanceSquareRoot(cur, [x, y]); - cur = [x, y]; - - if (typeof distance === 'number' && totalLength >= distance) { - const dv = (totalLength - distance) / (totalLength - prev[2]); - - return { - x: cur[0] * (1 - dv) + prev[0] * dv, - y: cur[1] * (1 - dv) + prev[1] * dv, - }; - } - prev = [x, y, totalLength]; - } - - if (typeof distance === 'number' && distance >= totalLength) { - return { x: x2, y: y2 }; - } - return totalLength; -} - -/** - * Returns the length of a A (arc-to) segment, - * or an {x,y} point at a given length. - * - * @param {number} X1 the starting x position - * @param {number} Y1 the starting y position - * @param {number} RX x-radius of the arc - * @param {number} RY y-radius of the arc - * @param {number} angle x-axis-rotation of the arc - * @param {number} LAF large-arc-flag of the arc - * @param {number} SF sweep-flag of the arc - * @param {number} X2 the ending x position - * @param {number} Y2 the ending y position - * @param {number} distance the point distance - * @returns {{x: number, y: number} | number} the segment length or point - */ -function segmentArcFactory(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, distance) { - let [x, y] = [X1, Y1]; - const cubicSeg = arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2); - const lengthMargin = 0.001; - let totalLength = 0; - let cubicSubseg = []; - let argsc = []; - let segLen = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x, y }; - } - - for (let i = 0, ii = cubicSeg.length; i < ii; i += 6) { - cubicSubseg = cubicSeg.slice(i, i + 6); - argsc = [x, y, ...cubicSubseg]; - // @ts-ignore - segLen = segmentCubicFactory(...argsc); - if (typeof distance === 'number' && totalLength + segLen >= distance) { - // @ts-ignore -- this is a `cubicSegment` - return segmentCubicFactory(...argsc, distance - totalLength); - } - totalLength += segLen; - [x, y] = cubicSubseg.slice(-2); - } - - if (typeof distance === 'number' && distance >= totalLength) { - return { x: X2, y: Y2 }; - } - - return totalLength; -} - -/** - * Returns the {x,y} coordinates of a point at a - * given length of a quad-bezier segment. - * - * @see https://github.com/substack/point-at-length - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} cx the control point X - * @param {number} cy the control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number} t a [0-1] ratio - * @returns {{x: number, y: number}} the requested {x,y} coordinates - */ -function getPointAtQuadSegmentLength(x1, y1, cx, cy, x2, y2, t) { - const t1 = 1 - t; - return { - x: (t1 ** 2) * x1 - + 2 * t1 * t * cx - + (t ** 2) * x2, - y: (t1 ** 2) * y1 - + 2 * t1 * t * cy - + (t ** 2) * y2, - }; -} - -/** - * Returns the Q (quadratic-bezier) segment length, - * or an {x,y} point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} qx the control point X - * @param {number} qy the control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the distance to point - * @returns {{x: number, y: number} | number} the segment length or point - */ -function segmentQuadFactory(x1, y1, qx, qy, x2, y2, distance) { - let x = x1; let y = y1; - const lengthMargin = 0.001; - let totalLength = 0; - let prev = [x1, y1, totalLength]; - /** @type {[number, number]} */ - let cur = [x1, y1]; - let t = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x, y }; - } - - const n = 100; - for (let j = 0; j <= n; j += 1) { - t = j / n; - - ({ x, y } = getPointAtQuadSegmentLength(x1, y1, qx, qy, x2, y2, t)); - totalLength += distanceSquareRoot(cur, [x, y]); - cur = [x, y]; - - if (typeof distance === 'number' && totalLength >= distance) { - const dv = (totalLength - distance) / (totalLength - prev[2]); - - return { - x: cur[0] * (1 - dv) + prev[0] * dv, - y: cur[1] * (1 - dv) + prev[1] * dv, - }; - } - prev = [x, y, totalLength]; - } - if (typeof distance === 'number' && distance >= totalLength) { - return { x: x2, y: y2 }; - } - return totalLength; -} - -/** - * Returns a {x,y} point at a given length of a shape or the shape total length. - * - * @param {string | SVGPathCommander.pathArray} pathInput the `pathArray` to look into - * @param {number=} distance the length of the shape to look at - * @returns {{x: number, y: number} | number} the total length or point - */ -function pathLengthFactory(pathInput, distance) { - let totalLength = 0; - let isM = true; - /** @type {number[]} */ - let data = []; - let pathCommand = 'M'; - let segLen = 0; - let x = 0; - let y = 0; - let mx = 0; - let my = 0; - let seg; - const path = fixPath(normalizePath(pathInput)); - - for (let i = 0, ll = path.length; i < ll; i += 1) { - seg = path[i]; - [pathCommand] = seg; - isM = pathCommand === 'M'; - // @ts-ignore - data = !isM ? [x, y, ...seg.slice(1)] : data; - - // this segment is always ZERO - if (isM) { - // remember mx, my for Z - // @ts-ignore - [, mx, my] = seg; - if (typeof distance === 'number' && distance < 0.001) { - return { x: mx, y: my }; - } - } else if (pathCommand === 'L') { - // @ts-ignore - segLen = segmentLineFactory(...data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentLineFactory(...data, distance - totalLength); - } - totalLength += segLen; - } else if (pathCommand === 'A') { - // @ts-ignore - segLen = segmentArcFactory(...data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentArcFactory(...data, distance - totalLength); - } - totalLength += segLen; - } else if (pathCommand === 'C') { - // @ts-ignore - segLen = segmentCubicFactory(...data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentCubicFactory(...data, distance - totalLength); - } - totalLength += segLen; - } else if (pathCommand === 'Q') { - // @ts-ignore - segLen = segmentQuadFactory(...data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentQuadFactory(...data, distance - totalLength); - } - totalLength += segLen; - } else if (pathCommand === 'Z') { - data = [x, y, mx, my]; - // @ts-ignore - segLen = segmentLineFactory(...data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentLineFactory(...data, distance - totalLength); - } - totalLength += segLen; - } - - // @ts-ignore -- needed for the below - [x, y] = pathCommand !== 'Z' ? seg.slice(-2) : [mx, my]; - } - - // native `getPointAtLength` behavior when the given distance - // is higher than total length - if (distance && distance >= totalLength) { - return { x, y }; - } - - return totalLength; -} - -/** - * Returns the shape total length, or the equivalent to `shape.getTotalLength()`. - * - * The `normalizePath` version is lighter, faster, more efficient and more accurate - * with paths that are not `curveArray`. - * - * @param {string | SVGPathCommander.pathArray} pathInput the target `pathArray` - * @returns {number} the shape total length - */ -function getTotalLength(pathInput) { - // @ts-ignore - it's fine - return pathLengthFactory(pathInput); -} - -/** - * Returns [x,y] coordinates of a point at a given length of a shape. - * - * @param {string | SVGPathCommander.pathArray} pathInput the `pathArray` to look into - * @param {number} distance the length of the shape to look at - * @returns {{x: number, y: number}} the requested {x, y} point coordinates - */ -function getPointAtLength(pathInput, distance) { - // @ts-ignore - return pathLengthFactory(pathInput, distance); -} - -/** - * d3-polygon-area - * https://github.com/d3/d3-polygon - * - * Returns the area of a polygon. - * - * @param {number[][]} polygon an array of coordinates - * @returns {number} the polygon area - */ -function polygonArea(polygon) { - const n = polygon.length; - let i = -1; - let a; - let b = polygon[n - 1]; - let area = 0; - - /* eslint-disable-next-line */ - while (++i < n) { - a = b; - b = polygon[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - - return area / 2; -} - -/** - * d3-polygon-length - * https://github.com/d3/d3-polygon - * - * Returns the perimeter of a polygon. - * - * @param {number[][]} polygon an array of coordinates - * @returns {number} the polygon length - */ -function polygonLength(polygon) { - return polygon.reduce((length, point, i) => { - if (i) { - // @ts-ignore - return length + distanceSquareRoot(polygon[i - 1], point); - } - return 0; - }, 0); -} - -/** - * A global namespace for epsilon. - * - * @type {number} - */ -const epsilon = 1e-9; - -/** - * Coordinates Interpolation Function. - * - * @param {number[][]} a start coordinates - * @param {number[][]} b end coordinates - * @param {string} l amount of coordinates - * @param {number} v progress - * @returns {number[][]} the interpolated coordinates - */ -function coords(a, b, l, v) { - const points = []; - for (let i = 0; i < l; i += 1) { // for each point - points[i] = []; - for (let j = 0; j < 2; j += 1) { // each point coordinate - // eslint-disable-next-line no-bitwise - points[i].push(((a[i][j] + (b[i][j] - a[i][j]) * v) * 1000 >> 0) / 1000); - } - } - return points; -} - -/* SVGMorph = { - property: 'path', - defaultValue: [], - interpolators: {numbers,coords} }, - functions = { prepareStart, prepareProperty, onStart, crossCheck } -} */ - -// Component functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -function onStartSVGMorph(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - const path1 = a.polygon; const path2 = b.polygon; - const len = path2.length; - elem.setAttribute('d', (v === 1 ? b.original : `M${coords(path1, path2, len, v).join('L')}Z`)); - }; - } -} - -// Component Util -// original script flubber -// https://github.com/veltman/flubber - -/** - * Returns an existing polygon or false if it's not a polygon. - * @param {SVGPathCommander.pathArray} pathArray target `pathArray` - * @returns {KUTE.exactPolygon | false} the resulted polygon - */ -function exactPolygon(pathArray) { - const polygon = []; - const pathlen = pathArray.length; - let segment = []; - let pathCommand = ''; - - if (!pathArray.length || pathArray[0][0] !== 'M') { - return false; - } - - for (let i = 0; i < pathlen; i += 1) { - segment = pathArray[i]; - [pathCommand] = segment; - - if ((pathCommand === 'M' && i) || pathCommand === 'Z') { - break; // !! - } else if ('ML'.includes(pathCommand)) { - polygon.push([segment[1], segment[2]]); - } else { - return false; - } - } - - return pathlen ? { polygon } : false; -} - -/** - * Returns a new polygon polygon. - * @param {SVGPathCommander.pathArray} parsed target `pathArray` - * @param {number} maxLength the maximum segment length - * @returns {KUTE.exactPolygon} the resulted polygon - */ -function approximatePolygon(parsed, maxLength) { - const ringPath = splitPath(pathToString(parsed))[0]; - const normalPath = normalizePath(ringPath); - const pathLength = getTotalLength(normalPath); - const polygon = []; - let numPoints = 3; - let point; - - if (maxLength && !Number.isNaN(maxLength) && +maxLength > 0) { - numPoints = Math.max(numPoints, Math.ceil(pathLength / maxLength)); - } - - for (let i = 0; i < numPoints; i += 1) { - point = getPointAtLength(normalPath, (pathLength * i) / numPoints); - polygon.push([point.x, point.y]); - } - - // Make all rings clockwise - if (polygonArea(polygon) > 0) { - polygon.reverse(); - } - - return { - polygon, - skipBisect: true, - }; -} - -/** - * Parses a path string and returns a polygon array. - * @param {string} str path string - * @param {number} maxLength maximum amount of points - * @returns {KUTE.exactPolygon} the polygon array we need - */ -function pathStringToPolygon(str, maxLength) { - const parsed = normalizePath(str); - return exactPolygon(parsed) || approximatePolygon(parsed, maxLength); -} - -/** - * Rotates a polygon to better match its pair. - * @param {KUTE.polygonMorph} polygon the target polygon - * @param {KUTE.polygonMorph} vs the reference polygon - */ -function rotatePolygon(polygon, vs) { - const len = polygon.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; - - for (let i = 0; i < vs.length; i += 1) { - p = vs[i]; - d = distanceSquareRoot(polygon[(offset + i) % len], p); - sumOfSquares += d * d; - } - - if (sumOfSquares < min) { - min = sumOfSquares; - bestOffset = offset; - } - } - - if (bestOffset) { - spliced = polygon.splice(0, bestOffset); - polygon.splice(polygon.length, 0, ...spliced); - } -} - -/** - * Sample additional points for a polygon to better match its pair. - * @param {KUTE.polygonObject} polygon the target polygon - * @param {number} numPoints the amount of points needed - */ -function addPoints(polygon, numPoints) { - const desiredLength = polygon.length + numPoints; - const step = polygonLength(polygon) / numPoints; - - let i = 0; - let cursor = 0; - let insertAt = step / 2; - let a; - let b; - let segment; - - while (polygon.length < desiredLength) { - a = polygon[i]; - b = polygon[(i + 1) % polygon.length]; - - segment = distanceSquareRoot(a, b); - - if (insertAt <= cursor + segment) { - polygon.splice(i + 1, 0, segment - ? midPoint(a, b, (insertAt - cursor) / segment) - : a.slice(0)); - insertAt += step; - } else { - cursor += segment; - i += 1; - } - } -} - -/** - * Split segments of a polygon until it reaches a certain - * amount of points. - * @param {number[][]} polygon the target polygon - * @param {number} maxSegmentLength the maximum amount of points - */ -function bisect(polygon, maxSegmentLength = Infinity) { - let a = []; - let b = []; - - for (let i = 0; i < polygon.length; i += 1) { - a = polygon[i]; - b = i === polygon.length - 1 ? polygon[0] : polygon[i + 1]; - - // Could splice the whole set for a segment instead, but a bit messy - while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = midPoint(a, b, 0.5); - polygon.splice(i + 1, 0, b); - } - } -} - -/** - * Checks the validity of a polygon. - * @param {KUTE.polygonMorph} polygon the target polygon - * @returns {boolean} the result of the check - */ -function validPolygon(polygon) { - return Array.isArray(polygon) - && polygon.every((point) => Array.isArray(point) - && point.length === 2 - && !Number.isNaN(point[0]) - && !Number.isNaN(point[1])); -} - -/** - * Returns a new polygon and its length from string or another `Array`. - * @param {KUTE.polygonMorph | string} input the target polygon - * @param {number} maxSegmentLength the maximum amount of points - * @returns {KUTE.polygonMorph} normalized polygon - */ -function getPolygon(input, maxSegmentLength) { - let skipBisect; - let polygon; - - if (typeof (input) === 'string') { - const converted = pathStringToPolygon(input, maxSegmentLength); - ({ polygon, skipBisect } = converted); - } else if (!Array.isArray(input)) { - throw Error(`${invalidPathValue}: ${input}`); - } - - /** @type {KUTE.polygonMorph} */ - const points = [...polygon]; - - if (!validPolygon(points)) { - throw Error(`${invalidPathValue}: ${points}`); - } - - // TODO skip this test to avoid scale issues? - // Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9 - if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { - points.pop(); - } - - if (!skipBisect && maxSegmentLength - && !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) { - bisect(points, maxSegmentLength); - } - - return points; -} - -/** - * Returns two new polygons ready to tween. - * @param {string} path1 the first path string - * @param {string} path2 the second path string - * @param {number} precision the morphPrecision option value - * @returns {KUTE.polygonMorph[]} the two polygons - */ -function getInterpolationPoints(path1, path2, precision) { - const morphPrecision = precision || defaultOptions$1.morphPrecision; - const fromRing = getPolygon(path1, morphPrecision); - const toRing = getPolygon(path2, morphPrecision); - const diff = fromRing.length - toRing.length; - - addPoints(fromRing, diff < 0 ? diff * -1 : 0); - addPoints(toRing, diff > 0 ? diff : 0); - - rotatePolygon(fromRing, toRing); - - return [roundPath(fromRing), roundPath(toRing)]; -} - -// Component functions -/** - * Returns the current `d` attribute value. - * @returns {string} the `d` attribute value - */ -function getSVGMorph(/* tweenProp */) { - return this.element.getAttribute('d'); -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.polygonObject} value the property value - * @returns {KUTE.polygonObject} the property tween object - */ -function prepareSVGMorph(/* tweenProp */_, value) { - const pathObject = {}; - // remove newlines, they brake JSON strings sometimes - const pathReg = new RegExp('\\n', 'ig'); - let elem = null; - - if (value instanceof SVGPathElement) { - elem = value; - } else if (/^\.|^#/.test(value)) { - elem = selector(value); - } - - // first make sure we return pre-processed values - if (typeof (value) === 'object' && value.polygon) { - return value; - } if (elem && ['path', 'glyph'].includes(elem.tagName)) { - pathObject.original = elem.getAttribute('d').replace(pathReg, ''); - // maybe it's a string path already - } else if (!elem && typeof (value) === 'string') { - pathObject.original = value.replace(pathReg, ''); - } - - return pathObject; -} - -/** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} prop the `path` property name - */ -function crossCheckSVGMorph(prop) { - if (this.valuesEnd[prop]) { - const pathArray1 = this.valuesStart[prop].polygon; - const pathArray2 = this.valuesEnd[prop].polygon; - // skip already processed paths - // allow the component to work with pre-processed values - if (!pathArray1 || !pathArray2 - || (pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length)) { - const p1 = this.valuesStart[prop].original; - const p2 = this.valuesEnd[prop].original; - // process morphPrecision - const morphPrecision = this._morphPrecision - ? parseInt(this._morphPrecision, 10) - : defaultOptions$1.morphPrecision; - - const [path1, path2] = getInterpolationPoints(p1, p2, morphPrecision); - this.valuesStart[prop].polygon = path1; - this.valuesEnd[prop].polygon = path2; - } - } -} - -// All Component Functions -const svgMorphFunctions = { - prepareStart: getSVGMorph, - prepareProperty: prepareSVGMorph, - onStart: onStartSVGMorph, - crossCheck: crossCheckSVGMorph, -}; - -// Component Full -const SVGMorph = { - component: 'svgMorph', - property: 'path', - defaultValue: [], - Interpolate: coords, - defaultOptions: { morphPrecision: 10 }, - functions: svgMorphFunctions, - // Export utils to global for faster execution - Util: { - // component - addPoints, - bisect, - getPolygon, - validPolygon, - getInterpolationPoints, - pathStringToPolygon, - distanceSquareRoot, - midPoint, - approximatePolygon, - rotatePolygon, - // svg-path-commander - pathToString, - pathToCurve, - getTotalLength, - getPointAtLength, - polygonArea, - roundPath, - }, -}; - -const Components = { - EssentialBoxModel: BoxModelEssential, - ColorsProperties: colorProperties, - HTMLAttributes: htmlAttributes, - OpacityProperty, - TextWriteProp: TextWrite, - TransformFunctions, - SVGDraw: SvgDrawProperty, - SVGMorph, -}; - -// init components -Object.keys(Components).forEach((component) => { - const compOps = Components[component]; - Components[component] = new Animation(compOps); -}); - -var version = "2.2.3"; - -// @ts-ignore - -/** - * A global namespace for library version. - * @type {string} - */ -const Version = version; - -// KUTE.js standard distribution version - -const KUTE = { - Animation, - Components, - - // Tween Interface - Tween, - fromTo, - to, - // Tween Collection - TweenCollection, - allFromTo, - allTo, - // Tween Interface - - Objects, - Util, - Easing, - CubicBezier, - Render, - Interpolate: interpolate, - Process, - Internals: internals, - Selector: selector, - Version, -}; - -export { KUTE as default }; diff --git a/dist/kute.esm.min.js b/dist/kute.esm.min.js deleted file mode 100644 index e5705e2..0000000 --- a/dist/kute.esm.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// KUTE.js Standard v2.2.3 | thednp © 2021 | MIT-License -class t{constructor(t,e,n,r,s){this.cx=3*t,this.bx=3*(n-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(r-e)-this.cy,this.ay=1-this.cy-this.by;const i=t=>this.sampleCurveY(this.solveCurveX(t));return Object.defineProperty(i,"name",{writable:!0}),i.name=s||`cubic-bezier(${[t,e,n,r]})`,i}sampleCurveX(t){return((this.ax*t+this.bx)*t+this.cx)*t}sampleCurveY(t){return((this.ay*t+this.by)*t+this.cy)*t}sampleCurveDerivativeX(t){return(3*this.ax*t+2*this.bx)*t+this.cx}solveCurveX(t){let e,n,r,s,i,a;const o=1e-5;for(r=t,a=0;a<32;a+=1){if(s=this.sampleCurveX(r)-t,Math.abs(s)n)return n;for(;es?e=r:n=r,r=.5*(n-e)+e}return r}}Object.assign(t,{Version:"1.0.18"});const e={},n=[];let r;r="undefined"!=typeof global?global:"undefined"!=typeof window?window.self:{};const s=r,i={},a={};let o;o="undefined"==typeof self&&"undefined"!=typeof process&&process.hrtime?()=>{const t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:"undefined"!=typeof self&&void 0!==self.performance&&void 0!==self.performance.now?self.performance.now.bind(self.performance):"undefined"!=typeof Date&&Date.now?Date.now:()=>(new Date).getTime();const l=o,c={};c.now=l;let u=0;const h=t=>{let e=0;for(;e{!n.length&&u&&(cancelAnimationFrame(u),u=null,Object.keys(a).forEach((t=>{"function"==typeof a[t]?e[t]&&delete e[t]:Object.keys(a[t]).forEach((t=>{e[t]&&delete e[t]}))})),Object.keys(i).forEach((t=>{e[t]&&delete e[t]})))}),64)}const f={Tick:u,Ticker:h,Tweens:n,Time:c};Object.keys(f).forEach((t=>{e[t]||(e[t]="Time"===t?c.now:f[t])})),s._KUTE=e;const d={},g={},y={duration:700,delay:0,easing:"linear",repeat:0,repeatDelay:0,yoyo:!1,resetStart:!1,offset:0},m={},b={},v={},x={},E={},w={supportedProperties:d,defaultValues:g,defaultOptions:y,prepareProperty:m,prepareStart:b,crossCheck:v,onStart:a,onComplete:x,linkProperty:E},k={},_=t=>n.push(t),C=t=>{const e=n.indexOf(t);-1!==e&&n.splice(e,1)};function O(){Object.keys(E).forEach((t=>{const n=E[t],r=d[t];Object.keys(n).forEach((t=>{"function"==typeof n[t]&&Object.keys(this.valuesEnd).some((t=>r&&r.includes(t)||"attr"===t&&Object.keys(this.valuesEnd[t]).some((t=>r&&r.includes(t)))))?e[t]||(e[t]=n[t]):Object.keys(this.valuesEnd).forEach((r=>{const s=this.valuesEnd[r];s instanceof Object&&Object.keys(s).forEach((r=>{"function"==typeof n[r]?e[r]||(e[r]=n[r]):Object.keys(n[t]).forEach((t=>{n[r]&&"function"==typeof n[r][t]&&(e[t]||(e[t]=n[r][t]))}))}))}))}))}))}const M={add:_,remove:C,getAll:()=>n,removeAll:()=>{n.length=0},stop:p,linkInterpolation:O};function T(t){if(!t.style)return!1;const e=t.style.cssText.replace(/\s/g,"").split(";"),n={},r=["translate3d","translate","scale3d","skew"];return e.forEach((t=>{if(/transform/i.test(t)){t.split(":")[1].split(")").forEach((t=>{const e=t.split("("),s=e[0],i=e[1];/matrix/.test(s)||(n[s]=r.includes(s)?i.split(","):i)}))}})),n}function I(t,e){let n=g[e];const r=t.style,s=getComputedStyle(t)||t.currentStyle,i=r[e]&&!/auto|initial|none|unset/.test(r[e])?r[e]:s[e];return"transform"!==e&&(e in s||e in r)&&(n=i),n}function S(t,e){const n="start"===e?this.valuesStart:this.valuesEnd;Object.keys(m).forEach((e=>{const r=m[e],s=d[e];Object.keys(r).forEach((e=>{const i={};Object.keys(t).forEach((a=>{g[a]&&r[a]?n[a]=r[a].call(this,a,t[a]):!g[e]&&"transform"===e&&s.includes(a)?i[a]=t[a]:g[a]||"transform"!==a?!g[e]&&s&&s.includes(a)&&(n[a]=r[e].call(this,a,t[a])):n[a]=t[a]})),Object.keys(i).length&&(n[e]=r[e].call(this,e,i))}))}))}function A(){const t={},e=T(this.element);Object.keys(this.valuesStart).forEach((e=>{Object.keys(b).forEach((n=>{const r=b[n];Object.keys(r).forEach((s=>{(s===e&&r[e]||d[n]&&d[n].includes(e))&&(t[e]=r[s].call(this,e,this.valuesStart[e]))}))}))})),Object.keys(e).forEach((n=>{n in this.valuesStart||(t[n]=e[n]||g[n])})),this.valuesStart={},S.call(this,t,"start")}var j={getInlineStyle:T,getStyleForProperty:I,getStartValues:A,prepareObject:S};const P={tween:null,processEasing:null},$={linear:new t(0,0,1,1,"linear"),easingSinusoidalIn:new t(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new t(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new t(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new t(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new t(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new t(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new t(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new t(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new t(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new t(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new t(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new t(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new t(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new t(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new t(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new t(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new t(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new t(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new t(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new t(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new t(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new t(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new t(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new t(.68,-.55,.265,1.55,"easingBackInOut")};function L(t,e){try{let n,r;return e?(r=t instanceof Array&&t.every((t=>t instanceof Element)),n=t instanceof HTMLCollection||t instanceof NodeList||r?t:document.querySelectorAll(t)):n=t instanceof Element||t===window?t:document.querySelector(t),n}catch(e){throw TypeError(`KUTE.js - Element(s) not found: ${t}.`)}}function N(){Object.keys(a).forEach((t=>{"function"==typeof a[t]?a[t].call(this,t):Object.keys(a[t]).forEach((e=>{a[t][e].call(this,e)}))})),O.call(this)}P.processEasing=function(e){if("function"==typeof e)return e;if("function"==typeof $[e])return $[e];if(/bezier/.test(e)){const n=e.replace(/bezier|\s|\(|\)/g,"").split(",");return new t(1*n[0],1*n[1],1*n[2],1*n[3])}return $.linear};class q{constructor(t,n,r,s){this.element=t,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n;const i=s||{};this._resetStart=i.resetStart||0,this._easing="function"==typeof i.easing?i.easing:P.processEasing(i.easing),this._duration=i.duration||y.duration,this._delay=i.delay||y.delay,Object.keys(i).forEach((t=>{const e=`_${t}`;e in this||(this[e]=i[t])}));const o=this._easing.name;return a[o]||(a[o]=function(t){e[t]||t!==this._easing.name||(e[t]=this._easing)}),this}start(t){return _(this),this.playing=!0,this._startTime=void 0!==t?t:e.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),N.call(this),this._startFired=!0),u||h(),this}stop(){return this.playing&&(C(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this}close(){Object.keys(x).forEach((t=>{Object.keys(x[t]).forEach((e=>{x[t][e].call(this,e)}))})),this._startFired=!1,p.call(this)}chain(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this}stopChainedTweens(){this._chain&&this._chain.length&&this._chain.forEach((t=>t.stop()))}update(t){const n=void 0!==t?t:e.Time();let r;if(n1?1:r;const s=this._easing(r);return Object.keys(this.valuesEnd).forEach((t=>{e[t](this.element,this.valuesStart[t],this.valuesEnd[t],s)})),this._onUpdate&&this._onUpdate.call(this),1!==r||(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.map((t=>t.start())),!1)}}P.tween=q;class V extends q{constructor(...t){super(...t),this.valuesStart={},this.valuesEnd={};const[e,n,r]=t.slice(1);return S.call(this,n,"end"),this._resetStart?this.valuesStart=e:S.call(this,e,"start"),this._resetStart||Object.keys(v).forEach((t=>{Object.keys(v[t]).forEach((e=>{v[t][e].call(this,e)}))})),this.paused=!1,this._pauseTime=null,this._repeat=r.repeat||y.repeat,this._repeatDelay=r.repeatDelay||y.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=r.yoyo||y.yoyo,this._reversed=!1,this}start(t){return this._resetStart&&(this.valuesStart=this._resetStart,A.call(this),Object.keys(v).forEach((t=>{Object.keys(v[t]).forEach((e=>{v[t][e].call(this,e)}))}))),this.paused=!1,this._yoyo&&Object.keys(this.valuesEnd).forEach((t=>{this.valuesRepeat[t]=this.valuesStart[t]})),super.start(t),this}stop(){return super.stop(),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this}close(){return super.close(),this._repeatOption>0&&(this._repeat=this._repeatOption),this._yoyo&&!0===this._reversed&&(this.reverse(),this._reversed=!1),this}resume(){return this.paused&&this.playing&&(this.paused=!1,void 0!==this._onResume&&this._onResume.call(this),N.call(this),this._startTime+=e.Time()-this._pauseTime,_(this),u||h()),this}pause(){return!this.paused&&this.playing&&(C(this),this.paused=!0,this._pauseTime=e.Time(),void 0!==this._onPause&&this._onPause.call(this)),this}reverse(){Object.keys(this.valuesEnd).forEach((t=>{const e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}))}update(t){const n=void 0!==t?t:e.Time();let r;if(n1?1:r;const s=this._easing(r);return Object.keys(this.valuesEnd).forEach((t=>{e[t](this.element,this.valuesStart[t],this.valuesEnd[t],s)})),this._onUpdate&&this._onUpdate.call(this),1!==r||(this._repeat>0?(Number.isFinite(this._repeat)&&(this._repeat-=1),this._startTime=n,Number.isFinite(this._repeat)&&this._yoyo&&!this._reversed&&(this._startTime+=this._repeatDelay),this._yoyo&&(this._reversed=!this._reversed,this.reverse()),!0):(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.forEach((t=>t.start())),!1))}}P.tween=V;class H{constructor(t,e,n,r){const s=P.tween;this.tweens=[];const i=r||{};i.delay=i.delay||y.delay;const a=[];return Array.from(t).forEach(((t,r)=>{if(a[r]=i||{},a[r].delay=r>0?i.delay+(i.offset||y.offset):i.delay,!(t instanceof Element))throw Error(`KUTE - ${t} is not instanceof Element`);this.tweens.push(new s(t,e,n,a[r]))})),this.length=this.tweens.length,this}start(t){const n=void 0===t?e.Time():t;return this.tweens.map((t=>t.start(n))),this}stop(){return this.tweens.map((t=>t.stop())),this}pause(){return this.tweens.map((t=>t.pause())),this}resume(){return this.tweens.map((t=>t.resume())),this}chain(t){const e=this.tweens[this.length-1];if(t instanceof H)e.chain(t.tweens);else{if(!(t instanceof P.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this}playing(){return this.tweens.some((t=>t.playing))}removeTweens(){this.tweens=[]}getMaxDuration(){const t=[];return this.tweens.forEach((e=>{t.push(e._duration+e._delay+e._repeat*e._repeatDelay)})),Math.max(t)}}const{tween:Q}=P;const{tween:F}=P;class U{constructor(t){try{if(t.component in d)throw Error(`KUTE - ${t.component} already registered`);if(t.property in g)throw Error(`KUTE - ${t.property} already registered`)}catch(t){throw Error(t)}const e=this,n=t.component,r={prepareProperty:m,prepareStart:b,onStart:a,onComplete:x,crossCheck:v},s=t.category,o=t.property,l=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;return d[n]=t.properties||t.subProperties||t.property,"defaultValue"in t?(g[o]=t.defaultValue,e.supports=`${o} property`):t.defaultValues&&(Object.keys(t.defaultValues).forEach((e=>{g[e]=t.defaultValues[e]})),e.supports=`${l||o} ${o||s} properties`),t.defaultOptions&&Object.assign(y,t.defaultOptions),t.functions&&Object.keys(r).forEach((e=>{e in t.functions&&("function"==typeof t.functions[e]?(r[e][n]||(r[e][n]={}),r[e][n][s||o]||(r[e][n][s||o]=t.functions[e])):Object.keys(t.functions[e]).forEach((s=>{r[e][n]||(r[e][n]={}),r[e][n][s]||(r[e][n][s]=t.functions[e][s])})))})),t.Interpolate&&(Object.keys(t.Interpolate).forEach((e=>{const n=t.Interpolate[e];"function"!=typeof n||i[e]?Object.keys(n).forEach((t=>{"function"!=typeof n[t]||i[e]||(i[e]=n[t])})):i[e]=n})),E[n]=t.Interpolate),t.Util&&Object.keys(t.Util).forEach((e=>{k[e]||(k[e]=t.Util[e])})),e}}const D=(t,e)=>{const n=parseInt(t,10)||0,r=["px","%","deg","rad","em","rem","vh","vw"];let s;for(let e=0;e{e.style[t]=(s>.99||s<.01?(10*X(n,r,s)>>0)/10:X(n,r,s)>>0)+"px"})}const B={};["top","left","width","height"].forEach((t=>{B[t]=Z}));const R=["top","left","width","height"],Y={};R.forEach((t=>{Y[t]=Z}));const z={component:"essentialBoxModel",category:"boxModel",properties:R,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:X},functions:{prepareStart:function(t){return I(this.element,t)||g[t]},prepareProperty:function(t,e){const n=D(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:Y},Util:{trueDimension:D}},K=t=>{let e;if(/rgb|rgba/.test(t)){const n=t.replace(/\s|\)/,"").split("(")[1].split(","),r=n[3]?n[3]:null;r||(e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10)}),e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10),a:parseFloat(r)}}if(/^#/.test(t)){const n=(t=>{const e=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,((t,e,n,r)=>e+e+n+n+r+r)),n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return n?{r:parseInt(n[1],16),g:parseInt(n[2],16),b:parseInt(n[3],16)}:null})(t);e={r:n.r,g:n.g,b:n.b}}if(/transparent|none|initial|inherit/.test(t)&&(e={r:0,g:0,b:0,a:0}),!/^#|^rgb/.test(t)){const n=document.getElementsByTagName("head")[0];n.style.color=t;let r=getComputedStyle(n,null).color;r=/rgb/.test(r)?r.replace(/[^\d,]/g,"").split(","):[0,0,0],n.style.color="",e={r:parseInt(r[0],10),g:parseInt(r[1],10),b:parseInt(r[2],10)}}return e};function W(t,e,n){const r={},s=",";return Object.keys(e).forEach((s=>{"a"!==s?r[s]=X(t[s],e[s],n)>>0||0:t[s]&&e[s]&&(r[s]=(100*X(t[s],e[s],n)>>0)/100)})),r.a?"rgba("+r.r+s+r.g+s+r.b+s+r.a+")":"rgb("+r.r+s+r.g+s+r.b+")"}function G(t){this.valuesEnd[t]&&!e[t]&&(e[t]=(e,n,r,s)=>{e.style[t]=W(n,r,s)})}const J={};["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"].forEach((t=>{J[t]=G}));const tt=["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],et={};tt.forEach((t=>{et[t]="#000"}));const nt={};tt.forEach((t=>{nt[t]=G}));const rt={component:"colorProperties",category:"colors",properties:tt,defaultValues:et,Interpolate:{numbers:X,colors:W},functions:{prepareStart:function(t){return I(this.element,t)||g[t]},prepareProperty:function(t,e){return K(e)},onStart:nt},Util:{trueColor:K}},st={},it=["fill","stroke","stop-color"];function at(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}const ot={prepareStart:function(t,e){const n={};return Object.keys(e).forEach((t=>{const e=at(t).replace(/_+[a-z]+/,""),r=this.element.getAttribute(e);n[e]=it.includes(e)?r||"rgba(0,0,0,0)":r||(/opacity/i.test(t)?1:0)})),n},prepareProperty:function(t,e){const n={};return Object.keys(e).forEach((r=>{const s=at(r),i=/(%|[a-z]+)$/,o=this.element.getAttribute(s.replace(/_+[a-z]+/,""));if(it.includes(s))a.htmlAttributes[s]=e=>{this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in st)&&(st[e]=(t,e,n,r,s)=>{t.setAttribute(e,W(n,r,s))})},n[s]=K(e[r])||g.htmlAttributes[r];else if(null!==o&&i.test(o)){const i=D(o).u||D(e[r]).u,l=/%/.test(i)?"_percent":`_${i}`;a.htmlAttributes[s+l]=e=>{this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in st)&&(st[e]=(t,e,n,r,s)=>{const i=e.replace(l,"");t.setAttribute(i,(1e3*X(n.v,r.v,s)>>0)/1e3+r.u)})},n[s+l]=D(e[r])}else i.test(e[r])&&null!==o&&(null===o||i.test(o))||(a.htmlAttributes[s]=e=>{this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in st)&&(st[e]=(t,e,n,r,s)=>{t.setAttribute(e,(1e3*X(n,r,s)>>0)/1e3)})},n[s]=parseFloat(e[r]))})),n},onStart:{attr(t){!e[t]&&this.valuesEnd[t]&&(e[t]=(t,n,r,s)=>{Object.keys(r).forEach((i=>{e.attributes[i](t,i,n[i],r[i],s)}))})},attributes(t){!e[t]&&this.valuesEnd.attr&&(e[t]=st)}}},lt={component:"htmlAttributes",property:"attr",subProperties:["fill","stroke","stop-color","fill-opacity","stroke-opacity"],defaultValue:{fill:"rgb(0,0,0)",stroke:"rgb(0,0,0)","stop-color":"rgb(0,0,0)",opacity:1,"stroke-opacity":1,"fill-opacity":1},Interpolate:{numbers:X,colors:W},functions:ot,Util:{replaceUppercase:at,trueColor:K,trueDimension:D}};const ct={prepareStart:function(t){return I(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=(e,n,r,s)=>{e.style[t]=(1e3*X(n,r,s)>>0)/1e3})}},ut={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:X},functions:ct},ht=String("abcdefghijklmnopqrstuvwxyz").split(""),pt=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),ft=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),dt=String("0123456789").split(""),gt=ht.concat(pt,dt),yt=gt.concat(ft),mt={alpha:ht,upper:pt,symbols:ft,numeric:dt,alphanumeric:gt,all:yt},bt={text(t){if(!e[t]&&this.valuesEnd[t]){const n=this._textChars;let r=mt[y.textChars];n in mt?r=mt[n]:n&&n.length&&(r=n),e[t]=(t,e,n,s)=>{let i="",a="";const o=""===n?" ":n,l=e.substring(0),c=n.substring(0),u=r[Math.random()*r.length>>0];" "===e?(a=c.substring(Math.min(s*c.length,c.length)>>0,0),t.innerHTML=s<1?a+u:o):" "===n?(i=l.substring(0,Math.min((1-s)*l.length,l.length)>>0),t.innerHTML=s<1?i+u:o):(i=l.substring(l.length,Math.min(s*l.length,l.length)>>0),a=c.substring(0,Math.min(s*c.length,c.length)>>0),t.innerHTML=s<1?a+u+i:o)}}},number(t){t in this.valuesEnd&&!e[t]&&(e[t]=(t,e,n,r)=>{t.innerHTML=X(e,n,r)>>0})}};function vt(t,e){let n,r;if("string"==typeof t)return r=document.createElement("SPAN"),r.innerHTML=t,r.className=e,r;if(!t.children.length||t.children.length&&t.children[0].className!==e){const r=t.innerHTML;n=document.createElement("SPAN"),n.className=e,n.innerHTML=r,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&([n]=t.children);return n}function xt(t,e){let n=[];const r=t.children.length;if(r){const s=[];let i,a=t.innerHTML;for(let n,o,l,c=0;c>0)/1e3}${n})`}function wt(t,e,n,r){const s=[];for(let i=0;i<3;i+=1)s[i]=(t[i]||e[i]?(1e3*(t[i]+(e[i]-t[i])*r)>>0)/1e3:0)+n;return`translate3d(${s.join(",")})`}function kt(t,e,n,r){let s="";return s+=t[0]||e[0]?`rotateX(${(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3}${n})`:"",s+=t[1]||e[1]?`rotateY(${(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3}${n})`:"",s+=t[2]||e[2]?`rotateZ(${(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3}${n})`:"",s}function _t(t,e,n){return`scale(${(1e3*(t+(e-t)*n)>>0)/1e3})`}function Ct(t,e,n,r){const s=[];return s[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,s[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0",`skew(${s.join(",")})`}function Ot(t,e){return parseFloat(t)/100*e}function Mt(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Tt(t){const e=t.getAttribute("points").split(" ");let n=0;if(e.length>1){const r=t=>{const e=t.split(",");return 2!==e.length||Number.isNaN(1*e[0])||Number.isNaN(1*e[1])?0:[parseFloat(e[0]),parseFloat(e[1])]},s=(t,e)=>void 0!==t&&void 0!==e?Math.sqrt((e[0]-t[0])**2+(e[1]-t[1])**2):0;if(e.length>2)for(let t=0;t["s","e","l"].includes(t))))return e;if("string"==typeof e){const t=e.split(/,|\s/);r=/%/.test(t[0])?Ot(t[0].trim(),n):parseFloat(t[0]),s=/%/.test(t[1])?Ot(t[1].trim(),n):parseFloat(t[1])}else void 0===e&&(a=parseFloat(I(t,"stroke-dashoffset")),i=I(t,"stroke-dasharray").split(","),r=0-a,s=parseFloat(i[0])+r||n);return{s:r,e:s,l:n}}const $t={prepareStart:function(){return Pt(this.element)},prepareProperty:function(t,e){return Pt(this.element,e)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=(t,e,n,r)=>{const s=(100*e.l>>0)/100,i=0-(100*X(e.s,n.s,r)>>0)/100,a=(100*X(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=`${i}px`,t.style.strokeDasharray=`${(100*(a<1?0:a)>>0)/100}px, ${s}px`})}};function Lt(t,e,n){if(t[n].length>7){t[n].shift();const r=t[n];let s=n;for(;r.length;)e[n]="A",t.splice(s+=1,0,["C",...r.splice(0,6)]);t.splice(n,1)}}const Nt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function qt(t){let e=t.pathValue[t.segmentStart],n=e.toLowerCase(),{data:r}=t;for("m"===n&&r.length>2&&(t.segments.push([e,r[0],r[1]]),r=r.slice(2),n="l",e="m"===e?"l":"L");r.length>=Nt[n]&&(t.segments.push([e,...r.splice(0,Nt[n])]),Nt[n]););}function Vt(t){const{index:e}=t,n=t.pathValue.charCodeAt(e);return 48===n?(t.param=0,void(t.index+=1)):49===n?(t.param=1,void(t.index+=1)):void(t.err=`Invalid path value: invalid Arc flag "${n}", expecting 0 or 1 at index ${e}`)}function Ht(t){return t>=48&&t<=57}function Qt(t){const{max:e,pathValue:n,index:r}=t;let s,i=r,a=!1,o=!1,l=!1,c=!1;if(i>=e)t.err=`Invalid path value at ${i}: missing param ${n[i]}`;else if(s=n.charCodeAt(i),43!==s&&45!==s||(i+=1,s=i=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(r)>=0);)t.index+=1;var r}function Ut(t){return t>=48&&t<=57||43===t||45===t||46===t}function Dt(t){const{max:e,pathValue:n,index:r}=t,s=n.charCodeAt(r),i=Nt[n[r].toLowerCase()];if(t.segmentStart=r,function(t){switch(32|t){case 109:case 122:case 108:case 104:case 118:case 99:case 115:case 113:case 116:case 97:return!0;default:return!1}}(s))if(t.index+=1,Ft(t),t.data=[],i){for(;;){for(let r=i;r>0;r-=1){if(97!=(32|s)||3!==r&&4!==r?Qt(t):Vt(t),t.err.length)return;t.data.push(t.param),Ft(t),t.index=t.max)break;if(!Ut(n.charCodeAt(t.index)))break}qt(t)}else qt(t);else t.err=`Invalid path value: ${n[r]} not a path command`}function Xt(t){return t.map((t=>Array.isArray(t)?[...t]:t))}function Zt(t){this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""}function Bt(t){return Array.isArray(t)&&t.every((t=>{const e=t[0].toLowerCase();return Nt[e]===t.length-1&&"achlmqstvz".includes(e)}))}function Rt(t){if(Bt(t))return Xt(t);const e=new Zt(t);for(Ft(e);e.indext[0]===t[0].toUpperCase()))}function zt(t){if(Yt(t))return Xt(t);const e=Rt(t);let n=0,r=0,s=0,i=0;return e.map((t=>{const e=t.slice(1).map(Number),[a]=t,o=a.toUpperCase();if("M"===a)return[n,r]=e,s=n,i=r,["M",n,r];let l=[];if(a!==o)switch(o){case"A":l=[o,e[0],e[1],e[2],e[3],e[4],e[5]+n,e[6]+r];break;case"V":l=[o,e[0]+r];break;case"H":l=[o,e[0]+n];break;default:l=[o,...e.map(((t,e)=>t+(e%2?r:n)))]}else l=[o,...e];const c=l.length;switch(o){case"Z":n=s,r=i;break;case"H":[,n]=l;break;case"V":[,r]=l;break;default:n=l[c-2],r=l[c-1],"M"===o&&(s=n,i=r)}return l}))}function Kt(t,e,n){const[r]=t,{x1:s,y1:i,x2:a,y2:o}=e,l=t.slice(1).map(Number);let c=t;if("TQ".includes(r)||(e.qx=null,e.qy=null),"H"===r)c=["L",t[1],i];else if("V"===r)c=["L",s,t[1]];else if("S"===r){const{x1:t,y1:r}=function(t,e,n,r,s){return"CS".includes(s)?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(s,i,a,o,n);e.x1=t,e.y1=r,c=["C",t,r,...l]}else if("T"===r){const{qx:t,qy:r}=function(t,e,n,r,s){return"QT".includes(s)?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(s,i,e.qx,e.qy,n);e.qx=t,e.qy=r,c=["Q",t,r,...l]}else if("Q"===r){const[t,n]=l;e.qx=t,e.qy=n}return c}const Wt={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null};function Gt(t){if(function(t){return Yt(t)&&t.every((t=>"ACLMQZ".includes(t[0])))}(t))return Xt(t);const e=zt(t),n={...Wt},r=[],s=e.length;let i="",a="";for(let t=0;t1&&(n=Math.sqrt(n),p*=n,f*=n);const r=p*p,s=f*f,o=(i===a?-1:1)*Math.sqrt(Math.abs((r*s-r*e*e-s*t*t)/(r*e*e+s*t*t)));E=o*p*e/f+(u+d)/2,w=o*-f*t/p+(h+g)/2,v=(Math.asin((h-w)/f)*10**9>>0)/10**9,x=(Math.asin((g-w)/f)*10**9>>0)/10**9,v=ux&&(v-=2*Math.PI),!a&&x>v&&(x-=2*Math.PI)}let _=x-v;if(Math.abs(_)>y){const t=x,e=d,n=g;x=v+y*(a&&x>v?1:-1),d=E+p*Math.cos(x),g=w+f*Math.sin(x),k=ee(d,g,p,f,s,0,a,e,n,[x,t,E,w])}_=x-v;const C=Math.cos(v),O=Math.sin(v),M=Math.cos(x),T=Math.sin(x),I=Math.tan(_/4),S=4/3*p*I,A=4/3*f*I,j=[u,h],P=[u+S*O,h-A*C],$=[d+S*T,g-A*M],L=[d,g];if(P[0]=2*j[0]-P[0],P[1]=2*j[1]-P[1],c)return[...P,...$,...L,...k];k=[...P,...$,...L,...k];const N=[];for(let t=0,e=k.length;ti+.001)return{x:n,y:r};const[a,o]=re([t,e],[n,r],s/i);return{x:a,y:o}}return i}function ae(t,e,n,r){const s=.5,i=[t,e],a=[n,r],o=re(i,a,s),l=re(a,o,s),c=re(o,l,s),u=re(l,c,s),h=re(c,u,s),p=ie(...[...i,...o,...c,...h,s]),f=ie(...[...h,...u,...l,...a,0]);return[p.x,p.y,f.x,f.y,n,r]}function oe(t,e){const[n]=t,r=t.slice(1).map((t=>+t)),[s,i]=r;let a;const{x1:o,y1:l,x:c,y:u}=e;switch("TQ".includes(n)||(e.qx=null,e.qy=null),n){case"M":return e.x=s,e.y=i,t;case"A":return a=[o,l,...r],["C",...ee(...a)];case"Q":return e.qx=s,e.qy=i,a=[o,l,...r],["C",...ne(...a)];case"L":return["C",...ae(o,l,s,i)];case"Z":return["C",...ae(o,l,c,u)]}return t}const le={origin:[0,0,0],round:4};function ce(t,e){let{round:n}=le;if(!1===e||!1===n)return Xt(t);n=e>=1?e:n;const r=n>=1?10**n:1;return t.map((t=>{const e=t.slice(1).map(Number).map((t=>t%1==0?t:Math.round(t*r)/r));return[t[0],...e]}))}function ue(t,e){return ce(t,e).map((t=>t[0]+t.slice(1).join(" "))).join("")}function he(t,e,n,r,s,i,a,o,l){const c=1-l;return{x:c**3*t+3*c**2*l*n+3*c*l**2*s+l**3*a,y:c**3*e+3*c**2*l*r+3*c*l**2*i+l**3*o}}function pe(t,e,n,r,s,i,a,o,l){let c=t,u=e;let h=0,p=[t,e,h],f=[t,e],d=0;if("number"==typeof l&&l<.001)return{x:c,y:u};for(let g=0;g<=100;g+=1){if(d=g/100,({x:c,y:u}=he(t,e,n,r,s,i,a,o,d)),h+=se(f,[c,u]),f=[c,u],"number"==typeof l&&h>=l){const t=(h-l)/(h-p[2]);return{x:f[0]*(1-t)+p[0]*t,y:f[1]*(1-t)+p[1]*t}}p=[c,u,h]}return"number"==typeof l&&l>=h?{x:a,y:o}:h}function fe(t,e,n,r,s,i,a,o,l,c){let[u,h]=[t,e];const p=ee(t,e,n,r,s,i,a,o,l);let f=0,d=[],g=[],y=0;if("number"==typeof c&&c<.001)return{x:u,y:h};for(let t=0,e=p.length;t=c)return pe(...g,c-f);f+=y,[u,h]=d.slice(-2)}return"number"==typeof c&&c>=f?{x:o,y:l}:f}function de(t,e,n,r,s,i,a){const o=1-a;return{x:o**2*t+2*o*a*n+a**2*s,y:o**2*e+2*o*a*r+a**2*i}}function ge(t,e,n,r,s,i,a){let o=t,l=e;let c=0,u=[t,e,c],h=[t,e],p=0;if("number"==typeof a&&a<.001)return{x:o,y:l};for(let f=0;f<=100;f+=1){if(p=f/100,({x:o,y:l}=de(t,e,n,r,s,i,p)),c+=se(h,[o,l]),h=[o,l],"number"==typeof a&&c>=a){const t=(c-a)/(c-u[2]);return{x:h[0]*(1-t)+u[0]*t,y:h[1]*(1-t)+u[1]*t}}u=[o,l,c]}return"number"==typeof a&&a>=c?{x:s,y:i}:c}function ye(t,e){let n,r=0,s=!0,i=[],a="M",o=0,l=0,c=0,u=0,h=0;const p=Jt(Gt(t));for(let t=0,f=p.length;t=e)return ie(...i,e-r);r+=o}else if("A"===a){if(o=fe(...i),e&&r+o>=e)return fe(...i,e-r);r+=o}else if("C"===a){if(o=pe(...i),e&&r+o>=e)return pe(...i,e-r);r+=o}else if("Q"===a){if(o=ge(...i),e&&r+o>=e)return ge(...i,e-r);r+=o}else if("Z"===a){if(i=[l,c,u,h],o=ie(...i),e&&r+o>=e)return ie(...i,e-r);r+=o}[l,c]="Z"!==a?n.slice(-2):[u,h]}return e&&e>=r?{x:l,y:c}:r}function me(t){return ye(t)}function be(t,e){return ye(t,e)}function ve(t){const e=t.length;let n,r=-1,s=t[e-1],i=0;for(;++r>0)/1e3)}return s}function Ee(t,e){var n;const r=Gt((n=ue(t),ue(zt(n),0).replace(/(m|M)/g,"|$1").split("|").map((t=>t.trim())).filter((t=>t)))[0]),s=me(r),i=[];let a,o=3;e&&!Number.isNaN(e)&&+e>0&&(o=Math.max(o,Math.ceil(s/e)));for(let t=0;t0&&i.reverse(),{polygon:i,skipBisect:!0}}function we(t,e){const n=Gt(t);return function(t){const e=[],n=t.length;let r=[],s="";if(!t.length||"M"!==t[0][0])return!1;for(let i=0;ir?e+se(t[r-1],n):0),0)}(t)/e;let s,i,a,o=0,l=0,c=r/2;for(;t.lengthe;)r=re(n,r,.5),t.splice(s+1,0,r)}function Oe(t){return Array.isArray(t)&&t.every((t=>Array.isArray(t)&&2===t.length&&!Number.isNaN(t[0])&&!Number.isNaN(t[1])))}function Me(t,e){let n,r;if("string"==typeof t){const s=we(t,e);({polygon:r,skipBisect:n}=s)}else if(!Array.isArray(t))throw Error(`Invalid path value: ${t}`);const s=[...r];if(!Oe(s))throw Error(`Invalid path value: ${s}`);return s.length>1&&se(s[0],s[s.length-1])<1e-9&&s.pop(),!n&&e&&!Number.isNaN(e)&&+e>0&&Ce(s,e),s}function Te(t,e,n){const r=n||y.morphPrecision,s=Me(t,r),i=Me(e,r),a=s.length-i.length;return _e(s,a<0?-1*a:0),_e(i,a>0?a:0),ke(s,i),[ce(s),ce(i)]}const Ie={prepareStart:function(){return this.element.getAttribute("d")},prepareProperty:function(t,e){const n={},r=new RegExp("\\n","ig");let s=null;return e instanceof SVGPathElement?s=e:/^\.|^#/.test(e)&&(s=L(e)),"object"==typeof e&&e.polygon?e:(s&&["path","glyph"].includes(s.tagName)?n.original=s.getAttribute("d").replace(r,""):s||"string"!=typeof e||(n.original=e.replace(r,"")),n)},onStart:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=(t,e,n,r)=>{const s=e.polygon,i=n.polygon,a=i.length;t.setAttribute("d",1===r?n.original:`M${xe(s,i,a,r).join("L")}Z`)})},crossCheck:function(t){if(this.valuesEnd[t]){const e=this.valuesStart[t].polygon,n=this.valuesEnd[t].polygon;if(!e||!n||e&&n&&e.length!==n.length){const e=this.valuesStart[t].original,n=this.valuesEnd[t].original,r=this._morphPrecision?parseInt(this._morphPrecision,10):y.morphPrecision,[s,i]=Te(e,n,r);this.valuesStart[t].polygon=s,this.valuesEnd[t].polygon=i}}}},Se={EssentialBoxModel:z,ColorsProperties:rt,HTMLAttributes:lt,OpacityProperty:ut,TextWriteProp:{component:"textWriteProperties",category:"textWrite",properties:["text","number"],defaultValues:{text:" ",number:"0"},defaultOptions:{textChars:"alpha"},Interpolate:{numbers:X},functions:{prepareStart:function(){return this.element.innerHTML},prepareProperty:function(t,e){return"number"===t?parseFloat(e):""===e?" ":e},onStart:bt},Util:{charSet:mt,createTextTweens:function(t,e,n){if(t.playing)return!1;const r=n||{};r.duration=1e3,"auto"===n.duration?r.duration="auto":Number.isFinite(1*n.duration)&&(r.duration=1*n.duration);const s=P.tween,i=function(t,e){const n=xt(t,"text-part"),r=xt(vt(e),"text-part");return t.innerHTML="",t.innerHTML+=n.map((t=>(t.className+=" oldText",t.outerHTML))).join(""),t.innerHTML+=r.map((t=>(t.className+=" newText",t.outerHTML.replace(t.innerHTML,"")))).join(""),[n,r]}(t,e),a=i[0],o=i[1],l=[].slice.call(t.getElementsByClassName("oldText")).reverse(),c=[].slice.call(t.getElementsByClassName("newText"));let u=[],h=0;return u=u.concat(l.map(((t,e)=>(r.duration="auto"===r.duration?75*a[e].innerHTML.length:r.duration,r.delay=h,r.onComplete=null,h+=r.duration,new s(t,{text:t.innerHTML},{text:""},r))))),u=u.concat(c.map(((n,i)=>(r.duration="auto"===r.duration?75*o[i].innerHTML.length:r.duration,r.delay=h,r.onComplete=i===o.length-1?function(){t.innerHTML=e,t.playing=!1}:null,h+=r.duration,new s(n,{text:""},{text:o[i].innerHTML},r))))),u.start=function(){t.playing||(u.forEach((t=>t.start())),t.playing=!0)},u}}},TransformFunctions:{component:"transformFunctions",property:"transform",subProperties:["perspective","translate3d","translateX","translateY","translateZ","translate","rotate3d","rotateX","rotateY","rotateZ","rotate","skewX","skewY","skew","scale"],defaultValues:{perspective:400,translate3d:[0,0,0],translateX:0,translateY:0,translateZ:0,translate:[0,0],rotate3d:[0,0,0],rotateX:0,rotateY:0,rotateZ:0,rotate:0,skewX:0,skewY:0,skew:[0,0],scale:1},functions:{prepareStart:function(t){const e=T(this.element);return e[t]?e[t]:g[t]},prepareProperty:function(t,e){const n=["X","Y","Z"],r={},s=[],i=[],a=[],o=["translate3d","translate","rotate3d","skew"];return Object.keys(e).forEach((t=>{const l="object"==typeof e[t]&&e[t].length?e[t].map((t=>parseInt(t,10))):parseInt(e[t],10);if(o.includes(t)){const e="translate"===t||"rotate"===t?`${t}3d`:t;r[e]="skew"===t?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===t?l.length?[l[0]||0,l[1]||0,l[2]||0]:[l||0,0,0]:[l[0]||0,l[1]||0,l[2]||0]}else if(/[XYZ]/.test(t)){const o=t.replace(/[XYZ]/,""),l="skew"===o?o:`${o}3d`,c="skew"===o?2:3;let u=[];"translate"===o?u=s:"rotate"===o?u=i:"skew"===o&&(u=a);for(let t=0;t{e.style[t]=(n.perspective||r.perspective?Et(n.perspective,r.perspective,"px",s):"")+(n.translate3d?wt(n.translate3d,r.translate3d,"px",s):"")+(n.rotate3d?kt(n.rotate3d,r.rotate3d,"deg",s):"")+(n.skew?Ct(n.skew,r.skew,"deg",s):"")+(n.scale||r.scale?_t(n.scale,r.scale,s):"")})},crossCheck:function(t){this.valuesEnd[t]&&this.valuesEnd[t]&&this.valuesEnd[t].perspective&&!this.valuesStart[t].perspective&&(this.valuesStart[t].perspective=this.valuesEnd[t].perspective)}},Interpolate:{perspective:Et,translate3d:wt,rotate3d:kt,translate:function(t,e,n,r){const s=[];return s[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,s[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0",`translate(${s.join(",")})`},rotate:function(t,e,n,r){return`rotate(${(1e3*(t+(e-t)*r)>>0)/1e3}${n})`},scale:_t,skew:Ct}},SVGDraw:{component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:X},functions:$t,Util:{getRectLength:Mt,getPolyLength:Tt,getLineLength:It,getCircleLength:St,getEllipseLength:At,getTotalLength:jt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Pt,percent:Ot}},SVGMorph:{component:"svgMorph",property:"path",defaultValue:[],Interpolate:xe,defaultOptions:{morphPrecision:10},functions:Ie,Util:{addPoints:_e,bisect:Ce,getPolygon:Me,validPolygon:Oe,getInterpolationPoints:Te,pathStringToPolygon:we,distanceSquareRoot:se,midPoint:re,approximatePolygon:Ee,rotatePolygon:ke,pathToString:ue,pathToCurve:function(t){if(function(t){return Bt(t)&&t.every((t=>"MC".includes(t[0])))}(t))return Xt(t);const e=Jt(Gt(t)),n={...Wt},r=[];let s="",i=e.length;for(let t=0;t{const e=Se[t];Se[t]=new U(e)}));const Ae={Animation:U,Components:Se,Tween:V,fromTo:function(t,e,n,r){const s=r||{};return new F(L(t),e,n,s)},to:function(t,e,n){const r=n||{};return r.resetStart=e,new Q(L(t),e,e,r)},TweenCollection:H,allFromTo:function(t,e,n,r){const s=r||{};return new H(L(t,!0),e,n,s)},allTo:function(t,e,n){const r=n||{};return r.resetStart=e,new H(L(t,!0),e,e,r)},Objects:w,Util:k,Easing:$,CubicBezier:t,Render:f,Interpolate:i,Process:j,Internals:M,Selector:L,Version:"2.2.3"};export{Ae as default}; diff --git a/dist/kute.js b/dist/kute.js deleted file mode 100644 index c750121..0000000 --- a/dist/kute.js +++ /dev/null @@ -1,4675 +0,0 @@ -/*! -* KUTE.js Standard v2.2.3 (http://thednp.github.io/kute.js) -* Copyright 2015-2021 © thednp -* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) -*/ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); -})(this, (function () { 'use strict'; - - /** - * Creates cubic-bezier easing functions. - * - * @class - */ - var CubicBezier = function CubicBezier(p1x, p1y, p2x, p2y, functionName) { - var this$1$1 = this; - - // pre-calculate the polynomial coefficients - // First and last control points are implied to be (0,0) and (1.0, 1.0) - - /** @type {number} */ - this.cx = 3.0 * p1x; - - /** @type {number} */ - this.bx = 3.0 * (p2x - p1x) - this.cx; - - /** @type {number} */ - this.ax = 1.0 - this.cx - this.bx; - - /** @type {number} */ - this.cy = 3.0 * p1y; - - /** @type {number} */ - this.by = 3.0 * (p2y - p1y) - this.cy; - - /** @type {number} */ - this.ay = 1.0 - this.cy - this.by; - - /** @type {(t: number) => number} */ - var BezierEasing = function (t) { return this$1$1.sampleCurveY(this$1$1.solveCurveX(t)); }; - - // this function needs a name - Object.defineProperty(BezierEasing, 'name', { writable: true }); - BezierEasing.name = functionName || ("cubic-bezier(" + ([p1x, p1y, p2x, p2y]) + ")"); - - return BezierEasing; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled X value - */ - CubicBezier.prototype.sampleCurveX = function sampleCurveX (t) { - return ((this.ax * t + this.bx) * t + this.cx) * t; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled Y value - */ - CubicBezier.prototype.sampleCurveY = function sampleCurveY (t) { - return ((this.ay * t + this.by) * t + this.cy) * t; - }; - - /** - * @param {number} t - progress [0-1] - * @return {number} - sampled curve derivative X value - */ - CubicBezier.prototype.sampleCurveDerivativeX = function sampleCurveDerivativeX (t) { - return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx; - }; - - /** - * @param {number} x - progress [0-1] - * @return {number} - solved curve X value - */ - CubicBezier.prototype.solveCurveX = function solveCurveX (x) { - var t0; - var t1; - var t2; - var x2; - var d2; - var i; - var epsilon = 1e-5; // Precision - - // First try a few iterations of Newton's method -- normally very fast. - for (t2 = x, i = 0; i < 32; i += 1) { - x2 = this.sampleCurveX(t2) - x; - if (Math.abs(x2) < epsilon) { return t2; } - d2 = this.sampleCurveDerivativeX(t2); - if (Math.abs(d2) < epsilon) { break; } - t2 -= x2 / d2; - } - - // No solution found - use bi-section - t0 = 0.0; - t1 = 1.0; - t2 = x; - - if (t2 < t0) { return t0; } - if (t2 > t1) { return t1; } - - while (t0 < t1) { - x2 = this.sampleCurveX(t2); - if (Math.abs(x2 - x) < epsilon) { return t2; } - if (x > x2) { t0 = t2; } - else { t1 = t2; } - - t2 = (t1 - t0) * 0.5 + t0; - } - - // Give up - return t2; - }; - - var version$1 = "1.0.18"; - - // @ts-ignore - - /** - * A global namespace for library version. - * @type {string} - */ - var Version$1 = version$1; - - Object.assign(CubicBezier, { Version: Version$1 }); - - /** - * The KUTE.js Execution Context - */ - var KEC = {}; - - var Tweens = []; - - var gl0bal; - - if (typeof global !== 'undefined') { gl0bal = global; } - else if (typeof window !== 'undefined') { gl0bal = window.self; } - else { gl0bal = {}; } - - var globalObject = gl0bal; - - // KUTE.js INTERPOLATE FUNCTIONS - // ============================= - var interpolate = {}; - - // schedule property specific function on animation start - // link property update function to KUTE.js execution context - var onStart = {}; - - // Include a performance.now polyfill. - // source https://github.com/tweenjs/tween.js/blob/master/src/Now.ts - var performanceNow; - - // In node.js, use process.hrtime. - // eslint-disable-next-line - // @ts-ignore - if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { - performanceNow = function () { - // eslint-disable-next-line - // @ts-ignore - var time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; - } else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { - // In a browser, use self.performance.now if it is available. - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - performanceNow = self.performance.now.bind(self.performance); - } else if (typeof Date !== 'undefined' && Date.now) { - // Use Date.now if it is available. - performanceNow = Date.now; - } else { - // Otherwise, use 'new Date().getTime()'. - performanceNow = function () { return new Date().getTime(); }; - } - - var now = performanceNow; - - var Time = {}; - Time.now = now; - - // eslint-disable-next-line import/no-mutable-exports -- impossible to satisfy - var Tick = 0; - - /** - * - * @param {number | Date} time - */ - var Ticker = function (time) { - var i = 0; - while (i < Tweens.length) { - if (Tweens[i].update(time)) { - i += 1; - } else { - Tweens.splice(i, 1); - } - } - Tick = requestAnimationFrame(Ticker); - }; - - // stop requesting animation frame - function stop() { - setTimeout(function () { // re-added for #81 - if (!Tweens.length && Tick) { - cancelAnimationFrame(Tick); - Tick = null; - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - if (KEC[obj]) { delete KEC[obj]; } - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - if (KEC[prop]) { delete KEC[prop]; } - }); - } - }); - - Object.keys(interpolate).forEach(function (i) { - if (KEC[i]) { delete KEC[i]; } - }); - } - }, 64); - } - - // render update functions - // ======================= - var Render = { - Tick: Tick, Ticker: Ticker, Tweens: Tweens, Time: Time, - }; - Object.keys(Render).forEach(function (blob) { - if (!KEC[blob]) { - KEC[blob] = blob === 'Time' ? Time.now : Render[blob]; - } - }); - - globalObject._KUTE = KEC; - - // all supported properties - var supportedProperties = {}; - - var defaultValues = {}; - - var defaultOptions$1 = { - duration: 700, - delay: 0, - easing: 'linear', - repeat: 0, - repeatDelay: 0, - yoyo: false, - resetStart: false, - offset: 0, - }; - - // used in preparePropertiesObject - var prepareProperty = {}; - - // check current property value when .to() method is used - var prepareStart = {}; - - // checks for differences between the processed start and end values, - // can be set to make sure start unit and end unit are same, - // stack transforms, process SVG paths, - // any type of post processing the component needs - var crossCheck = {}; - - // schedule property specific function on animation complete - var onComplete = {}; - - // link properties to interpolate functions - var linkProperty = {}; - - var Objects = { - supportedProperties: supportedProperties, - defaultValues: defaultValues, - defaultOptions: defaultOptions$1, - prepareProperty: prepareProperty, - prepareStart: prepareStart, - crossCheck: crossCheck, - onStart: onStart, - onComplete: onComplete, - linkProperty: linkProperty, - }; - - // util - a general object for utils like rgbToHex, processEasing - var Util = {}; - - /** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var add = function (tw) { return Tweens.push(tw); }; - - /** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - var remove = function (tw) { - var i = Tweens.indexOf(tw); - if (i !== -1) { Tweens.splice(i, 1); } - }; - - /** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ - var getAll = function () { return Tweens; }; - - /** - * KUTE.removeAll() - */ - var removeAll = function () { Tweens.length = 0; }; - - /** - * linkInterpolation - * @this {KUTE.Tween} - */ - function linkInterpolation() { - var this$1$1 = this; - // DON'T change - Object.keys(linkProperty).forEach(function (component) { - var componentLink = linkProperty[component]; - var componentProps = supportedProperties[component]; - - Object.keys(componentLink).forEach(function (fnObj) { - if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius - && Object.keys(this$1$1.valuesEnd).some(function (i) { return (componentProps && componentProps.includes(i)) - || (i === 'attr' && Object.keys(this$1$1.valuesEnd[i]).some(function (j) { return componentProps && componentProps.includes(j); })); })) { - if (!KEC[fnObj]) { KEC[fnObj] = componentLink[fnObj]; } - } else { - Object.keys(this$1$1.valuesEnd).forEach(function (prop) { - var propObject = this$1$1.valuesEnd[prop]; - if (propObject instanceof Object) { - Object.keys(propObject).forEach(function (i) { - if (typeof (componentLink[i]) === 'function') { // transformCSS3 - if (!KEC[i]) { KEC[i] = componentLink[i]; } - } else { - Object.keys(componentLink[fnObj]).forEach(function (j) { - if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix - if (!KEC[j]) { KEC[j] = componentLink[i][j]; } - } - }); - } - }); - } - }); - } - }); - }); - } - - var internals = { - add: add, - remove: remove, - getAll: getAll, - removeAll: removeAll, - stop: stop, - linkInterpolation: linkInterpolation, - }; - - /** - * getInlineStyle - * Returns the transform style for element from - * cssText. Used by for the `.to()` static method. - * - * @param {Element} el target element - * @returns {object} - */ - function getInlineStyle(el) { - // if the scroll applies to `window` it returns as it has no styling - if (!el.style) { return false; } - // the cssText | the resulting transform object - var css = el.style.cssText.replace(/\s/g, '').split(';'); - var transformObject = {}; - var arrayFn = ['translate3d', 'translate', 'scale3d', 'skew']; - - css.forEach(function (cs) { - if (/transform/i.test(cs)) { - // all transform properties - var tps = cs.split(':')[1].split(')'); - tps.forEach(function (tpi) { - var tpv = tpi.split('('); - var tp = tpv[0]; - // each transform property - var tv = tpv[1]; - if (!/matrix/.test(tp)) { - transformObject[tp] = arrayFn.includes(tp) ? tv.split(',') : tv; - } - }); - } - }); - - return transformObject; - } - - /** - * getStyleForProperty - * - * Returns the computed style property for element for .to() method. - * Used by for the `.to()` static method. - * - * @param {Element} elem - * @param {string} propertyName - * @returns {string} - */ - function getStyleForProperty(elem, propertyName) { - var result = defaultValues[propertyName]; - var styleAttribute = elem.style; - var computedStyle = getComputedStyle(elem) || elem.currentStyle; - var styleValue = styleAttribute[propertyName] && !/auto|initial|none|unset/.test(styleAttribute[propertyName]) - ? styleAttribute[propertyName] - : computedStyle[propertyName]; - - if (propertyName !== 'transform' && (propertyName in computedStyle || propertyName in styleAttribute)) { - result = styleValue; - } - - return result; - } - - /** - * prepareObject - * - * Returns all processed valuesStart / valuesEnd. - * - * @param {Element} obj the values start/end object - * @param {string} fn toggles between the two - */ - function prepareObject(obj, fn) { - var this$1$1 = this; - // this, props object, type: start/end - var propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd; - - Object.keys(prepareProperty).forEach(function (component) { - var prepareComponent = prepareProperty[component]; - var supportComponent = supportedProperties[component]; - - Object.keys(prepareComponent).forEach(function (tweenCategory) { - var transformObject = {}; - - Object.keys(obj).forEach(function (tweenProp) { - // scroll, opacity, other components - if (defaultValues[tweenProp] && prepareComponent[tweenProp]) { - propertiesObject[tweenProp] = prepareComponent[tweenProp] - .call(this$1$1, tweenProp, obj[tweenProp]); - - // transform - } else if (!defaultValues[tweenCategory] && tweenCategory === 'transform' - && supportComponent.includes(tweenProp)) { - transformObject[tweenProp] = obj[tweenProp]; - - // allow transformFunctions to work with preprocessed input values - } else if (!defaultValues[tweenProp] && tweenProp === 'transform') { - propertiesObject[tweenProp] = obj[tweenProp]; - - // colors, boxModel, category - } else if (!defaultValues[tweenCategory] - && supportComponent && supportComponent.includes(tweenProp)) { - propertiesObject[tweenProp] = prepareComponent[tweenCategory] - .call(this$1$1, tweenProp, obj[tweenProp]); - } - }); - - // we filter out older browsers by checking Object.keys - if (Object.keys(transformObject).length) { - propertiesObject[tweenCategory] = prepareComponent[tweenCategory] - .call(this$1$1, tweenCategory, transformObject); - } - }); - }); - } - - /** - * getStartValues - * - * Returns the start values for to() method. - * Used by for the `.to()` static method. - * - * @this {KUTE.Tween} the tween instance - */ - function getStartValues() { - var this$1$1 = this; - - var startValues = {}; - var currentStyle = getInlineStyle(this.element); - - Object.keys(this.valuesStart).forEach(function (tweenProp) { - Object.keys(prepareStart).forEach(function (component) { - var componentStart = prepareStart[component]; - - Object.keys(componentStart).forEach(function (tweenCategory) { - // clip, opacity, scroll - if (tweenCategory === tweenProp && componentStart[tweenProp]) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this$1$1, tweenProp, this$1$1.valuesStart[tweenProp]); - // find in an array of properties - } else if (supportedProperties[component] - && supportedProperties[component].includes(tweenProp)) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this$1$1, tweenProp, this$1$1.valuesStart[tweenProp]); - } - }); - }); - }); - - // stack transformCSS props for .to() chains - // also add to startValues values from previous tweens - Object.keys(currentStyle).forEach(function (current) { - if (!(current in this$1$1.valuesStart)) { - startValues[current] = currentStyle[current] || defaultValues[current]; - } - }); - - this.valuesStart = {}; - prepareObject.call(this, startValues, 'start'); - } - - var Process = { - getInlineStyle: getInlineStyle, - getStyleForProperty: getStyleForProperty, - getStartValues: getStartValues, - prepareObject: prepareObject, - }; - - var connect = {}; - /** @type {KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra} */ - connect.tween = null; - connect.processEasing = null; - - var Easing = { - linear: new CubicBezier(0, 0, 1, 1, 'linear'), - easingSinusoidalIn: new CubicBezier(0.47, 0, 0.745, 0.715, 'easingSinusoidalIn'), - easingSinusoidalOut: new CubicBezier(0.39, 0.575, 0.565, 1, 'easingSinusoidalOut'), - easingSinusoidalInOut: new CubicBezier(0.445, 0.05, 0.55, 0.95, 'easingSinusoidalInOut'), - - easingQuadraticIn: new CubicBezier(0.550, 0.085, 0.680, 0.530, 'easingQuadraticIn'), - easingQuadraticOut: new CubicBezier(0.250, 0.460, 0.450, 0.940, 'easingQuadraticOut'), - easingQuadraticInOut: new CubicBezier(0.455, 0.030, 0.515, 0.955, 'easingQuadraticInOut'), - - easingCubicIn: new CubicBezier(0.55, 0.055, 0.675, 0.19, 'easingCubicIn'), - easingCubicOut: new CubicBezier(0.215, 0.61, 0.355, 1, 'easingCubicOut'), - easingCubicInOut: new CubicBezier(0.645, 0.045, 0.355, 1, 'easingCubicInOut'), - - easingQuarticIn: new CubicBezier(0.895, 0.03, 0.685, 0.22, 'easingQuarticIn'), - easingQuarticOut: new CubicBezier(0.165, 0.84, 0.44, 1, 'easingQuarticOut'), - easingQuarticInOut: new CubicBezier(0.77, 0, 0.175, 1, 'easingQuarticInOut'), - - easingQuinticIn: new CubicBezier(0.755, 0.05, 0.855, 0.06, 'easingQuinticIn'), - easingQuinticOut: new CubicBezier(0.23, 1, 0.32, 1, 'easingQuinticOut'), - easingQuinticInOut: new CubicBezier(0.86, 0, 0.07, 1, 'easingQuinticInOut'), - - easingExponentialIn: new CubicBezier(0.95, 0.05, 0.795, 0.035, 'easingExponentialIn'), - easingExponentialOut: new CubicBezier(0.19, 1, 0.22, 1, 'easingExponentialOut'), - easingExponentialInOut: new CubicBezier(1, 0, 0, 1, 'easingExponentialInOut'), - - easingCircularIn: new CubicBezier(0.6, 0.04, 0.98, 0.335, 'easingCircularIn'), - easingCircularOut: new CubicBezier(0.075, 0.82, 0.165, 1, 'easingCircularOut'), - easingCircularInOut: new CubicBezier(0.785, 0.135, 0.15, 0.86, 'easingCircularInOut'), - - easingBackIn: new CubicBezier(0.6, -0.28, 0.735, 0.045, 'easingBackIn'), - easingBackOut: new CubicBezier(0.175, 0.885, 0.32, 1.275, 'easingBackOut'), - easingBackInOut: new CubicBezier(0.68, -0.55, 0.265, 1.55, 'easingBackInOut'), - }; - - /** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easingfunction - */ - function processBezierEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof (Easing[fn]) === 'function') { - return Easing[fn]; - } if (/bezier/.test(fn)) { - var bz = fn.replace(/bezier|\s|\(|\)/g, '').split(','); - return new CubicBezier(bz[0] * 1, bz[1] * 1, bz[2] * 1, bz[3] * 1); // bezier easing - } - // if (/elastic|bounce/i.test(fn)) { - // throw TypeError(`KUTE - CubicBezier doesn't support ${fn} easing.`); - // } - return Easing.linear; - } - - connect.processEasing = processBezierEasing; - - /** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ - function selector(el, multi) { - try { - var requestedElem; - var itemsArray; - if (multi) { - itemsArray = el instanceof Array && el.every(function (x) { return x instanceof Element; }); - requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray - ? el : document.querySelectorAll(el); - } else { - requestedElem = el instanceof Element || el === window // scroll - ? el : document.querySelector(el); - } - return requestedElem; - } catch (e) { - throw TypeError(("KUTE.js - Element(s) not found: " + el + ".")); - } - } - - function queueStart() { - var this$1$1 = this; - - // fire onStart actions - Object.keys(onStart).forEach(function (obj) { - if (typeof (onStart[obj]) === 'function') { - onStart[obj].call(this$1$1, obj); // easing functions - } else { - Object.keys(onStart[obj]).forEach(function (prop) { - onStart[obj][prop].call(this$1$1, prop); - }); - } - }); - - // add interpolations - linkInterpolation.call(this); - } - - /** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ - var TweenBase = function TweenBase(targetElement, startObject, endObject, opsObject) { - var this$1$1 = this; - - // element animation is applied to - this.element = targetElement; - - /** @type {boolean} */ - this.playing = false; - /** @type {number?} */ - this._startTime = null; - /** @type {boolean} */ - this._startFired = false; - - // type is set via KUTE.tweenProps - this.valuesEnd = endObject; - this.valuesStart = startObject; - - // OPTIONS - var options = opsObject || {}; - // internal option to process inline/computed style at start instead of init - // used by to() method and expects object : {} / false - this._resetStart = options.resetStart || 0; - // you can only set a core easing function as default - /** @type {KUTE.easingOption} */ - this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing); - /** @type {number} */ - this._duration = options.duration || defaultOptions$1.duration; // duration option | default - /** @type {number} */ - this._delay = options.delay || defaultOptions$1.delay; // delay option | default - - // set other options - Object.keys(options).forEach(function (op) { - var internalOption = "_" + op; - if (!(internalOption in this$1$1)) { this$1$1[internalOption] = options[op]; } - }); - - // callbacks should not be set as undefined - // this._onStart = options.onStart - // this._onUpdate = options.onUpdate - // this._onStop = options.onStop - // this._onComplete = options.onComplete - - // queue the easing - var easingFnName = this._easing.name; - if (!onStart[easingFnName]) { - onStart[easingFnName] = function easingFn(prop) { - if (!KEC[prop] && prop === this._easing.name) { KEC[prop] = this._easing; } - }; - } - - return this; - }; - - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.start = function start (time) { - // now it's a good time to start - add(this); - this.playing = true; - - this._startTime = typeof time !== 'undefined' ? time : KEC.Time(); - this._startTime += this._delay; - - if (!this._startFired) { - if (this._onStart) { - this._onStart.call(this); - } - - queueStart.call(this); - - this._startFired = true; - } - - if (!Tick) { Ticker(); } - return this; - }; - - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - TweenBase.prototype.stop = function stop () { - if (this.playing) { - remove(this); - this.playing = false; - - if (this._onStop) { - this._onStop.call(this); - } - this.close(); - } - return this; - }; - - /** - * Trigger internal completion callbacks. - */ - TweenBase.prototype.close = function close () { - var this$1$1 = this; - - // scroll|transformMatrix need this - Object.keys(onComplete).forEach(function (component) { - Object.keys(onComplete[component]).forEach(function (toClose) { - onComplete[component][toClose].call(this$1$1, toClose); - }); - }); - // when all animations are finished, stop ticking after ~3 frames - this._startFired = false; - stop.call(this); - }; - - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - TweenBase.prototype.chain = function chain (args) { - this._chain = []; - this._chain = args.length ? args : this._chain.concat(args); - return this; - }; - - /** - * Stop tweening the chained tween instances. - */ - TweenBase.prototype.stopChainedTweens = function stopChainedTweens () { - if (this._chain && this._chain.length) { this._chain.forEach(function (tw) { return tw.stop(); }); } - }; - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - TweenBase.prototype.update = function update (time) { - var this$1$1 = this; - - var T = time !== undefined ? time : KEC.Time(); - - var elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - var progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach(function (tweenProp) { - KEC[tweenProp](this$1$1.element, - this$1$1.valuesStart[tweenProp], - this$1$1.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.map(function (tw) { return tw.start(); }); - } - - return false; - } - - return true; - }; - - // Update Tween Interface - connect.tween = TweenBase; - - /** - * The `KUTE.Tween()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor adds additional functionality and is the default - * Tween object constructor in KUTE.js. - */ - var Tween = /*@__PURE__*/(function (TweenBase) { - function Tween() { - var this$1$1 = this; - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - TweenBase.apply(this, args); // this calls the constructor of TweenBase - - // reset interpolation values - this.valuesStart = {}; - this.valuesEnd = {}; - - // const startObject = args[1]; - // const endObject = args[2]; - var ref = args.slice(1); - var startObject = ref[0]; - var endObject = ref[1]; - var options = ref[2]; - - // set valuesEnd - prepareObject.call(this, endObject, 'end'); - - // set valuesStart - if (this._resetStart) { - this.valuesStart = startObject; - } else { - prepareObject.call(this, startObject, 'start'); - } - - // ready for crossCheck - if (!this._resetStart) { - Object.keys(crossCheck).forEach(function (component) { - Object.keys(crossCheck[component]).forEach(function (checkProp) { - crossCheck[component][checkProp].call(this$1$1, checkProp); - }); - }); - } - - // set paused state - /** @type {boolean} */ - this.paused = false; - /** @type {number?} */ - this._pauseTime = null; - - // additional properties and options - /** @type {number?} */ - this._repeat = options.repeat || defaultOptions$1.repeat; - /** @type {number?} */ - this._repeatDelay = options.repeatDelay || defaultOptions$1.repeatDelay; - // we cache the number of repeats to be able to put it back after all cycles finish - /** @type {number?} */ - this._repeatOption = this._repeat; - - // yoyo needs at least repeat: 1 - /** @type {KUTE.tweenProps} */ - this.valuesRepeat = {}; // valuesRepeat - /** @type {boolean} */ - this._yoyo = options.yoyo || defaultOptions$1.yoyo; - /** @type {boolean} */ - this._reversed = false; - - // don't load extra callbacks - // this._onPause = options.onPause || defaultOptions.onPause - // this._onResume = options.onResume || defaultOptions.onResume - - // chained Tweens - // this._chain = options.chain || defaultOptions.chain; - return this; - } - - if ( TweenBase ) Tween.__proto__ = TweenBase; - Tween.prototype = Object.create( TweenBase && TweenBase.prototype ); - Tween.prototype.constructor = Tween; - - /** - * Starts tweening, extended method - * @param {number?} time the tween start time - * @returns {Tween} this instance - */ - Tween.prototype.start = function start (time) { - var this$1$1 = this; - - // on start we reprocess the valuesStart for TO() method - if (this._resetStart) { - this.valuesStart = this._resetStart; - getStartValues.call(this); - - // this is where we do the valuesStart and valuesEnd check for fromTo() method - Object.keys(crossCheck).forEach(function (component) { - Object.keys(crossCheck[component]).forEach(function (checkProp) { - crossCheck[component][checkProp].call(this$1$1, checkProp); - }); - }); - } - // still not paused - this.paused = false; - - // set yoyo values - if (this._yoyo) { - Object.keys(this.valuesEnd).forEach(function (endProp) { - this$1$1.valuesRepeat[endProp] = this$1$1.valuesStart[endProp]; - }); - } - - TweenBase.prototype.start.call(this, time); - - return this; - }; - - /** - * Stops tweening, extended method - * @returns {Tween} this instance - */ - Tween.prototype.stop = function stop () { - TweenBase.prototype.stop.call(this); - if (!this.paused && this.playing) { - this.paused = false; - this.stopChainedTweens(); - } - return this; - }; - - /** - * Trigger internal completion callbacks. - */ - Tween.prototype.close = function close () { - TweenBase.prototype.close.call(this); - - if (this._repeatOption > 0) { - this._repeat = this._repeatOption; - } - if (this._yoyo && this._reversed === true) { - this.reverse(); - this._reversed = false; - } - - return this; - }; - - /** - * Resume tweening - * @returns {Tween} this instance - */ - Tween.prototype.resume = function resume () { - if (this.paused && this.playing) { - this.paused = false; - if (this._onResume !== undefined) { - this._onResume.call(this); - } - // re-queue execution context - queueStart.call(this); - // update time and let it roll - this._startTime += KEC.Time() - this._pauseTime; - add(this); - // restart ticker if stopped - if (!Tick) { Ticker(); } - } - return this; - }; - - /** - * Pause tweening - * @returns {Tween} this instance - */ - Tween.prototype.pause = function pause () { - if (!this.paused && this.playing) { - remove(this); - this.paused = true; - this._pauseTime = KEC.Time(); - if (this._onPause !== undefined) { - this._onPause.call(this); - } - } - return this; - }; - - /** - * Reverses start values with end values - */ - Tween.prototype.reverse = function reverse () { - var this$1$1 = this; - - Object.keys(this.valuesEnd).forEach(function (reverseProp) { - var tmp = this$1$1.valuesRepeat[reverseProp]; - this$1$1.valuesRepeat[reverseProp] = this$1$1.valuesEnd[reverseProp]; - this$1$1.valuesEnd[reverseProp] = tmp; - this$1$1.valuesStart[reverseProp] = this$1$1.valuesRepeat[reverseProp]; - }); - }; - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - Tween.prototype.update = function update (time) { - var this$1$1 = this; - - var T = time !== undefined ? time : KEC.Time(); - - var elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - var progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach(function (tweenProp) { - KEC[tweenProp](this$1$1.element, - this$1$1.valuesStart[tweenProp], - this$1$1.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - if (this._repeat > 0) { - if (Number.isFinite(this._repeat)) { this._repeat -= 1; } - - // set the right time for delay - this._startTime = T; - if (Number.isFinite(this._repeat) && this._yoyo && !this._reversed) { - this._startTime += this._repeatDelay; - } - - if (this._yoyo) { // handle yoyo - this._reversed = !this._reversed; - this.reverse(); - } - - return true; - } - - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.forEach(function (tw) { return tw.start(); }); - } - - return false; - } - return true; - }; - - return Tween; - }(TweenBase)); - - // Update Tween Interface Update - connect.tween = Tween; - - /** - * The static method creates a new `Tween` object for each `HTMLElement` - * from and `Array`, `HTMLCollection` or `NodeList`. - */ - var TweenCollection = function TweenCollection(els, vS, vE, Options) { - var this$1$1 = this; - - var TweenConstructor = connect.tween; - /** @type {KUTE.twCollection[]} */ - this.tweens = []; - - var Ops = Options || {}; - /** @type {number?} */ - Ops.delay = Ops.delay || defaultOptions$1.delay; - - // set all options - var options = []; - - Array.from(els).forEach(function (el, i) { - options[i] = Ops || {}; - options[i].delay = i > 0 ? Ops.delay + (Ops.offset || defaultOptions$1.offset) : Ops.delay; - if (el instanceof Element) { - this$1$1.tweens.push(new TweenConstructor(el, vS, vE, options[i])); - } else { - throw Error(("KUTE - " + el + " is not instanceof Element")); - } - }); - - /** @type {number?} */ - this.length = this.tweens.length; - return this; - }; - - /** - * Starts tweening, all targets - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.start = function start (time) { - var T = time === undefined ? KEC.Time() : time; - this.tweens.map(function (tween) { return tween.start(T); }); - return this; - }; - - /** - * Stops tweening, all targets and their chains - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.stop = function stop () { - this.tweens.map(function (tween) { return tween.stop(); }); - return this; - }; - - /** - * Pause tweening, all targets - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.pause = function pause () { - this.tweens.map(function (tween) { return tween.pause(); }); - return this; - }; - - /** - * Resume tweening, all targets - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.resume = function resume () { - this.tweens.map(function (tween) { return tween.resume(); }); - return this; - }; - - /** - * Schedule another tween or collection to start after - * this one is complete. - * @param {number?} args the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.chain = function chain (args) { - var lastTween = this.tweens[this.length - 1]; - if (args instanceof TweenCollection) { - lastTween.chain(args.tweens); - } else if (args instanceof connect.tween) { - lastTween.chain(args); - } else { - throw new TypeError('KUTE.js - invalid chain value'); - } - return this; - }; - - /** - * Check if any tween instance is playing - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - TweenCollection.prototype.playing = function playing () { - return this.tweens.some(function (tw) { return tw.playing; }); - }; - - /** - * Remove all tweens in the collection - */ - TweenCollection.prototype.removeTweens = function removeTweens () { - this.tweens = []; - }; - - /** - * Returns the maximum animation duration - * @returns {number} this instance - */ - TweenCollection.prototype.getMaxDuration = function getMaxDuration () { - var durations = []; - this.tweens.forEach(function (tw) { - durations.push(tw._duration + tw._delay + tw._repeat * tw._repeatDelay); - }); - return Math.max(durations); - }; - - var TweenConstructor$1 = connect.tween; - - /** - * The `KUTE.to()` static method returns a new Tween object - * for a single `HTMLElement` at its current state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - function to(element, endObject, optionsObj) { - var options = optionsObj || {}; - options.resetStart = endObject; - return new TweenConstructor$1(selector(element), endObject, endObject, options); - } - - var TweenConstructor = connect.tween; - - /** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - function fromTo(element, startObject, endObject, optionsObj) { - var options = optionsObj || {}; - return new TweenConstructor(selector(element), startObject, endObject, options); - } - - /** - * The `KUTE.allTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at their current state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenProps} optionsObj progress - * @returns {TweenCollection} the Tween object collection - */ - function allTo(elements, endObject, optionsObj) { - var options = optionsObj || {}; - options.resetStart = endObject; - return new TweenCollection(selector(elements, true), endObject, endObject, options); - } - - /** - * The `KUTE.allFromTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at a given state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {TweenCollection} the Tween object collection - */ - function allFromTo(elements, startObject, endObject, optionsObj) { - var options = optionsObj || {}; - return new TweenCollection(selector(elements, true), startObject, endObject, options); - } - - /** - * Animation Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - */ - var Animation = function Animation(Component) { - try { - if (Component.component in supportedProperties) { - throw Error(("KUTE - " + (Component.component) + " already registered")); - } else if (Component.property in defaultValues) { - throw Error(("KUTE - " + (Component.property) + " already registered")); - } - } catch (e) { - throw Error(e); - } - - var propertyInfo = this; - var ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - var Functions = { - prepareProperty: prepareProperty, prepareStart: prepareStart, onStart: onStart, onComplete: onComplete, crossCheck: crossCheck, - }; - var Category = Component.category; - var Property = Component.property; - var Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // single property - // {property,defaultvalue,defaultOptions,Interpolate,functions} - - // category colors, boxModel, borderRadius - // {category,properties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg transform, filter - // {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg htmlAttributes - // {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - defaultValues[Property] = Component.defaultValue; - - // minimal info - propertyInfo.supports = Property + " property"; - } else if (Component.defaultValues) { - Object.keys(Component.defaultValues).forEach(function (dv) { - defaultValues[dv] = Component.defaultValues[dv]; - }); - - // minimal info - propertyInfo.supports = (Length || Property) + " " + (Property || Category) + " properties"; - } - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions$1, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach(function (fn) { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) { Functions[fn][ComponentName] = {}; } - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach(function (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 interpolation functions - if (Component.Interpolate) { - Object.keys(Component.Interpolate).forEach(function (fni) { - var compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach(function (sfn) { - if (typeof (compIntObj[sfn]) === 'function' && !interpolate[fni]) { - interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach(function (fnu) { - if (!Util[fnu]) { Util[fnu] = Component.Util[fnu]; } - }); - } - - return propertyInfo; - }; - - /** - * trueDimension - * - * Returns the string value of a specific CSS property converted into a nice - * { v = value, u = unit } object. - * - * @param {string} dimValue the property string value - * @param {boolean | number} isAngle sets the utility to investigate angles - * @returns {{v: number, u: string}} the true {value, unit} tuple - */ - var trueDimension = function (dimValue, isAngle) { - var intValue = parseInt(dimValue, 10) || 0; - var mUnits = ['px', '%', 'deg', 'rad', 'em', 'rem', 'vh', 'vw']; - var theUnit; - - for (var mIndex = 0; mIndex < mUnits.length; mIndex += 1) { - if (typeof dimValue === 'string' && dimValue.includes(mUnits[mIndex])) { - theUnit = mUnits[mIndex]; break; - } - } - if (theUnit === undefined) { - theUnit = isAngle ? 'deg' : 'px'; - } - - return { v: intValue, u: theUnit }; - }; - - /** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ - function numbers(a, b, v) { - var A = +a; - var B = b - a; - // a = +a; b -= a; - return A + B * v; - } - - // Component Functions - /** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - function boxModelOnStart(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - /* eslint-disable no-bitwise -- impossible to satisfy */ - elem.style[tweenProp] = (v > 0.99 || v < 0.01 - ? ((numbers(a, b, v) * 10) >> 0) / 10 - : (numbers(a, b, v)) >> 0) + "px"; - /* eslint-enable no-bitwise */ - /* eslint-enable no-param-reassign */ - }; - } - } - - // Component Base Props - var baseBoxProps = ['top', 'left', 'width', 'height']; - var baseBoxOnStart = {}; - baseBoxProps.forEach(function (x) { baseBoxOnStart[x] = boxModelOnStart; }); - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getBoxModel(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property name - * @returns {number} the property tween object - */ - function prepareBoxModel(tweenProp, value) { - var boxValue = trueDimension(value); - var offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; - return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v; - } - - // Component Base Props - var essentialBoxProps = ['top', 'left', 'width', 'height']; - var essentialBoxPropsValues = { - top: 0, left: 0, width: 0, height: 0, - }; - - var essentialBoxOnStart = {}; - essentialBoxProps.forEach(function (x) { essentialBoxOnStart[x] = boxModelOnStart; }); - - // All Component Functions - var essentialBoxModelFunctions = { - prepareStart: getBoxModel, - prepareProperty: prepareBoxModel, - onStart: essentialBoxOnStart, - }; - - // Component Essential - var BoxModelEssential = { - component: 'essentialBoxModel', - category: 'boxModel', - properties: essentialBoxProps, - defaultValues: essentialBoxPropsValues, - Interpolate: { numbers: numbers }, - functions: essentialBoxModelFunctions, - Util: { trueDimension: trueDimension }, - }; - - /** - * hexToRGB - * - * Converts a #HEX color format into RGB - * and returns a color object {r,g,b}. - * - * @param {string} hex the degree angle - * @returns {KUTE.colorObject | null} the radian angle - */ - var hexToRGB = function (hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var hexShorthand = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - var HEX = hex.replace(hexShorthand, function (_, r, g, b) { return r + r + g + g + b + b; }); - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(HEX); - - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), - } : null; - }; - - /** - * trueColor - * - * Transform any color to rgba()/rgb() and return a nice RGB(a) object. - * - * @param {string} colorString the color input - * @returns {KUTE.colorObject} the {r,g,b,a} color object - */ - var trueColor = function (colorString) { - var result; - if (/rgb|rgba/.test(colorString)) { // first check if it's a rgb string - var vrgb = colorString.replace(/\s|\)/, '').split('(')[1].split(','); - var colorAlpha = vrgb[3] ? vrgb[3] : null; - if (!colorAlpha) { - result = { r: parseInt(vrgb[0], 10), g: parseInt(vrgb[1], 10), b: parseInt(vrgb[2], 10) }; - } - result = { - r: parseInt(vrgb[0], 10), - g: parseInt(vrgb[1], 10), - b: parseInt(vrgb[2], 10), - a: parseFloat(colorAlpha), - }; - } if (/^#/.test(colorString)) { - var fromHex = hexToRGB(colorString); - result = { r: fromHex.r, g: fromHex.g, b: fromHex.b }; - } if (/transparent|none|initial|inherit/.test(colorString)) { - result = { - r: 0, g: 0, b: 0, a: 0, - }; - } - // maybe we can check for web safe colors - // only works in a browser - if (!/^#|^rgb/.test(colorString)) { - var siteHead = document.getElementsByTagName('head')[0]; - siteHead.style.color = colorString; - var webColor = getComputedStyle(siteHead, null).color; - webColor = /rgb/.test(webColor) ? webColor.replace(/[^\d,]/g, '').split(',') : [0, 0, 0]; - siteHead.style.color = ''; - result = { - r: parseInt(webColor[0], 10), - g: parseInt(webColor[1], 10), - b: parseInt(webColor[2], 10), - }; - } - return result; - }; - - /** - * Color Interpolation Function. - * - * @param {KUTE.colorObject} a start color - * @param {KUTE.colorObject} b end color - * @param {number} v progress - * @returns {string} the resulting color - */ - function colors(a, b, v) { - var _c = {}; - var ep = ')'; - var cm = ','; - var rgb = 'rgb('; - var rgba = 'rgba('; - - Object.keys(b).forEach(function (c) { - if (c !== 'a') { - _c[c] = numbers(a[c], b[c], v) >> 0 || 0; // eslint-disable-line no-bitwise - } else if (a[c] && b[c]) { - _c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100; // eslint-disable-line no-bitwise - } - }); - - 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; - } - - // Component Interpolation - // rgba1, rgba2, progress - - // Component Properties - // supported formats - // 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) - var supportedColors$1 = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', - 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor' ]; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartColors(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = colors(a, b, v); - }; - } - } - - var colorsOnStart$1 = {}; - supportedColors$1.forEach(function (x) { colorsOnStart$1[x] = onStartColors; }); - - // Component Properties - // supported formats - // 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) - var supportedColors = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor' ]; - - var defaultColors = {}; - supportedColors.forEach(function (tweenProp) { - defaultColors[tweenProp] = '#000'; - }); - - // Component Functions - var colorsOnStart = {}; - supportedColors.forEach(function (x) { - colorsOnStart[x] = onStartColors; - }); - - /** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} property computed style - */ - function getColor(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.colorObject} the property tween object - */ - function prepareColor(/* prop, */_, value) { - return trueColor(value); - } - - // All Component Functions - var colorFunctions = { - prepareStart: getColor, - prepareProperty: prepareColor, - onStart: colorsOnStart, - }; - - // Component Full - var colorProperties = { - component: 'colorProperties', - category: 'colors', - properties: supportedColors, - defaultValues: defaultColors, - Interpolate: { numbers: numbers, colors: colors }, - functions: colorFunctions, - Util: { trueColor: trueColor }, - }; - - // Component Special - var attributes = {}; - - var onStartAttr = { - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - attr: function attr(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (elem, vS, vE, v) { - Object.keys(vE).forEach(function (oneAttr) { - KEC.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v); - }); - }; - } - }, - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - attributes: function attributes$1(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd.attr) { - KEC[tweenProp] = attributes; - } - }, - }; - - // Component Name - var ComponentName = 'htmlAttributes'; - - // Component Properties - var svgColors = ['fill', 'stroke', 'stop-color']; - - // Component Util - /** - * Returns non-camelcase property name. - * @param {string} a the camelcase property name - * @returns {string} the non-camelcase property name - */ - function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); } - - // Component Functions - /** - * Returns the current attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {{[x:string]: string}} attribute value - */ - function getAttr(/* tweenProp, */_, value) { - var this$1$1 = this; - - var attrStartValues = {}; - Object.keys(value).forEach(function (attr) { - // get the value for 'fill-opacity' not fillOpacity - // also 'width' not the internal 'width_px' - var attribute = replaceUppercase(attr).replace(/_+[a-z]+/, ''); - var currentValue = this$1$1.element.getAttribute(attribute); - attrStartValues[attribute] = svgColors.includes(attribute) - ? (currentValue || 'rgba(0,0,0,0)') - : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); - }); - - return attrStartValues; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} attrObj the property value - * @returns {number} the property tween object - */ - function prepareAttr(tweenProp, attrObj) { - var this$1$1 = this; - // attr (string),attrObj (object) - var attributesObject = {}; - - Object.keys(attrObj).forEach(function (p) { - var prop = replaceUppercase(p); - var regex = /(%|[a-z]+)$/; - var currentValue = this$1$1.element.getAttribute(prop.replace(/_+[a-z]+/, '')); - - if (!svgColors.includes(prop)) { - // attributes set with unit suffixes - if (currentValue !== null && regex.test(currentValue)) { - var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - var suffix = /%/.test(unit) ? '_percent' : ("_" + unit); - - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop + suffix] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - var _p = oneAttr.replace(suffix, ''); - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - 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] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000); - }; - } - }; - attributesObject[prop] = parseFloat(attrObj[p]); - } - } else { // colors - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = function (tp) { - if (this$1$1.valuesEnd[tweenProp] && this$1$1.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = function (elem, oneAttr, a, b, v) { - elem.setAttribute(oneAttr, colors(a, b, v)); - }; - } - }; - attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; - } - }); - - return attributesObject; - } - - // All Component Functions - var attrFunctions = { - prepareStart: getAttr, - prepareProperty: prepareAttr, - onStart: onStartAttr, - }; - - // Component Full - var htmlAttributes = { - component: ComponentName, - property: 'attr', - // the Animation class will need some values to validate this Object attribute - subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'], - defaultValue: { - fill: 'rgb(0,0,0)', - stroke: 'rgb(0,0,0)', - 'stop-color': 'rgb(0,0,0)', - opacity: 1, - 'stroke-opacity': 1, - 'fill-opacity': 1, // same here - }, - Interpolate: { numbers: numbers, colors: colors }, - functions: attrFunctions, - // export to global for faster execution - Util: { replaceUppercase: replaceUppercase, trueColor: trueColor, trueDimension: trueDimension }, - }; - - /* opacityProperty = { - property: 'opacity', - defaultValue: 1, - interpolators: {numbers}, - functions = { prepareStart, prepareProperty, onStart } - } */ - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartOpacity(tweenProp/* , value */) { - // opacity could be 0 sometimes, we need to check regardless - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000; - /* eslint-enable */ - }; - } - } - - // Component Functions - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getOpacity(tweenProp/* , value */) { - return getStyleForProperty(this.element, tweenProp); - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareOpacity(/* tweenProp, */_, value) { - return parseFloat(value); // opacity always FLOAT - } - - // All Component Functions - var opacityFunctions = { - prepareStart: getOpacity, - prepareProperty: prepareOpacity, - onStart: onStartOpacity, - }; - - // Full Component - var OpacityProperty = { - component: 'opacityProperty', - property: 'opacity', - defaultValue: 1, - Interpolate: { numbers: numbers }, - functions: opacityFunctions, - }; - - // Component Values - var lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase - var upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase - var nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols - var numeric = String('0123456789').split(''); // numeric - var alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric - var allTypes = alphaNumeric.concat(nonAlpha); // all caracters - - var charSet = { - alpha: lowerCaseAlpha, // lowercase - upper: upperCaseAlpha, // uppercase - symbols: nonAlpha, // symbols - numeric: numeric, - alphanumeric: alphaNumeric, - all: allTypes, - }; - - // Component Functions - var onStartWrite = { - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - text: function text(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - var chars = this._textChars; - var charsets = charSet[defaultOptions$1.textChars]; - - if (chars in charSet) { - charsets = charSet[chars]; - } else if (chars && chars.length) { - charsets = chars; - } - - KEC[tweenProp] = function (elem, a, b, v) { - var initialText = ''; - var endText = ''; - var finalText = b === '' ? ' ' : b; - var firstLetterA = a.substring(0); - var firstLetterB = b.substring(0); - /* eslint-disable */ - var pointer = charsets[(Math.random() * charsets.length) >> 0]; - - if (a === ' ') { - endText = firstLetterB - .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0); - elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText; - } else if (b === ' ') { - initialText = firstLetterA - .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0); - elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText; - } else { - initialText = firstLetterA - .substring(firstLetterA.length, - Math.min(v * firstLetterA.length, firstLetterA.length) >> 0); - endText = firstLetterB - .substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0); - elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText; - } - /* eslint-enable */ - }; - } - }, - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - number: function number(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { // numbers can be 0 - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable */ - elem.innerHTML = numbers(a, b, v) >> 0; - /* eslint-enable */ - }; - } - }, - }; - - // Component Util - // utility for multi-child targets - // wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class - function wrapContentsSpan(el, classNAME) { - var assign; - - var textWriteWrapper; - var newElem; - if (typeof (el) === 'string') { - newElem = document.createElement('SPAN'); - newElem.innerHTML = el; - newElem.className = classNAME; - return newElem; - } - if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) { - var elementInnerHTML = el.innerHTML; - textWriteWrapper = document.createElement('SPAN'); - textWriteWrapper.className = classNAME; - textWriteWrapper.innerHTML = elementInnerHTML; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - el.appendChild(textWriteWrapper); - el.innerHTML = textWriteWrapper.outerHTML; - /* eslint-enable no-param-reassign -- impossible to satisfy */ - } else if (el.children.length && el.children[0].className === classNAME) { - (assign = el.children, textWriteWrapper = assign[0]); - } - return textWriteWrapper; - } - - function getTextPartsArray(el, classNAME) { - var elementsArray = []; - var len = el.children.length; - if (len) { - var textParts = []; - var remainingMarkup = el.innerHTML; - var wrapperParts; - - for (var i = 0, currentChild = (void 0), childOuter = (void 0), unTaggedContent = (void 0); i < len; i += 1) { - currentChild = el.children[i]; - childOuter = currentChild.outerHTML; - wrapperParts = remainingMarkup.split(childOuter); - - if (wrapperParts[0] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0], ''); - } else if (wrapperParts[1] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], ''); - } - - if (!currentChild.classList.contains(classNAME)) { currentChild.classList.add(classNAME); } - textParts.push(currentChild); - remainingMarkup = remainingMarkup.replace(childOuter, ''); - } - - if (remainingMarkup !== '') { - var unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME); - textParts.push(unTaggedRemaining); - } - - elementsArray = elementsArray.concat(textParts); - } else { - elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]); - } - return elementsArray; - } - - function setSegments(target, newText) { - var oldTargetSegs = getTextPartsArray(target, 'text-part'); - var newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part'); - - /* eslint-disable no-param-reassign */ - target.innerHTML = ''; - target.innerHTML += oldTargetSegs.map(function (s) { s.className += ' oldText'; return s.outerHTML; }).join(''); - target.innerHTML += newTargetSegs.map(function (s) { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join(''); - /* eslint-enable no-param-reassign */ - - return [oldTargetSegs, newTargetSegs]; - } - - function createTextTweens(target, newText, ops) { - if (target.playing) { return false; } - - var options = ops || {}; - options.duration = 1000; - - if (ops.duration === 'auto') { - options.duration = 'auto'; - } else if (Number.isFinite(ops.duration * 1)) { - options.duration = ops.duration * 1; - } - - var TweenContructor = connect.tween; - var segs = setSegments(target, newText); - var oldTargetSegs = segs[0]; - var newTargetSegs = segs[1]; - var oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); - var newTargets = [].slice.call(target.getElementsByClassName('newText')); - - var textTween = []; - var totalDelay = 0; - - textTween = textTween.concat(oldTargets.map(function (el, i) { - options.duration = options.duration === 'auto' - ? oldTargetSegs[i].innerHTML.length * 75 - : options.duration; - options.delay = totalDelay; - options.onComplete = null; - - totalDelay += options.duration; - return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options); - })); - textTween = textTween.concat(newTargets.map(function (el, i) { - function onComplete() { - /* eslint-disable no-param-reassign */ - target.innerHTML = newText; - target.playing = false; - /* eslint-enable no-param-reassign */ - } - - options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; - options.delay = totalDelay; - options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null; - totalDelay += options.duration; - - return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options); - })); - - textTween.start = function startTweens() { - if (!target.playing) { - textTween.forEach(function (tw) { return tw.start(); }); - // eslint-disable-next-line no-param-reassign - target.playing = true; - } - }; - - return textTween; - } - - // Component Functions - /** - * Returns the current element `innerHTML`. - * @returns {string} computed style for property - */ - function getWrite(/* tweenProp, value */) { - return this.element.innerHTML; - } - - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number | string} the property tween object - */ - function prepareText(tweenProp, value) { - if (tweenProp === 'number') { - return parseFloat(value); - } - // empty strings crash the update function - return value === '' ? ' ' : value; - } - - // All Component Functions - var textWriteFunctions = { - prepareStart: getWrite, - prepareProperty: prepareText, - onStart: onStartWrite, - }; - - // Full Component - var TextWrite = { - component: 'textWriteProperties', - category: 'textWrite', - properties: ['text', 'number'], - defaultValues: { text: ' ', number: '0' }, - defaultOptions: { textChars: 'alpha' }, - Interpolate: { numbers: numbers }, - functions: textWriteFunctions, - // export to global for faster execution - Util: { charSet: charSet, createTextTweens: createTextTweens }, - }; - - /** - * Perspective Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the perspective function in string format - */ - function perspective(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return ("perspective(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + u + ")"); - } - - /** - * Translate 3D Interpolation Function. - * - * @param {number[]} a start [x,y,z] position - * @param {number[]} b end [x,y,z] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D translation string - */ - function translate3d(a, b, u, v) { - var translateArray = []; - for (var ax = 0; ax < 3; ax += 1) { - translateArray[ax] = (a[ax] || b[ax] - // eslint-disable-next-line no-bitwise - ? ((a[ax] + (b[ax] - a[ax]) * v) * 1000 >> 0) / 1000 : 0) + u; - } - return ("translate3d(" + (translateArray.join(',')) + ")"); - } - - /** - * 3D Rotation Interpolation Function. - * - * @param {number} a start [x,y,z] angles - * @param {number} b end [x,y,z] angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D rotation string - */ - function rotate3d(a, b, u, v) { - var rotateStr = ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[0] || b[0] ? ("rotateX(" + (((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[1] || b[1] ? ("rotateY(" + (((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[2] || b[2] ? ("rotateZ(" + (((a[2] + (b[2] - a[2]) * v) * 1000 >> 0) / 1000) + u + ")") : ''; - return rotateStr; - } - - /** - * Translate 2D Interpolation Function. - * - * @param {number[]} a start [x,y] position - * @param {number[]} b end [x,y] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 2D translation string - */ - function translate(a, b, u, v) { - var translateArray = []; - // eslint-disable-next-line no-bitwise - translateArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')) + ")"); - } - - /** - * 2D Rotation Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated rotation - */ - function rotate(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return ("rotate(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + u + ")"); - } - - /** - * Scale Interpolation Function. - * - * @param {number} a start scale - * @param {number} b end scale - * @param {number} v progress - * @returns {string} the interpolated scale - */ - function scale(a, b, v) { - // eslint-disable-next-line no-bitwise - return ("scale(" + (((a + (b - a) * v) * 1000 >> 0) / 1000) + ")"); - } - - /** - * Skew Interpolation Function. - * - * @param {number} a start {x,y} angles - * @param {number} b end {x,y} angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated string value of skew(s) - */ - function skew(a, b, u, v) { - var skewArray = []; - // eslint-disable-next-line no-bitwise - skewArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')) + ")"); - } - - // Component Functions - /** - * Sets the property update function. - * * same to svgTransform, htmlAttributes - * @param {string} tweenProp the property name - */ - function onStartTransform(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0 - + (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z] - + (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z] - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } - } - - // same to svg transform, attr - // the component developed for modern browsers supporting non-prefixed transform - - // Component Functions - /** - * Returns the current property inline style. - * @param {string} tweenProp the property name - * @returns {string} inline style for property - */ - function getTransform(tweenProp/* , value */) { - var currentStyle = getInlineStyle(this.element); - return currentStyle[tweenProp] ? currentStyle[tweenProp] : defaultValues[tweenProp]; - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ - function prepareTransform(/* prop, */_, obj) { - var prepAxis = ['X', 'Y', 'Z']; // coordinates - var transformObject = {}; - var translateArray = []; var rotateArray = []; var skewArray = []; - var arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew']; - - Object.keys(obj).forEach(function (x) { - var pv = typeof obj[x] === 'object' && obj[x].length - ? obj[x].map(function (v) { return parseInt(v, 10); }) - : parseInt(obj[x], 10); - - if (arrayFunctions.includes(x)) { - var propId = x === 'translate' || x === 'rotate' ? (x + "3d") : x; - - if (x === 'skew') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0] - : [pv || 0, 0]; - } else if (x === 'translate') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0, pv[2] || 0] - : [pv || 0, 0, 0]; - } else { // translate3d | rotate3d - transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0]; - } - } else if (/[XYZ]/.test(x)) { - var fn = x.replace(/[XYZ]/, ''); - var fnId = fn === 'skew' ? fn : (fn + "3d"); - var fnLen = fn === 'skew' ? 2 : 3; - var fnArray = []; - - if (fn === 'translate') { - fnArray = translateArray; - } else if (fn === 'rotate') { - fnArray = rotateArray; - } else if (fn === 'skew') { - fnArray = skewArray; - } - - for (var fnIndex = 0; fnIndex < fnLen; fnIndex += 1) { - var fnAxis = prepAxis[fnIndex]; - fnArray[fnIndex] = (("" + fn + fnAxis) in obj) ? parseInt(obj[("" + fn + fnAxis)], 10) : 0; - } - transformObject[fnId] = fnArray; - } else if (x === 'rotate') { // rotate - transformObject.rotate3d = [0, 0, pv]; - } else { // scale | perspective - transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv; - } - }); - - return transformObject; - } - - /** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ - function crossCheckTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } - } - } - - // All Component Functions - var transformFunctions = { - prepareStart: getTransform, - prepareProperty: prepareTransform, - onStart: onStartTransform, - crossCheck: crossCheckTransform, - }; - - var supportedTransformProperties = [ - 'perspective', - 'translate3d', 'translateX', 'translateY', 'translateZ', 'translate', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate', - 'skewX', 'skewY', 'skew', - 'scale' ]; - - var defaultTransformValues = { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - translate: [0, 0], - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - rotate: 0, - skewX: 0, - skewY: 0, - skew: [0, 0], - scale: 1, - }; - - // Full Component - var TransformFunctions = { - component: 'transformFunctions', - property: 'transform', - subProperties: supportedTransformProperties, - defaultValues: defaultTransformValues, - functions: transformFunctions, - Interpolate: { - perspective: perspective, - translate3d: translate3d, - rotate3d: rotate3d, - translate: translate, - rotate: rotate, - scale: scale, - skew: skew, - }, - }; - - // Component Functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartDraw(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - /* eslint-disable no-bitwise -- impossible to satisfy */ - var pathLength = (a.l * 100 >> 0) / 100; - var start = (numbers(a.s, b.s, v) * 100 >> 0) / 100; - var end = (numbers(a.e, b.e, v) * 100 >> 0) / 100; - var offset = 0 - start; - var dashOne = end + offset; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDashoffset = offset + "px"; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDasharray = (((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100) + "px, " + pathLength + "px"; - /* eslint-disable no-bitwise -- impossible to satisfy */ - }; - } - } - - // Component Util - /** - * Convert a `` length percent value to absolute. - * @param {string} v raw value - * @param {number} l length value - * @returns {number} the absolute value - */ - function percent(v, l) { - return (parseFloat(v) / 100) * l; - } - - /** - * Returns the `` length. - * It doesn't compute `rx` and / or `ry` of the element. - * @see http://stackoverflow.com/a/30376660 - * @param {SVGRectElement} el target element - * @returns {number} the `` length - */ - function getRectLength(el) { - var w = el.getAttribute('width'); - var h = el.getAttribute('height'); - return (w * 2) + (h * 2); - } - - /** - * Returns the `` / `` length. - * @param {SVGPolylineElement | SVGPolygonElement} el target element - * @returns {number} the element length - */ - function getPolyLength(el) { - var points = el.getAttribute('points').split(' '); - - var len = 0; - if (points.length > 1) { - var coord = function (p) { - var c = p.split(','); - if (c.length !== 2) { return 0; } // return undefined - if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; } - return [parseFloat(c[0]), parseFloat(c[1])]; - }; - - var dist = function (c1, c2) { - if (c1 !== undefined && c2 !== undefined) { - return Math.sqrt(Math.pow( (c2[0] - c1[0]), 2 ) + Math.pow( (c2[1] - c1[1]), 2 )); - } - return 0; - }; - - if (points.length > 2) { - for (var i = 0; i < points.length - 1; i += 1) { - len += dist(coord(points[i]), coord(points[i + 1])); - } - } - len += el.tagName === 'polygon' - ? dist(coord(points[0]), coord(points[points.length - 1])) : 0; - } - return len; - } - - /** - * Returns the `` length. - * @param {SVGLineElement} el target element - * @returns {number} the element length - */ - function getLineLength(el) { - var x1 = el.getAttribute('x1'); - var x2 = el.getAttribute('x2'); - var y1 = el.getAttribute('y1'); - var y2 = el.getAttribute('y2'); - return Math.sqrt(Math.pow( (x2 - x1), 2 ) + Math.pow( (y2 - y1), 2 )); - } - - /** - * Returns the `` length. - * @param {SVGCircleElement} el target element - * @returns {number} the element length - */ - function getCircleLength(el) { - var r = el.getAttribute('r'); - return 2 * Math.PI * r; - } - - // returns the length of an ellipse - /** - * Returns the `` length. - * @param {SVGEllipseElement} el target element - * @returns {number} the element length - */ - function getEllipseLength(el) { - var rx = el.getAttribute('rx'); - var ry = el.getAttribute('ry'); - var len = 2 * rx; - var wid = 2 * ry; - return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; - } - - /** - * Returns the shape length. - * @param {SVGPathCommander.shapeTypes} el target element - * @returns {number} the element length - */ - function getTotalLength$1(el) { - if (el.tagName === 'rect') { - return getRectLength(el); - } if (el.tagName === 'circle') { - return getCircleLength(el); - } if (el.tagName === 'ellipse') { - return getEllipseLength(el); - } if (['polygon', 'polyline'].includes(el.tagName)) { - return getPolyLength(el); - } if (el.tagName === 'line') { - return getLineLength(el); - } - // ESLint - return 0; - } - - /** - * Returns the property tween object. - * @param {SVGPathCommander.shapeTypes} element the target element - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function getDraw(element, value) { - var length = /path|glyph/.test(element.tagName) - ? element.getTotalLength() - : getTotalLength$1(element); - var start; - var end; - var dasharray; - var offset; - - if (value instanceof Object && Object.keys(value).every(function (v) { return ['s', 'e', 'l'].includes(v); })) { - return value; - } if (typeof value === 'string') { - var v = value.split(/,|\s/); - start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]); - end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]); - } else if (typeof value === 'undefined') { - offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset')); - dasharray = getStyleForProperty(element, 'stroke-dasharray').split(','); - - start = 0 - offset; - end = parseFloat(dasharray[0]) + start || length; - } - return { s: start, e: end, l: length }; - } - - /** - * Reset CSS properties associated with the `draw` property. - * @param {SVGPathCommander.shapeTypes} element target - */ - function resetDraw(elem) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - elem.style.strokeDashoffset = ''; - elem.style.strokeDasharray = ''; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - } - - // Component Functions - /** - * Returns the property tween object. - * @returns {KUTE.drawObject} the property tween object - */ - function getDrawValue(/* prop, value */) { - return getDraw(this.element); - } - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function prepareDraw(_, value) { - return getDraw(this.element, value); - } - - // All Component Functions - var svgDrawFunctions = { - prepareStart: getDrawValue, - prepareProperty: prepareDraw, - onStart: onStartDraw, - }; - - // Component Full - var SvgDrawProperty = { - component: 'svgDraw', - property: 'draw', - defaultValue: '0% 0%', - Interpolate: { numbers: numbers }, - functions: svgDrawFunctions, - // Export to global for faster execution - Util: { - getRectLength: getRectLength, - getPolyLength: getPolyLength, - getLineLength: getLineLength, - getCircleLength: getCircleLength, - getEllipseLength: getEllipseLength, - getTotalLength: getTotalLength$1, - resetDraw: resetDraw, - getDraw: getDraw, - percent: percent, - }, - }; - - /** - * Splits an extended A (arc-to) segment into two cubic-bezier segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` this segment belongs to - * @param {string[]} allPathCommands all previous path commands - * @param {number} i the segment index - */ - - function fixArc(path, allPathCommands, i) { - if (path[i].length > 7) { - path[i].shift(); - var segment = path[i]; - var ni = i; // ESLint - while (segment.length) { - // if created multiple C:s, their original seg is saved - allPathCommands[i] = 'A'; - // @ts-ignore - path.splice(ni += 1, 0, ['C' ].concat( segment.splice(0, 6))); - } - path.splice(i, 1); - } - } - - /** - * Segment params length - * @type {Record} - */ - var paramsCount = { - a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0, - }; - - /** - * Breaks the parsing of a pathString once a segment is finalized. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function finalizeSegment(path) { - var pathCommand = path.pathValue[path.segmentStart]; - var LK = pathCommand.toLowerCase(); - var data = path.data; - - // Process duplicated commands (without comand name) - if (LK === 'm' && data.length > 2) { - // @ts-ignore - path.segments.push([pathCommand, data[0], data[1]]); - data = data.slice(2); - LK = 'l'; - pathCommand = pathCommand === 'm' ? 'l' : 'L'; - } - - // @ts-ignore - while (data.length >= paramsCount[LK]) { - // path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK]))); - // @ts-ignore - path.segments.push([pathCommand ].concat( data.splice(0, paramsCount[LK]))); - // @ts-ignore - if (!paramsCount[LK]) { - break; - } - } - } - - var invalidPathValue = 'Invalid path value'; - - /** - * Validates an A (arc-to) specific path command value. - * Usually a `large-arc-flag` or `sweep-flag`. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanFlag(path) { - var index = path.index; - var ch = path.pathValue.charCodeAt(index); - - if (ch === 0x30/* 0 */) { - path.param = 0; - path.index += 1; - return; - } - - if (ch === 0x31/* 1 */) { - path.param = 1; - path.index += 1; - return; - } - - path.err = invalidPathValue + ": invalid Arc flag \"" + ch + "\", expecting 0 or 1 at index " + index; - } - - /** - * Checks if a character is a digit. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isDigit(code) { - return (code >= 48 && code <= 57); // 0..9 - } - - /** - * Validates every character of the path string, - * every path command, negative numbers or floating point numbers. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanParam(path) { - var max = path.max; - var pathValue = path.pathValue; - var start = path.index; - var index = start; - var zeroFirst = false; - var hasCeiling = false; - var hasDecimal = false; - var hasDot = false; - var ch; - - if (index >= max) { - // path.err = 'SvgPath: missed param (at pos ' + index + ')'; - path.err = invalidPathValue + " at " + index + ": missing param " + (pathValue[index]); - return; - } - ch = pathValue.charCodeAt(index); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - // This logic is shamelessly borrowed from Esprima - // https://github.com/ariya/esprimas - if (!isDigit(ch) && ch !== 0x2E/* . */) { - // path.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')'; - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " is not a number"; - return; - } - - if (ch !== 0x2E/* . */) { - zeroFirst = (ch === 0x30/* 0 */); - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - - if (zeroFirst && index < max) { - // decimal number starts with '0' such as '09' is illegal. - if (ch && isDigit(ch)) { - // path.err = 'SvgPath: numbers started with `0` such as `09` - // are illegal (at pos ' + start + ')'; - path.err = invalidPathValue + " at index " + start + ": " + (pathValue[start]) + " illegal number"; - return; - } - } - - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasCeiling = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x2E/* . */) { - hasDot = true; - index += 1; - while (isDigit(pathValue.charCodeAt(index))) { - index += 1; - hasDecimal = true; - } - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - } - - if (ch === 0x65/* e */ || ch === 0x45/* E */) { - if (hasDot && !hasCeiling && !hasDecimal) { - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " invalid float exponent"; - return; - } - - index += 1; - - ch = (index < max) ? pathValue.charCodeAt(index) : 0; - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - index += 1; - } - if (index < max && isDigit(pathValue.charCodeAt(index))) { - while (index < max && isDigit(pathValue.charCodeAt(index))) { - index += 1; - } - } else { - // path.err = 'SvgPath: invalid float exponent (at pos ' + index + ')'; - path.err = invalidPathValue + " at index " + index + ": " + (pathValue[index]) + " invalid float exponent"; - return; - } - } - - path.index = index; - path.param = +path.pathValue.slice(start, index); - } - - /** - * Checks if the character is a space. - * - * @param {number} ch the character to check - * @returns {boolean} check result - */ - function isSpace(ch) { - var specialSpaces = [ - 0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, - 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF]; - return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029) // Line terminators - // White spaces - || (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) - || (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); - } - - /** - * Points the parser to the next character in the - * path string every time it encounters any kind of - * space character. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function skipSpaces(path) { - var pathValue = path.pathValue; - var max = path.max; - while (path.index < max && isSpace(pathValue.charCodeAt(path.index))) { - path.index += 1; - } - } - - /** - * Checks if the character is a path command. - * - * @param {any} code the character to check - * @returns {boolean} check result - */ - function isPathCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - switch (code | 0x20) { - case 0x6D/* m */: - case 0x7A/* z */: - case 0x6C/* l */: - case 0x68/* h */: - case 0x76/* v */: - case 0x63/* c */: - case 0x73/* s */: - case 0x71/* q */: - case 0x74/* t */: - case 0x61/* a */: - // case 0x72/* r */: - return true; - default: - return false; - } - } - - /** - * Checks if the character is or belongs to a number. - * [0-9]|+|-|. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isDigitStart(code) { - return (code >= 48 && code <= 57) /* 0..9 */ - || code === 0x2B /* + */ - || code === 0x2D /* - */ - || code === 0x2E; /* . */ - } - - /** - * Checks if the character is an A (arc-to) path command. - * - * @param {number} code the character to check - * @returns {boolean} check result - */ - function isArcCommand(code) { - // eslint-disable-next-line no-bitwise -- Impossible to satisfy - return (code | 0x20) === 0x61; - } - - /** - * Scans every character in the path string to determine - * where a segment starts and where it ends. - * - * @param {SVGPathCommander.PathParser} path the `PathParser` instance - */ - function scanSegment(path) { - var max = path.max; - var pathValue = path.pathValue; - var index = path.index; - var cmdCode = pathValue.charCodeAt(index); - var reqParams = paramsCount[pathValue[index].toLowerCase()]; - - path.segmentStart = index; - - if (!isPathCommand(cmdCode)) { - path.err = invalidPathValue + ": " + (pathValue[index]) + " not a path command"; - return; - } - - path.index += 1; - skipSpaces(path); - - path.data = []; - - if (!reqParams) { - // Z - finalizeSegment(path); - return; - } - - for (;;) { - for (var i = reqParams; i > 0; i -= 1) { - if (isArcCommand(cmdCode) && (i === 3 || i === 4)) { scanFlag(path); } - else { scanParam(path); } - - if (path.err.length) { - return; - } - path.data.push(path.param); - - skipSpaces(path); - - // after ',' param is mandatory - if (path.index < max && pathValue.charCodeAt(path.index) === 0x2C/* , */) { - path.index += 1; - skipSpaces(path); - } - } - - if (path.index >= path.max) { - break; - } - - // Stop on next segment - if (!isDigitStart(pathValue.charCodeAt(path.index))) { - break; - } - } - - finalizeSegment(path); - } - - /** - * Returns a clone of an existing `pathArray`. - * - * @param {SVGPathCommander.pathArray | SVGPathCommander.pathSegment} path the source `pathArray` - * @returns {any} the cloned `pathArray` - */ - function clonePath(path) { - return path.map(function (x) { return (Array.isArray(x) ? [].concat( x ) : x); }); - } - - /** - * The `PathParser` is used by the `parsePathString` static method - * to generate a `pathArray`. - * - * @param {string} pathString - */ - function PathParser(pathString) { - /** @type {SVGPathCommander.pathArray} */ - // @ts-ignore - this.segments = []; - /** @type {string} */ - this.pathValue = pathString; - /** @type {number} */ - this.max = pathString.length; - /** @type {number} */ - this.index = 0; - /** @type {number} */ - this.param = 0.0; - /** @type {number} */ - this.segmentStart = 0; - /** @type {any} */ - this.data = []; - /** @type {string} */ - this.err = ''; - } - - /** - * Iterates an array to check if it's an actual `pathArray`. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isPathArray(path) { - return Array.isArray(path) && path.every(function (seg) { - var lk = seg[0].toLowerCase(); - return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk); - }); - } - - /** - * Parses a path string value and returns an array - * of segments we like to call `pathArray`. - * - * @param {SVGPathCommander.pathArray | string} pathInput the string to be parsed - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` - */ - function parsePathString(pathInput) { - if (isPathArray(pathInput)) { - // @ts-ignore -- isPathArray also checks if it's an `Array` - return clonePath(pathInput); - } - - // @ts-ignore -- pathInput is now string - var path = new PathParser(pathInput); - - skipSpaces(path); - - while (path.index < path.max && !path.err.length) { - scanSegment(path); - } - - if (path.err.length) { - // @ts-ignore - path.segments = []; - } else if (path.segments.length) { - if (!'mM'.includes(path.segments[0][0])) { - path.err = invalidPathValue + ": missing M/m"; - // @ts-ignore - path.segments = []; - } else { - path.segments[0][0] = 'M'; - } - } - - return path.segments; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isAbsoluteArray(path) { - return isPathArray(path) - // @ts-ignore -- `isPathArray` also checks if it's `Array` - && path.every(function (x) { return x[0] === x[0].toUpperCase(); }); - } - - /** - * Parses a path string value or object and returns an array - * of segments, all converted to absolute values. - * - * @param {string | SVGPathCommander.pathArray} pathInput the path string | object - * @returns {SVGPathCommander.absoluteArray} the resulted `pathArray` with absolute values - */ - function pathToAbsolute(pathInput) { - if (isAbsoluteArray(pathInput)) { - // @ts-ignore -- `isAbsoluteArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - var path = parsePathString(pathInput); - var x = 0; var y = 0; - var mx = 0; var my = 0; - - // @ts-ignore -- the `absoluteSegment[]` is for sure an `absolutePath` - return path.map(function (segment) { - var assign, assign$1, assign$2; - - var values = segment.slice(1).map(Number); - var pathCommand = segment[0]; - /** @type {SVGPathCommander.absoluteCommand} */ - // @ts-ignore - var absCommand = pathCommand.toUpperCase(); - - if (pathCommand === 'M') { - (assign = values, x = assign[0], y = assign[1]); - mx = x; - my = y; - return ['M', x, y]; - } - /** @type {SVGPathCommander.absoluteSegment} */ - // @ts-ignore - var absoluteSegment = []; - - if (pathCommand !== absCommand) { - switch (absCommand) { - case 'A': - absoluteSegment = [ - absCommand, values[0], values[1], values[2], - values[3], values[4], values[5] + x, values[6] + y]; - break; - case 'V': - absoluteSegment = [absCommand, values[0] + y]; - break; - case 'H': - absoluteSegment = [absCommand, values[0] + x]; - break; - default: { - // use brakets for `eslint: no-case-declaration` - // https://stackoverflow.com/a/50753272/803358 - var absValues = values.map(function (n, j) { return n + (j % 2 ? y : x); }); - // @ts-ignore for n, l, c, s, q, t - absoluteSegment = [absCommand ].concat( absValues); - } - } - } else { - // @ts-ignore - absoluteSegment = [absCommand ].concat( values); - } - - var segLength = absoluteSegment.length; - switch (absCommand) { - case 'Z': - x = mx; - y = my; - break; - case 'H': - // @ts-ignore - (assign$1 = absoluteSegment, x = assign$1[1]); - break; - case 'V': - // @ts-ignore - (assign$2 = absoluteSegment, y = assign$2[1]); - break; - default: - // @ts-ignore - x = absoluteSegment[segLength - 2]; - // @ts-ignore - y = absoluteSegment[segLength - 1]; - - if (absCommand === 'M') { - mx = x; - my = y; - } - } - return absoluteSegment; - }); - } - - /** - * Returns the missing control point from an - * T (shorthand quadratic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {string} prevCommand the previous path command - * @returns {{qx: number, qy: number}}} the missing control point - */ - function shorthandToQuad(x1, y1, qx, qy, prevCommand) { - return 'QT'.includes(prevCommand) - ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy } - : { qx: x1, qy: y1 }; - } - - /** - * Returns the missing control point from an - * S (shorthand cubic bezier) segment. - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @param {string} prevCommand the previous path command - * @returns {{x1: number, y1: number}}} the missing control point - */ - function shorthandToCubic(x1, y1, x2, y2, prevCommand) { - return 'CS'.includes(prevCommand) - ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2 } - : { x1: x1, y1: y1 }; - } - - /** - * Normalizes a single segment of a `pathArray` object. - * - * @param {SVGPathCommander.pathSegment} segment the segment object - * @param {any} params the coordinates of the previous segment - * @param {string} prevCommand the path command of the previous segment - * @returns {SVGPathCommander.normalSegment} the normalized segment - */ - function normalizeSegment(segment, params, prevCommand) { - var pathCommand = segment[0]; - var px1 = params.x1; - var py1 = params.y1; - var px2 = params.x2; - var py2 = params.y2; - var values = segment.slice(1).map(Number); - var result = segment; - - if (!'TQ'.includes(pathCommand)) { - // optional but good to be cautious - params.qx = null; - params.qy = null; - } - - if (pathCommand === 'H') { - result = ['L', segment[1], py1]; - } else if (pathCommand === 'V') { - result = ['L', px1, segment[1]]; - } else if (pathCommand === 'S') { - var ref = shorthandToCubic(px1, py1, px2, py2, prevCommand); - var x1 = ref.x1; - var y1 = ref.y1; - params.x1 = x1; - params.y1 = y1; - // @ts-ignore - result = ['C', x1, y1 ].concat( values); - } else if (pathCommand === 'T') { - var ref$1 = shorthandToQuad(px1, py1, params.qx, params.qy, prevCommand); - var qx = ref$1.qx; - var qy = ref$1.qy; - params.qx = qx; - params.qy = qy; - // @ts-ignore - result = ['Q', qx, qy ].concat( values); - } else if (pathCommand === 'Q') { - var nqx = values[0]; - var nqy = values[1]; - params.qx = nqx; - params.qy = nqy; - } - - // @ts-ignore -- we-re switching `pathSegment` type - return result; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all segments are in non-shorthand notation - * with absolute values. - * - * @param {string | SVGPathCommander.pathArray} path the `pathArray` to be checked - * @returns {boolean} iteration result - */ - function isNormalizedArray(path) { - // @ts-ignore -- `isAbsoluteArray` also checks if it's `Array` - return isAbsoluteArray(path) && path.every(function (seg) { return 'ACLMQZ'.includes(seg[0]); }); - } - - /** - * @type {SVGPathCommander.parserParams} - */ - var paramsParser = { - x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null, - }; - - /** - * Normalizes a `path` object for further processing: - * * convert segments to absolute values - * * convert shorthand path commands to their non-shorthand notation - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.normalArray} the normalized `pathArray` - */ - function normalizePath(pathInput) { - var assign; - - if (isNormalizedArray(pathInput)) { - // @ts-ignore -- `isNormalizedArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - /** @type {SVGPathCommander.normalArray} */ - // @ts-ignore -- `absoluteArray` will become a `normalArray` - var path = pathToAbsolute(pathInput); - var params = Object.assign({}, paramsParser); - var allPathCommands = []; - var ii = path.length; - var pathCommand = ''; - var prevCommand = ''; - - for (var i = 0; i < ii; i += 1) { - (assign = path[i], pathCommand = assign[0]); - - // Save current path command - allPathCommands[i] = pathCommand; - // Get previous path command - if (i) { prevCommand = allPathCommands[i - 1]; } - // Previous path command is used to normalizeSegment - // @ts-ignore -- expected on normalization - path[i] = normalizeSegment(path[i], params, prevCommand); - - var segment = path[i]; - var seglen = segment.length; - - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - return path; - } - - /** - * Checks a `pathArray` for an unnecessary `Z` segment - * and returns a new `pathArray` without it. - * - * The `pathInput` must be a single path, without - * sub-paths. For multi-path `` elements, - * use `splitPath` first and apply this utility on each - * sub-path separately. - * - * @param {SVGPathCommander.pathArray | string} pathInput the `pathArray` source - * @return {SVGPathCommander.pathArray} a fixed `pathArray` - */ - function fixPath(pathInput) { - var pathArray = parsePathString(pathInput); - var normalArray = normalizePath(pathArray); - var length = pathArray.length; - var isClosed = normalArray.slice(-1)[0][0] === 'Z'; - var segBeforeZ = isClosed ? length - 2 : length - 1; - - var ref = normalArray[0].slice(1); - var mx = ref[0]; - var my = ref[1]; - var ref$1 = normalArray[segBeforeZ].slice(-2); - var x = ref$1[0]; - var y = ref$1[1]; - - if (isClosed && mx === x && my === y) { - // @ts-ignore -- `pathSegment[]` is quite a `pathArray` - return pathArray.slice(0, -1); - } - return pathArray; - } - - /** - * Iterates an array to check if it's a `pathArray` - * with all C (cubic bezier) segments. - * - * @param {string | SVGPathCommander.pathArray} path the `Array` to be checked - * @returns {boolean} iteration result - */ - function isCurveArray(path) { - // @ts-ignore -- `isPathArray` also checks if it's `Array` - return isPathArray(path) && path.every(function (seg) { return 'MC'.includes(seg[0]); }); - } - - /** - * Returns an {x,y} vector rotated by a given - * angle in radian. - * - * @param {number} x the initial vector x - * @param {number} y the initial vector y - * @param {number} rad the radian vector angle - * @returns {{x: number, y: number}} the rotated vector - */ - function rotateVector(x, y, rad) { - var X = x * Math.cos(rad) - y * Math.sin(rad); - var Y = x * Math.sin(rad) + y * Math.cos(rad); - return { x: X, y: Y }; - } - - /** - * Converts A (arc-to) segments to C (cubic-bezier-to). - * - * For more information of where this math came from visit: - * http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - * - * @param {number} X1 the starting x position - * @param {number} Y1 the starting y position - * @param {number} RX x-radius of the arc - * @param {number} RY y-radius of the arc - * @param {number} angle x-axis-rotation of the arc - * @param {number} LAF large-arc-flag of the arc - * @param {number} SF sweep-flag of the arc - * @param {number} X2 the ending x position - * @param {number} Y2 the ending y position - * @param {number[]=} recursive the parameters needed to split arc into 2 segments - * @return {number[]} the resulting cubic-bezier segment(s) - */ - function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) { - var assign; - - var x1 = X1; var y1 = Y1; var rx = RX; var ry = RY; var x2 = X2; var y2 = Y2; - // for more information of where this Math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - var d120 = (Math.PI * 120) / 180; - - var rad = (Math.PI / 180) * (+angle || 0); - /** @type {number[]} */ - var res = []; - var xy; - var f1; - var f2; - var cx; - var cy; - - if (!recursive) { - xy = rotateVector(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotateVector(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - - var x = (x1 - x2) / 2; - var y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = Math.sqrt(h); - rx *= h; - ry *= h; - } - var rx2 = rx * rx; - var ry2 = ry * ry; - - var k = (LAF === SF ? -1 : 1) - * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) - / (rx2 * y * y + ry2 * x * x))); - - cx = ((k * rx * y) / ry) + ((x1 + x2) / 2); - cy = ((k * -ry * x) / rx) + ((y1 + y2) / 2); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f1 = (Math.asin((((y1 - cy) / ry))) * (Math.pow( 10, 9 )) >> 0) / (Math.pow( 10, 9 )); - // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise - f2 = (Math.asin((((y2 - cy) / ry))) * (Math.pow( 10, 9 )) >> 0) / (Math.pow( 10, 9 )); - - f1 = x1 < cx ? Math.PI - f1 : f1; - f2 = x2 < cx ? Math.PI - f2 : f2; - if (f1 < 0) { (f1 = Math.PI * 2 + f1); } - if (f2 < 0) { (f2 = Math.PI * 2 + f2); } - if (SF && f1 > f2) { - f1 -= Math.PI * 2; - } - if (!SF && f2 > f1) { - f2 -= Math.PI * 2; - } - } else { - (assign = recursive, f1 = assign[0], f2 = assign[1], cx = assign[2], cy = assign[3]); - } - var df = f2 - f1; - if (Math.abs(df) > d120) { - var f2old = f2; - var x2old = x2; - var y2old = y2; - f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1); - x2 = cx + rx * Math.cos(f2); - y2 = cy + ry * Math.sin(f2); - res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - var c1 = Math.cos(f1); - var s1 = Math.sin(f1); - var c2 = Math.cos(f2); - var s2 = Math.sin(f2); - var t = Math.tan(df / 4); - var hx = (4 / 3) * rx * t; - var hy = (4 / 3) * ry * t; - var m1 = [x1, y1]; - var m2 = [x1 + hx * s1, y1 - hy * c1]; - var m3 = [x2 + hx * s2, y2 - hy * c2]; - var m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return m2.concat( m3, m4, res); - } - res = m2.concat( m3, m4, res); - var newres = []; - for (var i = 0, ii = res.length; i < ii; i += 1) { - newres[i] = i % 2 - ? rotateVector(res[i - 1], res[i], rad).y - : rotateVector(res[i], res[i + 1], rad).x; - } - return newres; - } - - /** - * Converts a Q (quadratic-bezier) segment to C (cubic-bezier). - * - * @param {number} x1 curve start x - * @param {number} y1 curve start y - * @param {number} qx control point x - * @param {number} qy control point y - * @param {number} x2 curve end x - * @param {number} y2 curve end y - * @returns {number[]} the cubic-bezier segment - */ - function quadToCubic(x1, y1, qx, qy, x2, y2) { - var r13 = 1 / 3; - var r23 = 2 / 3; - return [ - r13 * x1 + r23 * qx, // cpx1 - r13 * y1 + r23 * qy, // cpy1 - r13 * x2 + r23 * qx, // cpx2 - r13 * y2 + r23 * qy, // cpy2 - x2, y2 ]; - } - - /** - * Returns the coordinates of a specified distance - * ratio between two points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @param {number} t the ratio - * @returns {[number, number]} the midpoint coordinates - */ - function midPoint(a, b, t) { - var ax = a[0]; - var ay = a[1]; var bx = b[0]; - var by = b[1]; - return [ax + (bx - ax) * t, ay + (by - ay) * t]; - } - - /** - * Returns the square root of the distance - * between two given points. - * - * @param {[number, number]} a the first point coordinates - * @param {[number, number]} b the second point coordinates - * @returns {number} the distance value - */ - function distanceSquareRoot(a, b) { - return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) - + (a[1] - b[1]) * (a[1] - b[1]) - ); - } - - /** - * Returns the length of a line (L,V,H,Z) segment, - * or a point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the distance to point - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentLineFactory(x1, y1, x2, y2, distance) { - var length = distanceSquareRoot([x1, y1], [x2, y2]); - var margin = 0.001; - - if (typeof distance === 'number') { - if (distance < margin) { - return { x: x1, y: y1 }; - } - if (distance > length + margin) { - return { x: x2, y: y2 }; - } - var ref = midPoint([x1, y1], [x2, y2], distance / length); - var x = ref[0]; - var y = ref[1]; - return { x: x, y: y }; - } - return length; - } - - /** - * Converts an L (line-to) segment to C (cubic-bezier). - * - * @param {number} x1 line start x - * @param {number} y1 line start y - * @param {number} x2 line end x - * @param {number} y2 line end y - * @returns {number[]} the cubic-bezier segment - */ - function lineToCubic(x1, y1, x2, y2) { - var t = 0.5; - /** @type {[number, number]} */ - var p0 = [x1, y1]; - /** @type {[number, number]} */ - var p1 = [x2, y2]; - var p2 = midPoint(p0, p1, t); - var p3 = midPoint(p1, p2, t); - var p4 = midPoint(p2, p3, t); - var p5 = midPoint(p3, p4, t); - var p6 = midPoint(p4, p5, t); - var seg1 = p0.concat( p2, p4, p6, [t]); - // @ts-ignore - var cp1 = segmentLineFactory.apply(void 0, seg1); - var seg2 = p6.concat( p5, p3, p1, [0]); - // @ts-ignore - var cp2 = segmentLineFactory.apply(void 0, seg2); - - // @ts-ignore - return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2]; - } - - /** - * Converts any segment to C (cubic-bezier). - * - * @param {SVGPathCommander.pathSegment} segment the source segment - * @param {SVGPathCommander.parserParams} params the source segment parameters - * @returns {SVGPathCommander.cubicSegment | SVGPathCommander.MSegment} the cubic-bezier segment - */ - function segmentToCubic(segment, params) { - var pathCommand = segment[0]; - var values = segment.slice(1).map(function (n) { return +n; }); - var x = values[0]; - var y = values[1]; - var args; - var px1 = params.x1; - var py1 = params.y1; - var px = params.x; - var py = params.y; - - if (!'TQ'.includes(pathCommand)) { - params.qx = null; - params.qy = null; - } - - switch (pathCommand) { - case 'M': - params.x = x; - params.y = y; - return segment; - case 'A': - args = [px1, py1 ].concat( values); - // @ts-ignore -- relax, the utility will return 6 numbers - return ['C' ].concat( arcToCubic.apply(void 0, args)); - case 'Q': - params.qx = x; - params.qy = y; - args = [px1, py1 ].concat( values); - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( quadToCubic.apply(void 0, args)); - case 'L': - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( lineToCubic(px1, py1, x, y)); - case 'Z': - // @ts-ignore -- also returning 6 numbers - return ['C' ].concat( lineToCubic(px1, py1, px, py)); - } - // @ts-ignore -- we're switching `pathSegment` type - return segment; - } - - /** - * Parses a path string value or 'pathArray' and returns a new one - * in which all segments are converted to cubic-bezier. - * - * In addition, un-necessary `Z` segment is removed if previous segment - * extends to the `M` segment. - * - * @param {string | SVGPathCommander.pathArray} pathInput the string to be parsed or 'pathArray' - * @returns {SVGPathCommander.curveArray} the resulted `pathArray` converted to cubic-bezier - */ - function pathToCurve(pathInput) { - var assign; - - if (isCurveArray(pathInput)) { - // @ts-ignore -- `isCurveArray` checks if it's `pathArray` - return clonePath(pathInput); - } - - var path = fixPath(normalizePath(pathInput)); - var params = Object.assign({}, paramsParser); - var allPathCommands = []; - var pathCommand = ''; // ts-lint - var ii = path.length; - - for (var i = 0; i < ii; i += 1) { - (assign = path[i], pathCommand = assign[0]); - allPathCommands[i] = pathCommand; - - path[i] = segmentToCubic(path[i], params); - - fixArc(path, allPathCommands, i); - ii = path.length; - - var segment = path[i]; - var seglen = segment.length; - params.x1 = +segment[seglen - 2]; - params.y1 = +segment[seglen - 1]; - params.x2 = +(segment[seglen - 4]) || params.x1; - params.y2 = +(segment[seglen - 3]) || params.y1; - } - - // @ts-ignore - return path; - } - - /** - * SVGPathCommander default options - * @type {SVGPathCommander.options} - */ - var defaultOptions = { - origin: [0, 0, 0], - round: 4, - }; - - /** - * Rounds the values of a `pathArray` instance to - * a specified amount of decimals and returns it. - * - * @param {SVGPathCommander.pathArray} path the source `pathArray` - * @param {number | boolean} roundOption the amount of decimals to round numbers to - * @returns {SVGPathCommander.pathArray} the resulted `pathArray` with rounded values - */ - function roundPath(path, roundOption) { - var round = defaultOptions.round; - if (roundOption === false || round === false) { return clonePath(path); } - round = roundOption >= 1 ? roundOption : round; - // to round values to the power - // the `round` value must be integer - // @ts-ignore - var pow = round >= 1 ? (Math.pow( 10, round )) : 1; - - // @ts-ignore -- `pathSegment[]` is `pathArray` - return path.map(function (pi) { - var values = pi.slice(1).map(Number) - .map(function (n) { return (n % 1 === 0 ? n : Math.round(n * pow) / pow); }); - return [pi[0] ].concat( values); - }); - } - - /** - * Returns a valid `d` attribute string value created - * by rounding values and concatenating the `pathArray` segments. - * - * @param {SVGPathCommander.pathArray} path the `pathArray` object - * @param {any} round amount of decimals to round values to - * @returns {string} the concatenated path string - */ - function pathToString(path, round) { - return roundPath(path, round) - .map(function (x) { return x[0] + x.slice(1).join(' '); }).join(''); - } - - /** - * Split a path into an `Array` of sub-path strings. - * - * In the process, values are converted to absolute - * for visual consistency. - * - * @param {SVGPathCommander.pathArray | string} pathInput the source `pathArray` - * @return {string[]} an array with all sub-path strings - */ - function splitPath(pathInput) { - return pathToString(pathToAbsolute(pathInput), 0) - .replace(/(m|M)/g, '|$1') - .split('|') - .map(function (s) { return s.trim(); }) - .filter(function (s) { return s; }); - } - - /** - * Returns a point at a given length of a C (cubic-bezier) segment. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number} t a [0-1] ratio - * @returns {{x: number, y: number}} the cubic-bezier segment length - */ - function getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t) { - var t1 = 1 - t; - return { - x: (Math.pow( t1, 3 )) * x1 - + 3 * (Math.pow( t1, 2 )) * t * c1x - + 3 * t1 * (Math.pow( t, 2 )) * c2x - + (Math.pow( t, 3 )) * x2, - y: (Math.pow( t1, 3 )) * y1 - + 3 * (Math.pow( t1, 2 )) * t * c1y - + 3 * t1 * (Math.pow( t, 2 )) * c2y - + (Math.pow( t, 3 )) * y2, - }; - } - - /** - * Returns the length of a C (cubic-bezier) segment, - * or an {x,y} point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} c1x the first control point X - * @param {number} c1y the first control point Y - * @param {number} c2x the second control point X - * @param {number} c2y the second control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the point distance - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentCubicFactory(x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance) { - var assign; - - var x = x1; var y = y1; - var lengthMargin = 0.001; - var totalLength = 0; - var prev = [x1, y1, totalLength]; - /** @type {[number, number]} */ - var cur = [x1, y1]; - var t = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x: x, y: y }; - } - - var n = 100; - for (var j = 0; j <= n; j += 1) { - t = j / n; - - ((assign = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t), x = assign.x, y = assign.y)); - totalLength += distanceSquareRoot(cur, [x, y]); - cur = [x, y]; - - if (typeof distance === 'number' && totalLength >= distance) { - var dv = (totalLength - distance) / (totalLength - prev[2]); - - return { - x: cur[0] * (1 - dv) + prev[0] * dv, - y: cur[1] * (1 - dv) + prev[1] * dv, - }; - } - prev = [x, y, totalLength]; - } - - if (typeof distance === 'number' && distance >= totalLength) { - return { x: x2, y: y2 }; - } - return totalLength; - } - - /** - * Returns the length of a A (arc-to) segment, - * or an {x,y} point at a given length. - * - * @param {number} X1 the starting x position - * @param {number} Y1 the starting y position - * @param {number} RX x-radius of the arc - * @param {number} RY y-radius of the arc - * @param {number} angle x-axis-rotation of the arc - * @param {number} LAF large-arc-flag of the arc - * @param {number} SF sweep-flag of the arc - * @param {number} X2 the ending x position - * @param {number} Y2 the ending y position - * @param {number} distance the point distance - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentArcFactory(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, distance) { - var assign; - - var ref = [X1, Y1]; - var x = ref[0]; - var y = ref[1]; - var cubicSeg = arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2); - var lengthMargin = 0.001; - var totalLength = 0; - var cubicSubseg = []; - var argsc = []; - var segLen = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x: x, y: y }; - } - - for (var i = 0, ii = cubicSeg.length; i < ii; i += 6) { - cubicSubseg = cubicSeg.slice(i, i + 6); - argsc = [x, y ].concat( cubicSubseg); - // @ts-ignore - segLen = segmentCubicFactory.apply(void 0, argsc); - if (typeof distance === 'number' && totalLength + segLen >= distance) { - // @ts-ignore -- this is a `cubicSegment` - return segmentCubicFactory.apply(void 0, argsc.concat( [distance - totalLength] )); - } - totalLength += segLen; - (assign = cubicSubseg.slice(-2), x = assign[0], y = assign[1]); - } - - if (typeof distance === 'number' && distance >= totalLength) { - return { x: X2, y: Y2 }; - } - - return totalLength; - } - - /** - * Returns the {x,y} coordinates of a point at a - * given length of a quad-bezier segment. - * - * @see https://github.com/substack/point-at-length - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} cx the control point X - * @param {number} cy the control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number} t a [0-1] ratio - * @returns {{x: number, y: number}} the requested {x,y} coordinates - */ - function getPointAtQuadSegmentLength(x1, y1, cx, cy, x2, y2, t) { - var t1 = 1 - t; - return { - x: (Math.pow( t1, 2 )) * x1 - + 2 * t1 * t * cx - + (Math.pow( t, 2 )) * x2, - y: (Math.pow( t1, 2 )) * y1 - + 2 * t1 * t * cy - + (Math.pow( t, 2 )) * y2, - }; - } - - /** - * Returns the Q (quadratic-bezier) segment length, - * or an {x,y} point at a given length. - * - * @param {number} x1 the starting point X - * @param {number} y1 the starting point Y - * @param {number} qx the control point X - * @param {number} qy the control point Y - * @param {number} x2 the ending point X - * @param {number} y2 the ending point Y - * @param {number=} distance the distance to point - * @returns {{x: number, y: number} | number} the segment length or point - */ - function segmentQuadFactory(x1, y1, qx, qy, x2, y2, distance) { - var assign; - - var x = x1; var y = y1; - var lengthMargin = 0.001; - var totalLength = 0; - var prev = [x1, y1, totalLength]; - /** @type {[number, number]} */ - var cur = [x1, y1]; - var t = 0; - - if (typeof distance === 'number' && distance < lengthMargin) { - return { x: x, y: y }; - } - - var n = 100; - for (var j = 0; j <= n; j += 1) { - t = j / n; - - ((assign = getPointAtQuadSegmentLength(x1, y1, qx, qy, x2, y2, t), x = assign.x, y = assign.y)); - totalLength += distanceSquareRoot(cur, [x, y]); - cur = [x, y]; - - if (typeof distance === 'number' && totalLength >= distance) { - var dv = (totalLength - distance) / (totalLength - prev[2]); - - return { - x: cur[0] * (1 - dv) + prev[0] * dv, - y: cur[1] * (1 - dv) + prev[1] * dv, - }; - } - prev = [x, y, totalLength]; - } - if (typeof distance === 'number' && distance >= totalLength) { - return { x: x2, y: y2 }; - } - return totalLength; - } - - /** - * Returns a {x,y} point at a given length of a shape or the shape total length. - * - * @param {string | SVGPathCommander.pathArray} pathInput the `pathArray` to look into - * @param {number=} distance the length of the shape to look at - * @returns {{x: number, y: number} | number} the total length or point - */ - function pathLengthFactory(pathInput, distance) { - var assign, assign$1, assign$2; - - var totalLength = 0; - var isM = true; - /** @type {number[]} */ - var data = []; - var pathCommand = 'M'; - var segLen = 0; - var x = 0; - var y = 0; - var mx = 0; - var my = 0; - var seg; - var path = fixPath(normalizePath(pathInput)); - - for (var i = 0, ll = path.length; i < ll; i += 1) { - seg = path[i]; - (assign = seg, pathCommand = assign[0]); - isM = pathCommand === 'M'; - // @ts-ignore - data = !isM ? [x, y ].concat( seg.slice(1)) : data; - - // this segment is always ZERO - if (isM) { - // remember mx, my for Z - // @ts-ignore - (assign$1 = seg, mx = assign$1[1], my = assign$1[2]); - if (typeof distance === 'number' && distance < 0.001) { - return { x: mx, y: my }; - } - } else if (pathCommand === 'L') { - // @ts-ignore - segLen = segmentLineFactory.apply(void 0, data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentLineFactory.apply(void 0, data.concat( [distance - totalLength] )); - } - totalLength += segLen; - } else if (pathCommand === 'A') { - // @ts-ignore - segLen = segmentArcFactory.apply(void 0, data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentArcFactory.apply(void 0, data.concat( [distance - totalLength] )); - } - totalLength += segLen; - } else if (pathCommand === 'C') { - // @ts-ignore - segLen = segmentCubicFactory.apply(void 0, data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentCubicFactory.apply(void 0, data.concat( [distance - totalLength] )); - } - totalLength += segLen; - } else if (pathCommand === 'Q') { - // @ts-ignore - segLen = segmentQuadFactory.apply(void 0, data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentQuadFactory.apply(void 0, data.concat( [distance - totalLength] )); - } - totalLength += segLen; - } else if (pathCommand === 'Z') { - data = [x, y, mx, my]; - // @ts-ignore - segLen = segmentLineFactory.apply(void 0, data); - if (distance && totalLength + segLen >= distance) { - // @ts-ignore - return segmentLineFactory.apply(void 0, data.concat( [distance - totalLength] )); - } - totalLength += segLen; - } - - // @ts-ignore -- needed for the below - (assign$2 = pathCommand !== 'Z' ? seg.slice(-2) : [mx, my], x = assign$2[0], y = assign$2[1]); - } - - // native `getPointAtLength` behavior when the given distance - // is higher than total length - if (distance && distance >= totalLength) { - return { x: x, y: y }; - } - - return totalLength; - } - - /** - * Returns the shape total length, or the equivalent to `shape.getTotalLength()`. - * - * The `normalizePath` version is lighter, faster, more efficient and more accurate - * with paths that are not `curveArray`. - * - * @param {string | SVGPathCommander.pathArray} pathInput the target `pathArray` - * @returns {number} the shape total length - */ - function getTotalLength(pathInput) { - // @ts-ignore - it's fine - return pathLengthFactory(pathInput); - } - - /** - * Returns [x,y] coordinates of a point at a given length of a shape. - * - * @param {string | SVGPathCommander.pathArray} pathInput the `pathArray` to look into - * @param {number} distance the length of the shape to look at - * @returns {{x: number, y: number}} the requested {x, y} point coordinates - */ - function getPointAtLength(pathInput, distance) { - // @ts-ignore - return pathLengthFactory(pathInput, distance); - } - - /** - * d3-polygon-area - * https://github.com/d3/d3-polygon - * - * Returns the area of a polygon. - * - * @param {number[][]} polygon an array of coordinates - * @returns {number} the polygon area - */ - function polygonArea(polygon) { - var n = polygon.length; - var i = -1; - var a; - var b = polygon[n - 1]; - var area = 0; - - /* eslint-disable-next-line */ - while (++i < n) { - a = b; - b = polygon[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - - return area / 2; - } - - /** - * d3-polygon-length - * https://github.com/d3/d3-polygon - * - * Returns the perimeter of a polygon. - * - * @param {number[][]} polygon an array of coordinates - * @returns {number} the polygon length - */ - function polygonLength(polygon) { - return polygon.reduce(function (length, point, i) { - if (i) { - // @ts-ignore - return length + distanceSquareRoot(polygon[i - 1], point); - } - return 0; - }, 0); - } - - /** - * A global namespace for epsilon. - * - * @type {number} - */ - var epsilon = 1e-9; - - /** - * Coordinates Interpolation Function. - * - * @param {number[][]} a start coordinates - * @param {number[][]} b end coordinates - * @param {string} l amount of coordinates - * @param {number} v progress - * @returns {number[][]} the interpolated coordinates - */ - function coords(a, b, l, v) { - var points = []; - for (var i = 0; i < l; i += 1) { // for each point - points[i] = []; - for (var j = 0; j < 2; j += 1) { // each point coordinate - // eslint-disable-next-line no-bitwise - points[i].push(((a[i][j] + (b[i][j] - a[i][j]) * v) * 1000 >> 0) / 1000); - } - } - return points; - } - - /* SVGMorph = { - property: 'path', - defaultValue: [], - interpolators: {numbers,coords} }, - functions = { prepareStart, prepareProperty, onStart, crossCheck } - } */ - - // Component functions - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function onStartSVGMorph(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function (elem, a, b, v) { - var path1 = a.polygon; var path2 = b.polygon; - var len = path2.length; - elem.setAttribute('d', (v === 1 ? b.original : ("M" + (coords(path1, path2, len, v).join('L')) + "Z"))); - }; - } - } - - // Component Util - // original script flubber - // https://github.com/veltman/flubber - - /** - * Returns an existing polygon or false if it's not a polygon. - * @param {SVGPathCommander.pathArray} pathArray target `pathArray` - * @returns {KUTE.exactPolygon | false} the resulted polygon - */ - function exactPolygon(pathArray) { - var assign; - - var polygon = []; - var pathlen = pathArray.length; - var segment = []; - var pathCommand = ''; - - if (!pathArray.length || pathArray[0][0] !== 'M') { - return false; - } - - for (var i = 0; i < pathlen; i += 1) { - segment = pathArray[i]; - (assign = segment, pathCommand = assign[0]); - - if ((pathCommand === 'M' && i) || pathCommand === 'Z') { - break; // !! - } else if ('ML'.includes(pathCommand)) { - polygon.push([segment[1], segment[2]]); - } else { - return false; - } - } - - return pathlen ? { polygon: polygon } : false; - } - - /** - * Returns a new polygon polygon. - * @param {SVGPathCommander.pathArray} parsed target `pathArray` - * @param {number} maxLength the maximum segment length - * @returns {KUTE.exactPolygon} the resulted polygon - */ - function approximatePolygon(parsed, maxLength) { - var ringPath = splitPath(pathToString(parsed))[0]; - var normalPath = normalizePath(ringPath); - var pathLength = getTotalLength(normalPath); - var polygon = []; - var numPoints = 3; - var point; - - if (maxLength && !Number.isNaN(maxLength) && +maxLength > 0) { - numPoints = Math.max(numPoints, Math.ceil(pathLength / maxLength)); - } - - for (var i = 0; i < numPoints; i += 1) { - point = getPointAtLength(normalPath, (pathLength * i) / numPoints); - polygon.push([point.x, point.y]); - } - - // Make all rings clockwise - if (polygonArea(polygon) > 0) { - polygon.reverse(); - } - - return { - polygon: polygon, - skipBisect: true, - }; - } - - /** - * Parses a path string and returns a polygon array. - * @param {string} str path string - * @param {number} maxLength maximum amount of points - * @returns {KUTE.exactPolygon} the polygon array we need - */ - function pathStringToPolygon(str, maxLength) { - var parsed = normalizePath(str); - return exactPolygon(parsed) || approximatePolygon(parsed, maxLength); - } - - /** - * Rotates a polygon to better match its pair. - * @param {KUTE.polygonMorph} polygon the target polygon - * @param {KUTE.polygonMorph} vs the reference polygon - */ - function rotatePolygon(polygon, vs) { - var len = polygon.length; - var min = Infinity; - var bestOffset; - var sumOfSquares = 0; - var spliced; - var d; - var p; - - for (var offset = 0; offset < len; offset += 1) { - sumOfSquares = 0; - - for (var i = 0; i < vs.length; i += 1) { - p = vs[i]; - d = distanceSquareRoot(polygon[(offset + i) % len], p); - sumOfSquares += d * d; - } - - if (sumOfSquares < min) { - min = sumOfSquares; - bestOffset = offset; - } - } - - if (bestOffset) { - spliced = polygon.splice(0, bestOffset); - polygon.splice.apply(polygon, [ polygon.length, 0 ].concat( spliced )); - } - } - - /** - * Sample additional points for a polygon to better match its pair. - * @param {KUTE.polygonObject} polygon the target polygon - * @param {number} numPoints the amount of points needed - */ - function addPoints(polygon, numPoints) { - var desiredLength = polygon.length + numPoints; - var step = polygonLength(polygon) / numPoints; - - var i = 0; - var cursor = 0; - var insertAt = step / 2; - var a; - var b; - var segment; - - while (polygon.length < desiredLength) { - a = polygon[i]; - b = polygon[(i + 1) % polygon.length]; - - segment = distanceSquareRoot(a, b); - - if (insertAt <= cursor + segment) { - polygon.splice(i + 1, 0, segment - ? midPoint(a, b, (insertAt - cursor) / segment) - : a.slice(0)); - insertAt += step; - } else { - cursor += segment; - i += 1; - } - } - } - - /** - * Split segments of a polygon until it reaches a certain - * amount of points. - * @param {number[][]} polygon the target polygon - * @param {number} maxSegmentLength the maximum amount of points - */ - function bisect(polygon, maxSegmentLength) { - if ( maxSegmentLength === void 0 ) maxSegmentLength = Infinity; - - var a = []; - var b = []; - - for (var i = 0; i < polygon.length; i += 1) { - a = polygon[i]; - b = i === polygon.length - 1 ? polygon[0] : polygon[i + 1]; - - // Could splice the whole set for a segment instead, but a bit messy - while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = midPoint(a, b, 0.5); - polygon.splice(i + 1, 0, b); - } - } - } - - /** - * Checks the validity of a polygon. - * @param {KUTE.polygonMorph} polygon the target polygon - * @returns {boolean} the result of the check - */ - function validPolygon(polygon) { - return Array.isArray(polygon) - && polygon.every(function (point) { return Array.isArray(point) - && point.length === 2 - && !Number.isNaN(point[0]) - && !Number.isNaN(point[1]); }); - } - - /** - * Returns a new polygon and its length from string or another `Array`. - * @param {KUTE.polygonMorph | string} input the target polygon - * @param {number} maxSegmentLength the maximum amount of points - * @returns {KUTE.polygonMorph} normalized polygon - */ - function getPolygon(input, maxSegmentLength) { - var assign; - - var skipBisect; - var polygon; - - if (typeof (input) === 'string') { - var converted = pathStringToPolygon(input, maxSegmentLength); - ((assign = converted, polygon = assign.polygon, skipBisect = assign.skipBisect)); - } else if (!Array.isArray(input)) { - throw Error((invalidPathValue + ": " + input)); - } - - /** @type {KUTE.polygonMorph} */ - var points = [].concat( polygon ); - - if (!validPolygon(points)) { - throw Error((invalidPathValue + ": " + points)); - } - - // TODO skip this test to avoid scale issues? - // Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9 - if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { - points.pop(); - } - - if (!skipBisect && maxSegmentLength - && !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) { - bisect(points, maxSegmentLength); - } - - return points; - } - - /** - * Returns two new polygons ready to tween. - * @param {string} path1 the first path string - * @param {string} path2 the second path string - * @param {number} precision the morphPrecision option value - * @returns {KUTE.polygonMorph[]} the two polygons - */ - function getInterpolationPoints(path1, path2, precision) { - var morphPrecision = precision || defaultOptions$1.morphPrecision; - var fromRing = getPolygon(path1, morphPrecision); - var toRing = getPolygon(path2, morphPrecision); - var diff = fromRing.length - toRing.length; - - addPoints(fromRing, diff < 0 ? diff * -1 : 0); - addPoints(toRing, diff > 0 ? diff : 0); - - rotatePolygon(fromRing, toRing); - - return [roundPath(fromRing), roundPath(toRing)]; - } - - // Component functions - /** - * Returns the current `d` attribute value. - * @returns {string} the `d` attribute value - */ - function getSVGMorph(/* tweenProp */) { - return this.element.getAttribute('d'); - } - - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.polygonObject} value the property value - * @returns {KUTE.polygonObject} the property tween object - */ - function prepareSVGMorph(/* tweenProp */_, value) { - var pathObject = {}; - // remove newlines, they brake JSON strings sometimes - var pathReg = new RegExp('\\n', 'ig'); - var elem = null; - - if (value instanceof SVGPathElement) { - elem = value; - } else if (/^\.|^#/.test(value)) { - elem = selector(value); - } - - // first make sure we return pre-processed values - if (typeof (value) === 'object' && value.polygon) { - return value; - } if (elem && ['path', 'glyph'].includes(elem.tagName)) { - pathObject.original = elem.getAttribute('d').replace(pathReg, ''); - // maybe it's a string path already - } else if (!elem && typeof (value) === 'string') { - pathObject.original = value.replace(pathReg, ''); - } - - return pathObject; - } - - /** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} prop the `path` property name - */ - function crossCheckSVGMorph(prop) { - if (this.valuesEnd[prop]) { - var pathArray1 = this.valuesStart[prop].polygon; - var pathArray2 = this.valuesEnd[prop].polygon; - // skip already processed paths - // allow the component to work with pre-processed values - if (!pathArray1 || !pathArray2 - || (pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length)) { - var p1 = this.valuesStart[prop].original; - var p2 = this.valuesEnd[prop].original; - // process morphPrecision - var morphPrecision = this._morphPrecision - ? parseInt(this._morphPrecision, 10) - : defaultOptions$1.morphPrecision; - - var ref = getInterpolationPoints(p1, p2, morphPrecision); - var path1 = ref[0]; - var path2 = ref[1]; - this.valuesStart[prop].polygon = path1; - this.valuesEnd[prop].polygon = path2; - } - } - } - - // All Component Functions - var svgMorphFunctions = { - prepareStart: getSVGMorph, - prepareProperty: prepareSVGMorph, - onStart: onStartSVGMorph, - crossCheck: crossCheckSVGMorph, - }; - - // Component Full - var SVGMorph = { - component: 'svgMorph', - property: 'path', - defaultValue: [], - Interpolate: coords, - defaultOptions: { morphPrecision: 10 }, - functions: svgMorphFunctions, - // Export utils to global for faster execution - Util: { - // component - addPoints: addPoints, - bisect: bisect, - getPolygon: getPolygon, - validPolygon: validPolygon, - getInterpolationPoints: getInterpolationPoints, - pathStringToPolygon: pathStringToPolygon, - distanceSquareRoot: distanceSquareRoot, - midPoint: midPoint, - approximatePolygon: approximatePolygon, - rotatePolygon: rotatePolygon, - // svg-path-commander - pathToString: pathToString, - pathToCurve: pathToCurve, - getTotalLength: getTotalLength, - getPointAtLength: getPointAtLength, - polygonArea: polygonArea, - roundPath: roundPath, - }, - }; - - var Components = { - EssentialBoxModel: BoxModelEssential, - ColorsProperties: colorProperties, - HTMLAttributes: htmlAttributes, - OpacityProperty: OpacityProperty, - TextWriteProp: TextWrite, - TransformFunctions: TransformFunctions, - SVGDraw: SvgDrawProperty, - SVGMorph: SVGMorph, - }; - - // init components - Object.keys(Components).forEach(function (component) { - var compOps = Components[component]; - Components[component] = new Animation(compOps); - }); - - var version = "2.2.3"; - - // @ts-ignore - - /** - * A global namespace for library version. - * @type {string} - */ - var Version = version; - - // KUTE.js standard distribution version - - var KUTE = { - Animation: Animation, - Components: Components, - - // Tween Interface - Tween: Tween, - fromTo: fromTo, - to: to, - // Tween Collection - TweenCollection: TweenCollection, - allFromTo: allFromTo, - allTo: allTo, - // Tween Interface - - Objects: Objects, - Util: Util, - Easing: Easing, - CubicBezier: CubicBezier, - Render: Render, - Interpolate: interpolate, - Process: Process, - Internals: internals, - Selector: selector, - Version: Version, - }; - - return KUTE; - -})); diff --git a/dist/kute.min.js b/dist/kute.min.js deleted file mode 100644 index f0c3fa3..0000000 --- a/dist/kute.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// KUTE.js Standard v2.2.3 | thednp © 2021 | MIT-License -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=e()}(this,(function(){"use strict";var t=function(t,e,n,r,a){var i=this;this.cx=3*t,this.bx=3*(n-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(r-e)-this.cy,this.ay=1-this.cy-this.by;var o=function(t){return i.sampleCurveY(i.solveCurveX(t))};return Object.defineProperty(o,"name",{writable:!0}),o.name=a||"cubic-bezier("+[t,e,n,r]+")",o};t.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},t.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},t.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},t.prototype.solveCurveX=function(t){var e,n,r,a,i,o,s=1e-5;for(r=t,o=0;o<32;o+=1){if(a=this.sampleCurveX(r)-t,Math.abs(a)(n=1))return n;for(;ea?e=r:n=r,r=.5*(n-e)+e}return r};Object.assign(t,{Version:"1.0.18"});var e={},n=[],r="undefined"!=typeof global?global:"undefined"!=typeof window?window.self:{},a={},i={},o="undefined"==typeof self&&"undefined"!=typeof process&&process.hrtime?function(){var t=process.hrtime();return 1e3*t[0]+t[1]/1e6}:"undefined"!=typeof self&&void 0!==self.performance&&void 0!==self.performance.now?self.performance.now.bind(self.performance):"undefined"!=typeof Date&&Date.now?Date.now:function(){return(new Date).getTime()},s={};s.now=o;var u=0,c=function(t){for(var e=0;e1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.map((function(t){return t.start()})),!1)},j.tween=N;var q=function(t){function n(){for(var e=this,n=[],r=arguments.length;r--;)n[r]=arguments[r];t.apply(this,n),this.valuesStart={},this.valuesEnd={};var a=n.slice(1),i=a[0],o=a[1],s=a[2];return T.call(this,o,"end"),this._resetStart?this.valuesStart=i:T.call(this,i,"start"),this._resetStart||Object.keys(g).forEach((function(t){Object.keys(g[t]).forEach((function(n){g[t][n].call(e,n)}))})),this.paused=!1,this._pauseTime=null,this._repeat=s.repeat||d.repeat,this._repeatDelay=s.repeatDelay||d.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=s.yoyo||d.yoyo,this._reversed=!1,this}return t&&(n.__proto__=t),n.prototype=Object.create(t&&t.prototype),n.prototype.constructor=n,n.prototype.start=function(e){var n=this;return this._resetStart&&(this.valuesStart=this._resetStart,S.call(this),Object.keys(g).forEach((function(t){Object.keys(g[t]).forEach((function(e){g[t][e].call(n,e)}))}))),this.paused=!1,this._yoyo&&Object.keys(this.valuesEnd).forEach((function(t){n.valuesRepeat[t]=n.valuesStart[t]})),t.prototype.start.call(this,e),this},n.prototype.stop=function(){return t.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return t.prototype.close.call(this),this._repeatOption>0&&(this._repeat=this._repeatOption),this._yoyo&&!0===this._reversed&&(this.reverse(),this._reversed=!1),this},n.prototype.resume=function(){return this.paused&&this.playing&&(this.paused=!1,void 0!==this._onResume&&this._onResume.call(this),L.call(this),this._startTime+=e.Time()-this._pauseTime,E(this),u||c()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(M(this),this.paused=!0,this._pauseTime=e.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){var t=this;Object.keys(this.valuesEnd).forEach((function(e){var n=t.valuesRepeat[e];t.valuesRepeat[e]=t.valuesEnd[e],t.valuesEnd[e]=n,t.valuesStart[e]=t.valuesRepeat[e]}))},n.prototype.update=function(t){var n,r=this,a=void 0!==t?t:e.Time();if(a1?1:n;var i=this._easing(n);return Object.keys(this.valuesEnd).forEach((function(t){e[t](r.element,r.valuesStart[t],r.valuesEnd[t],i)})),this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(Number.isFinite(this._repeat)&&(this._repeat-=1),this._startTime=a,Number.isFinite(this._repeat)&&this._yoyo&&!this._reversed&&(this._startTime+=this._repeatDelay),this._yoyo&&(this._reversed=!this._reversed,this.reverse()),!0):(this._onComplete&&this._onComplete.call(this),this.playing=!1,this.close(),void 0!==this._chain&&this._chain.length&&this._chain.forEach((function(t){return t.start()})),!1))},n}(N);j.tween=q;var V=function(t,e,n,r){var a=this,i=j.tween;this.tweens=[];var o=r||{};o.delay=o.delay||d.delay;var s=[];return Array.from(t).forEach((function(t,r){if(s[r]=o||{},s[r].delay=r>0?o.delay+(o.offset||d.offset):o.delay,!(t instanceof Element))throw Error("KUTE - "+t+" is not instanceof Element");a.tweens.push(new i(t,e,n,s[r]))})),this.length=this.tweens.length,this};V.prototype.start=function(t){var n=void 0===t?e.Time():t;return this.tweens.map((function(t){return t.start(n)})),this},V.prototype.stop=function(){return this.tweens.map((function(t){return t.stop()})),this},V.prototype.pause=function(){return this.tweens.map((function(t){return t.pause()})),this},V.prototype.resume=function(){return this.tweens.map((function(t){return t.resume()})),this},V.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof V)e.chain(t.tweens);else{if(!(t instanceof j.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},V.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},V.prototype.removeTweens=function(){this.tweens=[]},V.prototype.getMaxDuration=function(){var t=[];return this.tweens.forEach((function(e){t.push(e._duration+e._delay+e._repeat*e._repeatDelay)})),Math.max(t)};var H=j.tween;var Q=j.tween;var F=function(t){try{if(t.component in f)throw Error("KUTE - "+t.component+" already registered");if(t.property in h)throw Error("KUTE - "+t.property+" already registered")}catch(t){throw Error(t)}var e=this,n=t.component,r={prepareProperty:y,prepareStart:v,onStart:i,onComplete:m,crossCheck:g},o=t.category,s=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;return f[n]=t.properties||t.subProperties||t.property,"defaultValue"in t?(h[s]=t.defaultValue,e.supports=s+" property"):t.defaultValues&&(Object.keys(t.defaultValues).forEach((function(e){h[e]=t.defaultValues[e]})),e.supports=(u||s)+" "+(s||o)+" properties"),t.defaultOptions&&Object.assign(d,t.defaultOptions),t.functions&&Object.keys(r).forEach((function(e){e in t.functions&&("function"==typeof t.functions[e]?(r[e][n]||(r[e][n]={}),r[e][n][o||s]||(r[e][n][o||s]=t.functions[e])):Object.keys(t.functions[e]).forEach((function(a){r[e][n]||(r[e][n]={}),r[e][n][a]||(r[e][n][a]=t.functions[e][a])})))})),t.Interpolate&&(Object.keys(t.Interpolate).forEach((function(e){var n=t.Interpolate[e];"function"!=typeof n||a[e]?Object.keys(n).forEach((function(t){"function"!=typeof n[t]||a[e]||(a[e]=n[t])})):a[e]=n})),b[n]=t.Interpolate),t.Util&&Object.keys(t.Util).forEach((function(e){w[e]||(w[e]=t.Util[e])})),e},U=function(t,e){for(var n,r=parseInt(t,10)||0,a=["px","%","deg","rad","em","rem","vh","vw"],i=0;i.99||a<.01?(10*D(n,r,a)>>0)/10:D(n,r,a)>>0)+"px"})}var Z={};["top","left","width","height"].forEach((function(t){Z[t]=X}));var B=["top","left","width","height"],R={};B.forEach((function(t){R[t]=X}));var Y={component:"essentialBoxModel",category:"boxModel",properties:B,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:D},functions:{prepareStart:function(t){return O(this.element,t)||h[t]},prepareProperty:function(t,e){var n=U(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:R},Util:{trueDimension:U}},z=function(t){var e;if(/rgb|rgba/.test(t)){var n=t.replace(/\s|\)/,"").split("(")[1].split(","),r=n[3]?n[3]:null;r||(e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10)}),e={r:parseInt(n[0],10),g:parseInt(n[1],10),b:parseInt(n[2],10),a:parseFloat(r)}}if(/^#/.test(t)){var a=function(t){var e=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r})),n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return n?{r:parseInt(n[1],16),g:parseInt(n[2],16),b:parseInt(n[3],16)}:null}(t);e={r:a.r,g:a.g,b:a.b}}if(/transparent|none|initial|inherit/.test(t)&&(e={r:0,g:0,b:0,a:0}),!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var o=getComputedStyle(i,null).color;o=/rgb/.test(o)?o.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",e={r:parseInt(o[0],10),g:parseInt(o[1],10),b:parseInt(o[2],10)}}return e};function K(t,e,n){var r={},a=",";return Object.keys(e).forEach((function(a){"a"!==a?r[a]=D(t[a],e[a],n)>>0||0:t[a]&&e[a]&&(r[a]=(100*D(t[a],e[a],n)>>0)/100)})),r.a?"rgba("+r.r+a+r.g+a+r.b+a+r.a+")":"rgb("+r.r+a+r.g+a+r.b+")"}function $(t){this.valuesEnd[t]&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=K(n,r,a)})}var W={};["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"].forEach((function(t){W[t]=$}));var G=["color","backgroundColor","outlineColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],J={};G.forEach((function(t){J[t]="#000"}));var tt={};G.forEach((function(t){tt[t]=$}));var et={component:"colorProperties",category:"colors",properties:G,defaultValues:J,Interpolate:{numbers:D,colors:K},functions:{prepareStart:function(t){return O(this.element,t)||h[t]},prepareProperty:function(t,e){return z(e)},onStart:tt},Util:{trueColor:z}},nt={},rt="htmlAttributes",at=["fill","stroke","stop-color"];function it(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var ot={prepareStart:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(t){var e=it(t).replace(/_+[a-z]+/,""),a=n.element.getAttribute(e);r[e]=at.includes(e)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(t)?1:0)})),r},prepareProperty:function(t,e){var n=this,r={};return Object.keys(e).forEach((function(a){var o=it(a),s=/(%|[a-z]+)$/,u=n.element.getAttribute(o.replace(/_+[a-z]+/,""));if(at.includes(o))i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){t.setAttribute(e,K(n,r,a))})},r[o]=z(e[a])||h.htmlAttributes[a];else if(null!==u&&s.test(u)){var c=U(u).u||U(e[a]).u,l=/%/.test(c)?"_percent":"_"+c;i.htmlAttributes[o+l]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){var i=e.replace(l,"");t.setAttribute(i,(1e3*D(n.v,r.v,a)>>0)/1e3+r.u)})},r[o+l]=U(e[a])}else s.test(e[a])&&null!==u&&(null===u||s.test(u))||(i.htmlAttributes[o]=function(e){n.valuesEnd[t]&&n.valuesEnd[t][e]&&!(e in nt)&&(nt[e]=function(t,e,n,r,a){t.setAttribute(e,(1e3*D(n,r,a)>>0)/1e3)})},r[o]=parseFloat(e[a]))})),r},onStart:{attr:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,n,r,a){Object.keys(r).forEach((function(i){e.attributes[i](t,i,n[i],r[i],a)}))})},attributes:function(t){!e[t]&&this.valuesEnd.attr&&(e[t]=nt)}}},st={component:rt,property:"attr",subProperties:["fill","stroke","stop-color","fill-opacity","stroke-opacity"],defaultValue:{fill:"rgb(0,0,0)",stroke:"rgb(0,0,0)","stop-color":"rgb(0,0,0)",opacity:1,"stroke-opacity":1,"fill-opacity":1},Interpolate:{numbers:D,colors:K},functions:ot,Util:{replaceUppercase:it,trueColor:z,trueDimension:U}};var ut={prepareStart:function(t){return O(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(e,n,r,a){e.style[t]=(1e3*D(n,r,a)>>0)/1e3})}},ct={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:D},functions:ut},lt=String("abcdefghijklmnopqrstuvwxyz").split(""),pt=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),ft=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ht=String("0123456789").split(""),dt=lt.concat(pt,ht),yt=dt.concat(ft),vt={alpha:lt,upper:pt,symbols:ft,numeric:ht,alphanumeric:dt,all:yt},gt={text:function(t){if(!e[t]&&this.valuesEnd[t]){var n=this._textChars,r=vt[d.textChars];n in vt?r=vt[n]:n&&n.length&&(r=n),e[t]=function(t,e,n,a){var i="",o="",s=""===n?" ":n,u=e.substring(0),c=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(o=c.substring(Math.min(a*c.length,c.length)>>0,0),t.innerHTML=a<1?o+l:s):" "===n?(i=u.substring(0,Math.min((1-a)*u.length,u.length)>>0),t.innerHTML=a<1?i+l:s):(i=u.substring(u.length,Math.min(a*u.length,u.length)>>0),o=c.substring(0,Math.min(a*c.length,c.length)>>0),t.innerHTML=a<1?o+l+i:s)}}},number:function(t){t in this.valuesEnd&&!e[t]&&(e[t]=function(t,e,n,r){t.innerHTML=D(e,n,r)>>0})}};function mt(t,e){var n,r;if("string"==typeof t)return(r=document.createElement("SPAN")).innerHTML=t,r.className=e,r;if(!t.children.length||t.children.length&&t.children[0].className!==e){var a=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=a,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function bt(t,e){var n=[],r=t.children.length;if(r){for(var a,i=[],o=t.innerHTML,s=0,u=void 0,c=void 0,l=void 0;s>0)/1e3+n+")"}function wt(t,e,n,r){for(var a=[],i=0;i<3;i+=1)a[i]=(t[i]||e[i]?(1e3*(t[i]+(e[i]-t[i])*r)>>0)/1e3:0)+n;return"translate3d("+a.join(",")+")"}function Et(t,e,n,r){var a="";return a+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",a+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",a+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function Mt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function _t(t,e,n,r){var a=[];return a[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,a[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+a.join(",")+")"}function kt(t,e){return parseFloat(t)/100*e}function Ct(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Ot(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");return 2!==e.length||Number.isNaN(1*e[0])||Number.isNaN(1*e[1])?0:[parseFloat(e[0]),parseFloat(e[1])]},a=function(t,e){return void 0!==t&&void 0!==e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var i=0;i>0)/100,i=0-(100*D(e.s,n.s,r)>>0)/100,o=(100*D(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=i+"px",t.style.strokeDasharray=(100*(o<1?0:o)>>0)/100+"px, "+a+"px"})}};function Lt(t,e,n){if(t[n].length>7){t[n].shift();for(var r=t[n],a=n;r.length;)e[n]="A",t.splice(a+=1,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Nt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function qt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;for("m"===n&&r.length>2&&(t.segments.push([e,r[0],r[1]]),r=r.slice(2),n="l",e="m"===e?"l":"L");r.length>=Nt[n]&&(t.segments.push([e].concat(r.splice(0,Nt[n]))),Nt[n]););}var Vt="Invalid path value";function Ht(t){var e=t.index,n=t.pathValue.charCodeAt(e);return 48===n?(t.param=0,void(t.index+=1)):49===n?(t.param=1,void(t.index+=1)):void(t.err=Vt+': invalid Arc flag "'+n+'", expecting 0 or 1 at index '+e)}function Qt(t){return t>=48&&t<=57}function Ft(t){var e,n=t.max,r=t.pathValue,a=t.index,i=a,o=!1,s=!1,u=!1,c=!1;if(i>=n)t.err=Vt+" at "+i+": missing param "+r[i];else if(43!==(e=r.charCodeAt(i))&&45!==e||(e=(i+=1)=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index+=1}function Dt(t){return t>=48&&t<=57||43===t||45===t||46===t}function Xt(t){var e=t.max,n=t.pathValue,r=t.index,a=n.charCodeAt(r),i=Nt[n[r].toLowerCase()];if(t.segmentStart=r,function(t){switch(32|t){case 109:case 122:case 108:case 104:case 118:case 99:case 115:case 113:case 116:case 97:return!0;default:return!1}}(a))if(t.index+=1,Ut(t),t.data=[],i){for(;;){for(var o=i;o>0;o-=1){if(97!=(32|a)||3!==o&&4!==o?Ft(t):Ht(t),t.err.length)return;t.data.push(t.param),Ut(t),t.index=t.max)break;if(!Dt(n.charCodeAt(t.index)))break}qt(t)}else qt(t);else t.err=Vt+": "+n[r]+" not a path command"}function Zt(t){return t.map((function(t){return Array.isArray(t)?[].concat(t):t}))}function Bt(t){this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""}function Rt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Nt[e]===t.length-1&&"achlmqstvz".includes(e)}))}function Yt(t){if(Rt(t))return Zt(t);var e=new Bt(t);for(Ut(e);e.index1&&(m*=O=Math.sqrt(O),b*=O);var T=m*m,S=b*b,I=(i===o?-1:1)*Math.sqrt(Math.abs((T*S-T*C*C-S*k*k)/(T*C*C+S*k*k)));d=I*m*C/b+(v+x)/2,y=I*-b*k/m+(g+w)/2,f=(Math.asin((g-y)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),h=(Math.asin((w-y)/b)*Math.pow(10,9)>>0)/Math.pow(10,9),f=vh&&(f-=2*Math.PI),!o&&h>f&&(h-=2*Math.PI)}var j=h-f;if(Math.abs(j)>E){var A=h,P=x,L=w;h=f+E*(o&&h>f?1:-1),_=ee(x=d+m*Math.cos(h),w=y+b*Math.sin(h),m,b,a,0,o,P,L,[h,A,d,y])}j=h-f;var N=Math.cos(f),q=Math.sin(f),V=Math.cos(h),H=Math.sin(h),Q=Math.tan(j/4),F=4/3*m*Q,U=4/3*b*Q,D=[v,g],X=[v+F*q,g-U*N],Z=[x+F*H,w-U*V],B=[x,w];if(X[0]=2*D[0]-X[0],X[1]=2*D[1]-X[1],c)return X.concat(Z,B,_);for(var R=[],Y=0,z=(_=X.concat(Z,B,_)).length;Yi+.001)return{x:n,y:r};var o=re([t,e],[n,r],a/i);return{x:o[0],y:o[1]}}return i}function oe(t,e,n,r){var a=.5,i=[t,e],o=[n,r],s=re(i,o,a),u=re(o,s,a),c=re(s,u,a),l=re(u,c,a),p=re(c,l,a),f=i.concat(s,c,p,[a]),h=ie.apply(void 0,f),d=p.concat(l,u,o,[0]),y=ie.apply(void 0,d);return[h.x,h.y,y.x,y.y,n,r]}function se(t,e){var n,r=t[0],a=t.slice(1).map((function(t){return+t})),i=a[0],o=a[1],s=e.x1,u=e.y1,c=e.x,l=e.y;switch("TQ".includes(r)||(e.qx=null,e.qy=null),r){case"M":return e.x=i,e.y=o,t;case"A":return n=[s,u].concat(a),["C"].concat(ee.apply(void 0,n));case"Q":return e.qx=i,e.qy=o,n=[s,u].concat(a),["C"].concat(ne.apply(void 0,n));case"L":return["C"].concat(oe(s,u,i,o));case"Z":return["C"].concat(oe(s,u,c,l))}return t}var ue=4;function ce(t,e){var n=ue;if(!1===e||!1===n)return Zt(t);var r=(n=e>=1?e:n)>=1?Math.pow(10,n):1;return t.map((function(t){var e=t.slice(1).map(Number).map((function(t){return t%1==0?t:Math.round(t*r)/r}));return[t[0]].concat(e)}))}function le(t,e){return ce(t,e).map((function(t){return t[0]+t.slice(1).join(" ")})).join("")}function pe(t,e,n,r,a,i,o,s,u){var c=1-u;return{x:Math.pow(c,3)*t+3*Math.pow(c,2)*u*n+3*c*Math.pow(u,2)*a+Math.pow(u,3)*o,y:Math.pow(c,3)*e+3*Math.pow(c,2)*u*r+3*c*Math.pow(u,2)*i+Math.pow(u,3)*s}}function fe(t,e,n,r,a,i,o,s,u){var c,l=t,p=e,f=0,h=[t,e,f],d=[t,e];if("number"==typeof u&&u<.001)return{x:l,y:p};for(var y=0;y<=100;y+=1){if(f+=ae(d,[l=(c=pe(t,e,n,r,a,i,o,s,y/100)).x,p=c.y]),d=[l,p],"number"==typeof u&&f>=u){var v=(f-u)/(f-h[2]);return{x:d[0]*(1-v)+h[0]*v,y:d[1]*(1-v)+h[1]*v}}h=[l,p,f]}return"number"==typeof u&&u>=f?{x:o,y:s}:f}function he(t,e,n,r,a,i,o,s,u,c){var l,p=[t,e],f=p[0],h=p[1],d=ee(t,e,n,r,a,i,o,s,u),y=0,v=[],g=[],m=0;if("number"==typeof c&&c<.001)return{x:f,y:h};for(var b=0,x=d.length;b=c)return fe.apply(void 0,g.concat([c-y]));y+=m,f=(l=v.slice(-2))[0],h=l[1]}return"number"==typeof c&&c>=y?{x:s,y:u}:y}function de(t,e,n,r,a,i,o){var s=1-o;return{x:Math.pow(s,2)*t+2*s*o*n+Math.pow(o,2)*a,y:Math.pow(s,2)*e+2*s*o*r+Math.pow(o,2)*i}}function ye(t,e,n,r,a,i,o){var s,u=t,c=e,l=0,p=[t,e,l],f=[t,e];if("number"==typeof o&&o<.001)return{x:u,y:c};for(var h=0;h<=100;h+=1){if(l+=ae(f,[u=(s=de(t,e,n,r,a,i,h/100)).x,c=s.y]),f=[u,c],"number"==typeof o&&l>=o){var d=(l-o)/(l-p[2]);return{x:f[0]*(1-d)+p[0]*d,y:f[1]*(1-d)+p[1]*d}}p=[u,c,l]}return"number"==typeof o&&o>=l?{x:a,y:i}:l}function ve(t,e){for(var n,r,a,i=0,o=!0,s=[],u="M",c=0,l=0,p=0,f=0,h=0,d=Jt(Gt(t)),y=0,v=d.length;y=e)return ie.apply(void 0,s.concat([e-i]));i+=c}else if("A"===u){if(c=he.apply(void 0,s),e&&i+c>=e)return he.apply(void 0,s.concat([e-i]));i+=c}else if("C"===u){if(c=fe.apply(void 0,s),e&&i+c>=e)return fe.apply(void 0,s.concat([e-i]));i+=c}else if("Q"===u){if(c=ye.apply(void 0,s),e&&i+c>=e)return ye.apply(void 0,s.concat([e-i]));i+=c}else if("Z"===u){if(s=[l,p,f,h],c=ie.apply(void 0,s),e&&i+c>=e)return ie.apply(void 0,s.concat([e-i]));i+=c}l=(r="Z"!==u?a.slice(-2):[f,h])[0],p=r[1]}return e&&e>=i?{x:l,y:p}:i}function ge(t){return ve(t)}function me(t,e){return ve(t,e)}function be(t){for(var e,n=t.length,r=-1,a=t[n-1],i=0;++r>0)/1e3)}return a}function we(t,e){var n,r,a=Gt((n=le(t),le(Kt(n),0).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0]),i=ge(a),o=[],s=3;e&&!Number.isNaN(e)&&+e>0&&(s=Math.max(s,Math.ceil(i/e)));for(var u=0;u0&&o.reverse(),{polygon:o,skipBisect:!0}}function Ee(t,e){var n=Gt(t);return function(t){var e=[],n=t.length,r=[],a="";if(!t.length||"M"!==t[0][0])return!1;for(var i=0;ie;)r=re(n,r,.5),t.splice(a+1,0,r)}function Ce(t){return Array.isArray(t)&&t.every((function(t){return Array.isArray(t)&&2===t.length&&!Number.isNaN(t[0])&&!Number.isNaN(t[1])}))}function Oe(t,e){var n,r,a;if("string"==typeof t)a=(n=Ee(t,e)).polygon,r=n.skipBisect;else if(!Array.isArray(t))throw Error(Vt+": "+t);var i=[].concat(a);if(!Ce(i))throw Error(Vt+": "+i);return i.length>1&&ae(i[0],i[i.length-1])<1e-9&&i.pop(),!r&&e&&!Number.isNaN(e)&&+e>0&&ke(i,e),i}function Te(t,e,n){var r=n||d.morphPrecision,a=Oe(t,r),i=Oe(e,r),o=a.length-i.length;return _e(a,o<0?-1*o:0),_e(i,o>0?o:0),Me(a,i),[ce(a),ce(i)]}var Se={prepareStart:function(){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=new RegExp("\\n","ig"),a=null;return e instanceof SVGPathElement?a=e:/^\.|^#/.test(e)&&(a=P(e)),"object"==typeof e&&e.polygon?e:(a&&["path","glyph"].includes(a.tagName)?n.original=a.getAttribute("d").replace(r,""):a||"string"!=typeof e||(n.original=e.replace(r,"")),n)},onStart:function(t){!e[t]&&this.valuesEnd[t]&&(e[t]=function(t,e,n,r){var a=e.polygon,i=n.polygon,o=i.length;t.setAttribute("d",1===r?n.original:"M"+xe(a,i,o,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].polygon,n=this.valuesEnd[t].polygon;if(!e||!n||e&&n&&e.length!==n.length){var r=Te(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision,10):d.morphPrecision),a=r[0],i=r[1];this.valuesStart[t].polygon=a,this.valuesEnd[t].polygon=i}}}},Ie={EssentialBoxModel:Y,ColorsProperties:et,HTMLAttributes:st,OpacityProperty:ct,TextWriteProp:{component:"textWriteProperties",category:"textWrite",properties:["text","number"],defaultValues:{text:" ",number:"0"},defaultOptions:{textChars:"alpha"},Interpolate:{numbers:D},functions:{prepareStart:function(){return this.element.innerHTML},prepareProperty:function(t,e){return"number"===t?parseFloat(e):""===e?" ":e},onStart:gt},Util:{charSet:vt,createTextTweens:function(t,e,n){if(t.playing)return!1;var r=n||{};r.duration=1e3,"auto"===n.duration?r.duration="auto":Number.isFinite(1*n.duration)&&(r.duration=1*n.duration);var a=j.tween,i=function(t,e){var n=bt(t,"text-part"),r=bt(mt(e),"text-part");return t.innerHTML="",t.innerHTML+=n.map((function(t){return t.className+=" oldText",t.outerHTML})).join(""),t.innerHTML+=r.map((function(t){return t.className+=" newText",t.outerHTML.replace(t.innerHTML,"")})).join(""),[n,r]}(t,e),o=i[0],s=i[1],u=[].slice.call(t.getElementsByClassName("oldText")).reverse(),c=[].slice.call(t.getElementsByClassName("newText")),l=[],p=0;return(l=(l=l.concat(u.map((function(t,e){return r.duration="auto"===r.duration?75*o[e].innerHTML.length:r.duration,r.delay=p,r.onComplete=null,p+=r.duration,new a(t,{text:t.innerHTML},{text:""},r)})))).concat(c.map((function(n,i){return r.duration="auto"===r.duration?75*s[i].innerHTML.length:r.duration,r.delay=p,r.onComplete=i===s.length-1?function(){t.innerHTML=e,t.playing=!1}:null,p+=r.duration,new a(n,{text:""},{text:s[i].innerHTML},r)})))).start=function(){t.playing||(l.forEach((function(t){return t.start()})),t.playing=!0)},l}}},TransformFunctions:{component:"transformFunctions",property:"transform",subProperties:["perspective","translate3d","translateX","translateY","translateZ","translate","rotate3d","rotateX","rotateY","rotateZ","rotate","skewX","skewY","skew","scale"],defaultValues:{perspective:400,translate3d:[0,0,0],translateX:0,translateY:0,translateZ:0,translate:[0,0],rotate3d:[0,0,0],rotateX:0,rotateY:0,rotateZ:0,rotate:0,skewX:0,skewY:0,skew:[0,0],scale:1},functions:{prepareStart:function(t){var e=C(this.element);return e[t]?e[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},a=[],i=[],o=[],s=["translate3d","translate","rotate3d","skew"];return Object.keys(e).forEach((function(t){var u="object"==typeof e[t]&&e[t].length?e[t].map((function(t){return parseInt(t,10)})):parseInt(e[t],10);if(s.includes(t)){var c="translate"===t||"rotate"===t?t+"3d":t;r[c]="skew"===t?u.length?[u[0]||0,u[1]||0]:[u||0,0]:"translate"===t?u.length?[u[0]||0,u[1]||0,u[2]||0]:[u||0,0,0]:[u[0]||0,u[1]||0,u[2]||0]}else if(/[XYZ]/.test(t)){var l=t.replace(/[XYZ]/,""),p="skew"===l?l:l+"3d",f="skew"===l?2:3,h=[];"translate"===l?h=a:"rotate"===l?h=i:"skew"===l&&(h=o);for(var d=0;d>0)/1e3)+n,a[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+a.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:Mt,skew:_t}},SVGDraw:{component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:D},functions:Pt,Util:{getRectLength:Ct,getPolyLength:Ot,getLineLength:Tt,getCircleLength:St,getEllipseLength:It,getTotalLength:jt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:At,percent:kt}},SVGMorph:{component:"svgMorph",property:"path",defaultValue:[],Interpolate:xe,defaultOptions:{morphPrecision:10},functions:Se,Util:{addPoints:_e,bisect:ke,getPolygon:Oe,validPolygon:Ce,getInterpolationPoints:Te,pathStringToPolygon:Ee,distanceSquareRoot:ae,midPoint:re,approximatePolygon:we,rotatePolygon:Me,pathToString:le,pathToCurve:function(t){if(function(t){return Rt(t)&&t.every((function(t){return"MC".includes(t[0])}))}(t))return Zt(t);for(var e=Jt(Gt(t)),n=Object.assign({},Wt),r=[],a="",i=e.length,o=0;o 0 ? 1 : -1) * Math.floor(Math.abs(number)); - }; - var maxSafeInteger = Math.pow(2, 53) - 1; - var toLength = function (value) { - var len = toInteger(value); - return Math.min(Math.max(len, 0), maxSafeInteger); - }; - - return function from(arrayLike/*, mapFn, thisArg */) { - var C = this, items = Object(arrayLike); - if (arrayLike == null) { - throw new TypeError('Array.from requires an array-like object - not null or undefined'); - } - var mapFn = arguments.length > 1 ? arguments[1] : void undefined, T; - if (typeof mapFn !== 'undefined') { - if (!isCallable(mapFn)) { - throw new TypeError('Array.from: when provided, the second argument must be a function'); - } - - if (arguments.length > 2) { - T = arguments[2]; - } - } - var len = toLength(items.length); - var A = isCallable(C) ? Object(new C(len)) : new Array(len); - - var k = 0; - var kValue; - while (k < len) { - kValue = items[k]; - if (mapFn) { - A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); - } else { - A[k] = kValue; - } - k += 1; - } - A.length = len; - return A; - } - }()); -} - -// https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js - -if (!Array.prototype.flat) { - Object.defineProperty(Array.prototype, 'flat', { - configurable: true, - value: function flat () { - var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]); - - return depth ? Array.prototype.reduce.call(this, function (acc, cur) { - if (Array.isArray(cur)) { - acc.push.apply(acc, flat.call(cur, depth - 1)); - } else { - acc.push(cur); - } - - return acc; - }, []) : Array.prototype.slice.call(this); - }, - writable: true - }); -} - -if (!Array.prototype.includes) { - Array.prototype.includes = function(searchElement /*, fromIndex*/ ) { - var O = Object(this); - var len = parseInt(O.length) || 0; - if (len === 0) { - return false; - } - var n = parseInt(arguments[1]) || 0; - var k; - if (n >= 0) { - k = n; - } else { - k = len + n; - if (k < 0) {k = 0;} - } - var currentElement; - while (k < len) { - currentElement = O[k]; - if (searchElement === currentElement || - (searchElement !== searchElement && currentElement !== currentElement)) { - return true; - } - k++; - } - return false; - }; -} - -if (!String.prototype.includes) { - String.prototype.includes = function(search, start) { - if (search instanceof RegExp) { - throw TypeError('first argument must not be a RegExp'); - } - if (start === undefined) { start = 0; } - return this.indexOf(search, start) !== -1; - }; -} - -if (!Number.isFinite) { - Number.isFinite = function(value) { - return typeof value === 'number' - && isFinite(value); - }; -} - -if (!Number.isInteger) { - Number.isInteger = function(value) { - return typeof value === 'number' - && isFinite(value) - && Math.floor(value) === value; - }; -} - -if (!Number.isNaN) { - Number.isNaN = function(value) { - return typeof value === 'number' - && value !== value; - }; -} diff --git a/dist/polyfill.min.js b/dist/polyfill.min.js deleted file mode 100644 index ab1cd05..0000000 --- a/dist/polyfill.min.js +++ /dev/null @@ -1,3 +0,0 @@ -// KUTE.js Polyfill v2.1.1-alpha1 | 2021 © thednp | MIT-License -"use strict"; -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=0?n=o:(n=e+o)<0&&(n=0);n 0.0) { + aB = t; + } else { + aA = t; + } + } while (Math.abs(x) > j && ++i < y); + return t; + }; + + _bz.nri = function (aX, agt, mX1, mX2) { // newton Raphs on Iterate + var i = 0, j = _bz.ni; + for (i; i < j; ++i) { + var cs = _bz.gS(agt, mX1, mX2); + if (cs === 0.0) return agt; + var x = _bz.cB(agt, mX1, mX2) - aX; + agt -= x / cs; + } + return agt; + }; + + _bz.csv = function (mX1, mX2) { // calc Sample Values + var i = 0, j = _bz.ksts; + for (i; i < j; ++i) { + _bz.msv[i] = _bz.cB(i * _bz.ksss, mX1, mX2); + } + }; + + _bz.gx = function (aX,mX1,mX2) { //get to X + var iS = 0.0, cs = 1, ls = _bz.ksts - 1; + + for (; cs != ls && _bz.msv[cs] <= aX; ++cs) { + iS += _bz.ksss; + } + --cs; + + // Interpolate to provide an initial guess for t + var dist = (aX - _bz.msv[cs]) / (_bz.msv[cs+1] - _bz.msv[cs]), + gt = iS + dist * _bz.ksss, + ins = _bz.gS(gt, mX1, mX2), + fiS = iS + _bz.ksss; + + if (ins >= _bz.nms) { + return _bz.nri(aX, gt, mX1, mX2); + } else if (ins === 0.0) { + return gt; + } else { + return _bz.bS(aX, iS, fiS, mX1, mX2); + } + }; + + _bz.pc = function(mX1, mX2, mY1, mY2) { + this._p = true; + if (mX1 != mY1 || mX2 != mY2) + _bz.csv(mX1, mX2); + }; + + g.Ease = {}; // export these functions to global for best performance + + // predefined bezier based easings, can be accessed via string, eg 'easeIn' or 'easeInOutQuart' + // _easings = ["linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInExpo","easeOutExpo","easeInOutExpo","slowMo","slowMo1","slowMo2"], + g.Ease.easeIn = function(){ return _bz.pB(0.42, 0.0, 1.00, 1.0); }; + g.Ease.easeOut = function(){ return _bz.pB(0.00, 0.0, 0.58, 1.0); }; + g.Ease.easeInOut = function(){ return _bz.pB(0.50, 0.16, 0.49, 0.86); }; + + g.Ease.easeInSine = function(){ return _bz.pB(0.47, 0, 0.745, 0.715); }; + g.Ease.easeOutSine = function(){ return _bz.pB(0.39, 0.575, 0.565, 1); }; + g.Ease.easeInOutSine = function(){ return _bz.pB(0.445, 0.05, 0.55, 0.95); }; + + g.Ease.easeInQuad = function () { return _bz.pB(0.550, 0.085, 0.680, 0.530); }; + g.Ease.easeOutQuad = function () { return _bz.pB(0.250, 0.460, 0.450, 0.940); }; + g.Ease.easeInOutQuad = function () { return _bz.pB(0.455, 0.030, 0.515, 0.955); }; + + g.Ease.easeInCubic = function () { return _bz.pB(0.55, 0.055, 0.675, 0.19); }; + g.Ease.easeOutCubic = function () { return _bz.pB(0.215, 0.61, 0.355, 1); }; + g.Ease.easeInOutCubic = function () { return _bz.pB(0.645, 0.045, 0.355, 1); }; + + g.Ease.easeInQuart = function () { return _bz.pB(0.895, 0.03, 0.685, 0.22); }; + g.Ease.easeOutQuart = function () { return _bz.pB(0.165, 0.84, 0.44, 1); }; + g.Ease.easeInOutQuart = function () { return _bz.pB(0.77, 0, 0.175, 1); }; + + g.Ease.easeInQuint = function(){ return _bz.pB(0.755, 0.05, 0.855, 0.06); }; + g.Ease.easeOutQuint = function(){ return _bz.pB(0.23, 1, 0.32, 1); }; + g.Ease.easeInOutQuint = function(){ return _bz.pB(0.86, 0, 0.07, 1); }; + + g.Ease.easeInExpo = function(){ return _bz.pB(0.95, 0.05, 0.795, 0.035); }; + g.Ease.easeOutExpo = function(){ return _bz.pB(0.19, 1, 0.22, 1); }; + g.Ease.easeInOutExpo = function(){ return _bz.pB(1, 0, 0, 1); }; + + g.Ease.easeInCirc = function(){ return _bz.pB(0.6, 0.04, 0.98, 0.335); }; + g.Ease.easeOutCirc = function(){ return _bz.pB(0.075, 0.82, 0.165, 1); }; + g.Ease.easeInOutCirc = function(){ return _bz.pB(0.785, 0.135, 0.15, 0.86); }; + + g.Ease.easeInBack = function(){ return _bz.pB(0.600, -0.280, 0.735, 0.045); }; + g.Ease.easeOutBack = function(){ return _bz.pB(0.175, 0.885, 0.320, 1.275); }; + g.Ease.easeInOutBack = function(){ return _bz.pB(0.68, -0.55, 0.265, 1.55); }; + + g.Ease.slowMo = function(){ return _bz.pB(0.000, 0.500, 1.000, 0.500); }; + g.Ease.slowMo1 = function(){ return _bz.pB(0.000, 0.700, 1.000, 0.300); }; + g.Ease.slowMo2 = function(){ return _bz.pB(0.000, 0.900, 1.000, 0.100); }; + + // return E; +})); diff --git a/kute-bs.js b/kute-bs.js new file mode 100644 index 0000000..236df9a --- /dev/null +++ b/kute-bs.js @@ -0,0 +1,116 @@ +/* KUTE.js - The Light Tweening Engine + * package - Box Shadow Plugin + * desc - adds support for boxShadow property with an array of values [h-shadow, v-shadow, blur, spread, color, inset] + * examples + * var bShadowTween1 = KUTE.to('selector', {boxShadow: '1px 1px 1px #069'}); // accepting string value + * var bShadowTween2 = KUTE.to('selector', {boxShadow: [1, 1, 1, '#069', 'inset'] }); // accepting array value + * by dnp_theme + * Licensed under MIT-License + */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; }); + } else if(typeof module == "object" && typeof require == "function") { + var KUTE = require("./kute.js"); + module.exports = factory(KUTE); + } else if ( typeof window.KUTE !== 'undefined' ) { + factory(KUTE); + } else { + throw new Error("Box Shadow Plugin require KUTE.js."); + } +}( function (KUTE) { + 'use strict'; + + // filter unsupported browsers + if (!('boxShadow' in document.body.style)) {return;} + + // add a reference to KUTE object + var K = window.KUTE; + + // the preffixed boxShadow property, mostly for legacy browsers + // maybe the browser is supporting the property with its vendor preffix + // box-shadow: none|h-shadow v-shadow blur spread color |inset|initial|inherit; + var _boxShadow = K.property('boxShadow'); // note we're using the KUTE.property() autopreffix utility + var colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi; // a full RegEx for color strings + + // for the .to() method, you need to prepareStart the boxShadow property + // which means you need to read the current computed value + K.prS['boxShadow'] = function(element,property,value){ + var cssBoxShadow = K.gCS(element,'boxShadow'); + return /^none$|^initial$|^inherit$|^inset$/.test(cssBoxShadow) ? '0px 0px 0px 0px rgb(0,0,0)' : cssBoxShadow; + } + + // the processProperty for boxShadow + // registers the K.dom['boxShadow'] function + // returns an array of 6 values with the following format + // [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset] + K.pp['boxShadow'] = function(property,value,element){ + if ( !('boxShadow' in K.dom) ) { + + // the DOM update function for boxShadow registers here + // we only enqueue it if the boxShadow property is used to tween + K.dom['boxShadow'] = function(w,p,v) { + // let's start with the numbers | set unit | also determine inset + var numbers = [], unit = 'px', // the unit is always px + inset = w._vS[p][5] !== 'none' || w._vE[p][5] !== 'none' ? ' inset' : false; + for (var i=0; i<4; i++){ + numbers.push( (w._vS[p][i] + (w._vE[p][i] - w._vS[p][i]) * v ) + unit); + } + + // now we handle the color + var color, _color = {}; + for (var c in w._vE[p][4]) { + _color[c] = parseInt(w._vS[p][4][c] + (w._vE[p][4][c] - w._vS[p][4][c]) * v )||0; + } + color = 'rgb(' + _color.r + ',' + _color.g + ',' + _color.b + ') '; + + // the final piece of the puzzle, the DOM update + w._el.style[_boxShadow] = inset ? color + numbers.join(' ') + inset : color + numbers.join(' '); + }; + } + + // processProperty for boxShadow, builds basic structure with ready to tween values + if (typeof value === 'string'){ + var color, inset = 'none'; + // make sure to always have the inset last if possible + inset = /inset/.test(value) ? 'inset' : inset; + value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g,'') : value; + + // also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset" + color = value.match(colRegEx); + value = value.replace(color[0],'').split(' ').concat([color[0].replace(/\s/g,'')],[inset]); + + value = K.processBoxShadowArray(value); + } else if (value instanceof Array){ + value = K.processBoxShadowArray(value); + } + return value; + } + + // utility function to process values accordingly + // numbers must be integers and color must be rgb object + K.processBoxShadowArray = function(shadow){ + var newShadow, i; + + if (shadow.length === 3) { // [h-shadow, v-shadow, color] + newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none']; + } else if (shadow.length === 4) { // [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color] + newShadow = /inset|none/.test(shadow[3]) ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]] : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none']; + } else if (shadow.length === 5) { // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color] + newShadow = /inset|none/.test(shadow[4]) ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]] : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none']; + } else if (shadow.length === 6) { // ideal [h-shadow, v-shadow, blur, spread, color, inset] + newShadow = shadow; + } + + // make sure the values are ready to tween + for (i=0;i<4;i++){ + newShadow[i] = parseFloat(newShadow[i]); + } + // also the color must be a rgb object + newShadow[4] = K.truC(newShadow[4]); + return newShadow; + } + + return this; +})); \ No newline at end of file diff --git a/kute-effects.js b/kute-effects.js new file mode 100644 index 0000000..40bc8d0 --- /dev/null +++ b/kute-effects.js @@ -0,0 +1,114 @@ +/* KUTE.js - The Light Tweening Engine + * package - KUTE Effects Plugin + * desc - Customized and easy accessible FX effects + * by @dalisoft (https://github.com/dalisoft) + * Licensed under MIT-License + */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(["./kute.js"], function (KUTE) { + factory(KUTE); + return KUTE; + }); + } else if (typeof module == "object" && typeof require == "function") { + // We assume, that require() is sync. + var KUTE = require("./kute.js"); + // Export the modified one. Not really required, but convenient. + module.exports = factory(KUTE); + } else if (typeof window.KUTE !== 'undefined') { + // Browser globals + factory(window.KUTE); + } else { + throw new Error("Effects plugin require KUTE.js."); + } +} + (function (KUTE) { + + KUTE.Effects = { + setEffect : function (name, to, options) { + KUTE.Effects[name] = function (element) { + return { + to : to, + options : options(element) + } + } + }, + Show : function (element) { + return { + to : { + opacity : 1 + }, + options : { + start : function () { + element.style.display = 'block'; + } + } + } + }, + Hide : function (element) { + return { + to : { + opacity : 0 + }, + options : { + complete : function () { + element.style.display = 'none'; + } + } + } + }, + SlideUp : function (element) { + return { + to : { + height : 0 + }, + options : { + easing : 'easingQuadInOut', + complete : function () { + element.style.display = 'none'; + } + } + } + }, + /* TO-Do + SlideDown : function ( element ) { + return { + to : { maxHeight : 200 }, + options : { + start : function () { + element.style.display = 'block'; + element.style.height = '0px'; + }, + complete : function () { + element.style.height = ''; + } + } + } + }*/ + }; + + KUTE.setEffect = KUTE.Effects.setEffect; + + // you can add effects with ```setEffect``` function like this + KUTE.Effects.setEffect('ScaleOut', { scale : [0, 0], }, function ( element ) { + return { + easing : 'easingQuadInOut', + complete : function () { + element.style.display = 'none'; + } + } + }); + + KUTE.pp['effect'] = function (property, effect, element) { + + if (KUTE.Effects[effect]) { + var effects = KUTE.Effects[effect](element), + tween = KUTE.to(element, effects.to, effects.options).start(); + + KUTE.dom['effect'] = function (object, propertyName, value) {} + } + + return {}; + }; + + })); diff --git a/kute-html.js b/kute-html.js new file mode 100644 index 0000000..853c968 --- /dev/null +++ b/kute-html.js @@ -0,0 +1,30 @@ +/* KUTE.js - The Light Tweening Engine + * package - HTML Plugin + * desc - makes tween object with HTML + * by @dalisoft (https://github.com/dalisoft) + * Licensed under MIT-License + */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; }); + } else if(typeof module == "object" && typeof require == "function") { + // We assume, that require() is sync. + var KUTE = require("./kute.js"); + // Export the modified one. Not really required, but convenient. + module.exports = factory(KUTE); + } else if ( typeof window.KUTE !== 'undefined' ) { + // Browser globals + factory(window.KUTE); + } else { + throw new Error("HTML Plugin require KUTE.js."); + } +}( function (KUTE) { + 'use strict'; + // performance-ready simple & lightweight HTML plug-in for KUTE.js + var kute = [].slice.call(document.querySelectorAll('[kute]')); + kute.map(function(k){ + var type = k.getAttribute("kute"), prop = (new Function("return {" + k.getAttribute("kute-props") + "}")()), opt = (new Function("return {" + k.getAttribute("kute-options") + "}")()) + KUTE[type](/all/.test(type) ? (k.getAttribute("class") || "").split(" ")[0] || k.tagName : k, type === "fromTo" ? prop.from : prop, type === "fromTo" ? prop.to : opt, type === "fromTo" && opt).start(); + }); +})); diff --git a/kute-jquery.js b/kute-jquery.js new file mode 100644 index 0000000..b9b3c00 --- /dev/null +++ b/kute-jquery.js @@ -0,0 +1,42 @@ +/* KUTE.js - The Light Tweening Engine + * package jQuery Plugin + * by dnp_theme + * Licensed under MIT-License + */ + +(function(root,factory){ + // We need to require the root KUTE and jQuery. + if (typeof define === 'function' && define.amd) { + define(["./kute.js", "jquery"], function(KUTE, $){ + factory($, KUTE); + return KUTE; + }); + } else if(typeof module == "object" && typeof require == "function") { + // We assume, that require() is sync. + var KUTE = require("./kute.js"); + var $ = require("jquery"); + + // Export the modified one. Not really required, but convenient. + module.exports = factory($, KUTE); + } else if (typeof root.KUTE !== "undefined" && (typeof root.$ !== 'undefined' || typeof root.jQuery !== 'undefined' ) ) { + // jQuery always has two ways of existing... Find one, and pass. + var $ = root.jQuery || root.$, KUTE = root.KUTE; + factory($, KUTE); + } else { + throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery"); + } + })(this, function($, KUTE) { + 'use strict'; + + $.fn.fromTo = function(from,to,ops) { + var el = this.length > 1 ? this : this[0], method = this.length > 1 ? 'allFromTo' : 'fromTo'; + return KUTE[method](el,from,to,ops); + }; + + $.fn.to = function(to,ops) { + var el = this.length > 1 ? this : this[0], method = this.length > 1 ? 'allTo' : 'to'; + return KUTE[method](el,to,ops); + }; + + return this; +}); \ No newline at end of file diff --git a/kute-matrix.js b/kute-matrix.js new file mode 100644 index 0000000..91a9f2b --- /dev/null +++ b/kute-matrix.js @@ -0,0 +1,509 @@ +/* KUTE.js - The Light Tweening Engine + * package - Matrix Transform Plugin + * desc - adds the ability to animate transform with matrix / matrix3d + * by dnp_theme + * Licensed under MIT-License + */ + + +(function(factory){ + if (typeof define === 'function' && define.amd) { + define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; }); + } else if(typeof module == "object" && typeof require == "function") { + var KUTE = require("./kute.js"); + // Export the modified one. Not really required, but convenient. + module.exports = factory(KUTE); + } else if(typeof window.KUTE != "undefined") { + // window.KUTE.Matrix = window.KUTE.Matrix || factory(KUTE); + factory(KUTE); + } else { + throw new Error("Matrix Plugin require KUTE.js.") + } +})(function(KUTE){ + 'use strict'; + var K = window.KUTE, _pf = K.getPrefix(), + _pfT = (!('transform' in document.body.style)) ? true : false, // is prefix required for transform + _tr = _pfT ? _pf + 'Transform' : 'transform', + _3d = ['rotateX', 'rotateY','translateZ', 'perspective', 'rotate3d', 'scale3d', 'translate3d'], // transform properties that require perspective + _tf = ['translate3d', 'translateX', 'translateY', 'translateZ', 'rotate', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scale']; // transform + + + /** + * CSSMatrix Shim + * @constructor + */ + // CSS Matrix as implemented by @arian + // https://github.com/arian/M/blob/master/CSSMatrix.js + var CSSMatrix = function(){ + var a = [].slice.call(arguments), + m = this; + // if (a.length) for (var i = a.length; i--;){ + // if (Math.abs(a[i]) < CSSMatrix.SMALL_NUMBER) a[i] = 0; + // } + m.setIdentity(); + if (a.length == 16){ + m.m11 = m.a = a[0]; m.m12 = m.b = a[1]; m.m13 = a[2]; m.m14 = a[3]; + m.m21 = m.c = a[4]; m.m22 = m.d = a[5]; m.m23 = a[6]; m.m24 = a[7]; + m.m31 = a[8]; m.m32 = a[9]; m.m33 = a[10]; m.m34 = a[11]; + m.m41 = m.e = a[12]; m.m42 = m.f = a[13]; m.m43 = a[14]; m.m44 = a[15]; + } else if (a.length == 6) { + this.affine = true; + m.m11 = m.a = a[0]; m.m12 = m.b = a[1]; m.m14 = m.e = a[4]; + m.m21 = m.c = a[2]; m.m22 = m.d = a[3]; m.m24 = m.f = a[5]; + } else if (a.length === 1 && typeof a[0] == 'string') { + m.setMatrixValue(a[0]); + } else if (a.length > 0) { + throw new TypeError('Invalid Matrix Value'); + } + }; + + // decimal values in WebKitCSSMatrix.prototype.toString are truncated to 6 digits + CSSMatrix.SMALL_NUMBER = 1e-20; + + // Transformations + + // http://en.wikipedia.org/wiki/Rotation_matrix + CSSMatrix.Rotate = function(rx, ry, rz){ + rx *= Math.PI / 180; + ry *= Math.PI / 180; + rz *= Math.PI / 180; + // minus sin() because of right-handed system + var cosx = Math.cos(rx), sinx = - Math.sin(rx); + var cosy = Math.cos(ry), siny = - Math.sin(ry); + var cosz = Math.cos(rz), sinz = - Math.sin(rz); + var m = new CSSMatrix(); + + m.m11 = m.a = cosy * cosz; + m.m12 = m.b = - cosy * sinz; + m.m13 = siny; + + m.m21 = m.c = sinx * siny * cosz + cosx * sinz; + m.m22 = m.d = cosx * cosz - sinx * siny * sinz; + m.m23 = - sinx * cosy; + + m.m31 = sinx * sinz - cosx * siny * cosz; + m.m32 = sinx * cosz + cosx * siny * sinz; + m.m33 = cosx * cosy; + + return m; + }; + + CSSMatrix.RotateAxisAngle = function(x, y, z, angle){ + angle *= Math.PI / 360; + + var sinA = Math.sin(angle), cosA = Math.cos(angle), sinA2 = sinA * sinA; + var length = Math.sqrt(x * x + y * y + z * z); + + if (length === 0){ + // bad vector length, use something reasonable + x = 0; + y = 0; + z = 1; + } else { + x /= length; + y /= length; + z /= length; + } + + var x2 = x * x, y2 = y * y, z2 = z * z; + + var m = new CSSMatrix(); + m.m11 = m.a = 1 - 2 * (y2 + z2) * sinA2; + m.m12 = m.b = 2 * (x * y * sinA2 + z * sinA * cosA); + m.m13 = 2 * (x * z * sinA2 - y * sinA * cosA); + m.m21 = m.c = 2 * (y * x * sinA2 - z * sinA * cosA); + m.m22 = m.d = 1 - 2 * (z2 + x2) * sinA2; + m.m23 = 2 * (y * z * sinA2 + x * sinA * cosA); + m.m31 = 2 * (z * x * sinA2 + y * sinA * cosA); + m.m32 = 2 * (z * y * sinA2 - x * sinA * cosA); + m.m33 = 1 - 2 * (x2 + y2) * sinA2; + m.m14 = m.m24 = m.m34 = 0; + m.m41 = m.e = m.m42 = m.f = m.m43 = 0; + m.m44 = 1; + + return m; + }; + + CSSMatrix.ScaleX = function(x){ + var m = new CSSMatrix(); + m.m11 = m.a = x; + return m; + }; + + CSSMatrix.ScaleY = function(y){ + var m = new CSSMatrix(); + m.m22 = m.d = y; + return m; + }; + + CSSMatrix.ScaleZ = function(z){ + var m = new CSSMatrix(); + m.m33 = z; + return m; + }; + + CSSMatrix.Scale = function(x, y, z){ + var m = new CSSMatrix(); + m.m11 = m.a = x; + m.m22 = m.d = y; + m.m33 = z; + return m; + }; + + CSSMatrix.SkewX = function(angle){ + angle *= Math.PI / 180; + var m = new CSSMatrix(); + m.m21 = m.c = Math.tan(angle); + return m; + }; + + CSSMatrix.SkewY = function(angle){ + angle *= Math.PI / 180; + var m = new CSSMatrix(); + m.m12 = m.b = Math.tan(angle); + return m; + }; + + CSSMatrix.Translate = function(x, y, z){ + var m = new CSSMatrix(); + m.m41 = m.e = x; + m.m42 = m.f = y; + m.m43 = z; + return m; + }; + + CSSMatrix.multiply = function(m1, m2){ + + var m11 = m2.m11 * m1.m11 + m2.m12 * m1.m21 + m2.m13 * m1.m31 + m2.m14 * m1.m41, + m12 = m2.m11 * m1.m12 + m2.m12 * m1.m22 + m2.m13 * m1.m32 + m2.m14 * m1.m42, + m13 = m2.m11 * m1.m13 + m2.m12 * m1.m23 + m2.m13 * m1.m33 + m2.m14 * m1.m43, + m14 = m2.m11 * m1.m14 + m2.m12 * m1.m24 + m2.m13 * m1.m34 + m2.m14 * m1.m44, + + m21 = m2.m21 * m1.m11 + m2.m22 * m1.m21 + m2.m23 * m1.m31 + m2.m24 * m1.m41, + m22 = m2.m21 * m1.m12 + m2.m22 * m1.m22 + m2.m23 * m1.m32 + m2.m24 * m1.m42, + m23 = m2.m21 * m1.m13 + m2.m22 * m1.m23 + m2.m23 * m1.m33 + m2.m24 * m1.m43, + m24 = m2.m21 * m1.m14 + m2.m22 * m1.m24 + m2.m23 * m1.m34 + m2.m24 * m1.m44, + + m31 = m2.m31 * m1.m11 + m2.m32 * m1.m21 + m2.m33 * m1.m31 + m2.m34 * m1.m41, + m32 = m2.m31 * m1.m12 + m2.m32 * m1.m22 + m2.m33 * m1.m32 + m2.m34 * m1.m42, + m33 = m2.m31 * m1.m13 + m2.m32 * m1.m23 + m2.m33 * m1.m33 + m2.m34 * m1.m43, + m34 = m2.m31 * m1.m14 + m2.m32 * m1.m24 + m2.m33 * m1.m34 + m2.m34 * m1.m44, + + m41 = m2.m41 * m1.m11 + m2.m42 * m1.m21 + m2.m43 * m1.m31 + m2.m44 * m1.m41, + m42 = m2.m41 * m1.m12 + m2.m42 * m1.m22 + m2.m43 * m1.m32 + m2.m44 * m1.m42, + m43 = m2.m41 * m1.m13 + m2.m42 * m1.m23 + m2.m43 * m1.m33 + m2.m44 * m1.m43, + m44 = m2.m41 * m1.m14 + m2.m42 * m1.m24 + m2.m43 * m1.m34 + m2.m44 * m1.m44; + + return new CSSMatrix( m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 ); + }; + + // w3c defined methods + + /** + * The setMatrixValue method replaces the existing matrix with one computed + * from parsing the passed string as though it had been assigned to the + * transform property in a CSS style rule. + * @param {String} string The string to parse. + */ + CSSMatrix.prototype.setMatrixValue = function(string){ + string = String(string).trim(); + var m = this; + m.setIdentity(); + if (string == 'none') return m; + var type = string.slice(0, string.indexOf('(')), parts, i; + if (type == 'matrix3d'){ + parts = string.slice(9, -1).split(','); + for (i = parts.length; i--;) parts[i] = parseFloat(parts[i]); + m.m11 = m.a = parts[0]; m.m12 = m.b = parts[1]; m.m13 = parts[2]; m.m14 = parts[3]; + m.m21 = m.c = parts[4]; m.m22 = m.d = parts[5]; m.m23 = parts[6]; m.m24 = parts[7]; + m.m31 = parts[8]; m.m32 = parts[9]; m.m33 = parts[10]; m.m34 = parts[11]; + m.m41 = m.e = parts[12]; m.m42 = m.f = parts[13]; m.m43 = parts[14]; m.m44 = parts[15]; + } else if (type == 'matrix'){ + m.affine = true; + parts = string.slice(7, -1).split(','); + for (i = parts.length; i--;) parts[i] = parseFloat(parts[i]); + m.m11 = m.a = parts[0]; m.m12 = m.b = parts[2]; m.m41 = m.e = parts[4]; + m.m21 = m.c = parts[1]; m.m22 = m.d = parts[3]; m.m42 = m.f = parts[5]; + } else { + throw new TypeError('Invalid Matrix Value'); + } + return m; + }; + + /** + * The multiply method returns a new CSSMatrix which is the result of this + * matrix multiplied by the passed matrix, with the passed matrix to the right. + * This matrix is not modified. + * + * @param {CSSMatrix} m2 + * @return {CSSMatrix} The result matrix. + */ + CSSMatrix.prototype.multiply = function(m2){ + return CSSMatrix.multiply(this, m2); + }; + + /** + * The translate method returns a new matrix which is this matrix post + * multiplied by a translation matrix containing the passed values. If the z + * component is undefined, a 0 value is used in its place. This matrix is not + * modified. + * + * @param {number} x X component of the translation value. + * @param {number} y Y component of the translation value. + * @param {number=} z Z component of the translation value. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.translate = function(x, y, z){ + if (z == null) z = 0; + return CSSMatrix.multiply(this, CSSMatrix.Translate(x, y, z)); + }; + + /** + * The scale method returns a new matrix which is this matrix post multiplied by + * a scale matrix containing the passed values. If the z component is undefined, + * a 1 value is used in its place. If the y component is undefined, the x + * component value is used in its place. This matrix is not modified. + * + * @param {number} x The X component of the scale value. + * @param {number=} y The Y component of the scale value. + * @param {number=} z The Z component of the scale value. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.scale = function(x, y, z){ + if (y == null) y = x; + if (z == null) z = 1; + return CSSMatrix.multiply(this, CSSMatrix.Scale(x, y, z)); + }; + + /** + * The rotate method returns a new matrix which is this matrix post multiplied + * by each of 3 rotation matrices about the major axes, first X, then Y, then Z. + * If the y and z components are undefined, the x value is used to rotate the + * object about the z axis, as though the vector (0,0,x) were passed. All + * rotation values are in degrees. This matrix is not modified. + * + * @param {number} rx The X component of the rotation value, or the Z component if the rotY and rotZ parameters are undefined. + * @param {number=} ry The (optional) Y component of the rotation value. + * @param {number=} rz The (optional) Z component of the rotation value. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.rotate = function(rx, ry, rz){ + if (ry == null) ry = rx; + if (rz == null) rz = rx; + return CSSMatrix.multiply(this, CSSMatrix.Rotate(rx, ry, rz)); + }; + + /** + * The rotateAxisAngle method returns a new matrix which is this matrix post + * multiplied by a rotation matrix with the given axis and angle. The right-hand + * rule is used to determine the direction of rotation. All rotation values are + * in degrees. This matrix is not modified. + * + * @param {number} x The X component of the axis vector. + * @param {number=} y The Y component of the axis vector. + * @param {number=} z The Z component of the axis vector. + * @param {number} angle The angle of rotation about the axis vector, in degrees. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.rotateAxisAngle = function(x, y, z, angle){ + if (y == null) y = x; + if (z == null) z = x; + return CSSMatrix.multiply(this, CSSMatrix.RotateAxisAngle(x, y, z, angle)); + }; + + // Defined in WebKitCSSMatrix, but not in the w3c draft + + /** + * Specifies a skew transformation along the x-axis by the given angle. + * + * @param {number} angle The angle amount in degrees to skew. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.skewX = function(angle){ + return CSSMatrix.multiply(this, CSSMatrix.SkewX(angle)); + }; + + /** + * Specifies a skew transformation along the x-axis by the given angle. + * + * @param {number} angle The angle amount in degrees to skew. + * @return {CSSMatrix} The result matrix + */ + CSSMatrix.prototype.skewY = function(angle){ + return CSSMatrix.multiply(this, CSSMatrix.SkewY(angle)); + }; + + /** + * Returns a string representation of the matrix. + * @return {string} + */ + CSSMatrix.prototype.toString = function(){ + var m = this; + + if (this.affine){ + return 'matrix(' + [ + m.a, m.b, + m.c, m.d, + m.e, m.f + ].join(', ') + ')'; + } + // note: the elements here are transposed + return 'matrix3d(' + [ + m.m11, m.m12, m.m13, m.m14, + m.m21, m.m22, m.m23, m.m24, + m.m31, m.m32, m.m33, m.m34, + m.m41, m.m42, m.m43, m.m44 + ].join(', ') + ')'; + }; + + + // Additional methods + + /** + * Set the current matrix to the identity form + * + * @return {CSSMatrix} this matrix + */ + CSSMatrix.prototype.setIdentity = function(){ + var m = this; + m.m11 = m.a = 1; m.m12 = m.b = 0; m.m13 = 0; m.m14 = 0; + m.m21 = m.c = 0; m.m22 = m.d = 1; m.m23 = 0; m.m24 = 0; + m.m31 = 0; m.m32 = 0; m.m33 = 1; m.m34 = 0; + m.m41 = m.e = 0; m.m42 = m.f = 0; m.m43 = 0; m.m44 = 1; + return this; + }; + + /** + * Transform a tuple (3d point) with this CSSMatrix + * + * @param {Tuple} an object with x, y, z and w properties + * @return {Tuple} the passed tuple + */ + CSSMatrix.prototype.transform = function(t /* tuple */ ){ + var m = this; + + var x = m.m11 * t.x + m.m12 * t.y + m.m13 * t.z + m.m14 * t.w, + y = m.m21 * t.x + m.m22 * t.y + m.m23 * t.z + m.m24 * t.w, + z = m.m31 * t.x + m.m32 * t.y + m.m33 * t.z + m.m34 * t.w, + w = m.m41 * t.x + m.m42 * t.y + m.m43 * t.z + m.m44 * t.w; + + t.x = x / w; + t.y = y / w; + t.z = z / w; + + return t; + }; + + // CSSMatrix.prototype.toFullString = function(){ + // var m = this; + // return [ + // [m.m11, m.m12, m.m13, m.m14].join(', '), + // [m.m21, m.m22, m.m23, m.m24].join(', '), + // [m.m31, m.m32, m.m33, m.m34].join(', '), + // [m.m41, m.m42, m.m43, m.m44].join(', ') + // ].join('\n'); + // }; + + CSSMatrix.Perspective = function(d){ + var m = new CSSMatrix(); + m.m34 = -1/d; + return m; + }; + + + + /** + * The perspective method returns a new matrix which is this matrix post + * multiplied by a perspective matrix containing the passed values. If the + * y and z components are undefined, a 0 value is used in its place. + * + * @param {number} x X component of the perspective value. + * @param {number} y Y component of the perspective value. + * @param {number=} z Z component of the perspective value. + * @return {M} The result matrix + */ + CSSMatrix.prototype.perspective = function(d){ + return CSSMatrix.multiply(this, CSSMatrix.Perspective(d)); + }; + + CSSMatrix.toMat4 = function(out, a) { + if (!out) + out = new Array(16) + + out[0] = a[0] + out[1] = a[1] + out[2] = 0 + out[3] = 0 + out[4] = a[2] + out[5] = a[3] + out[6] = 0 + out[7] = 0 + out[8] = 0 + out[9] = 0 + out[10] = 1 + out[11] = 0 + out[12] = a[4] + out[13] = a[5] + out[14] = 0 + out[15] = 1 + return out + } + + CSSMatrix.prototype.toArray = function(p){ + if (p === 'matrix'){ + return [this.a, this.b, this.c, this.d, this.e, this.f]; + } else { + return [this.m11, this.m12, this.m13, this.m14, this.m21, this.m22, this.m23, this.m24, this.m31, this.m32, this.m33, this.m34, this.m41, this.m42, this.m43, this.m44]; + } + } + + K.pp['matrix'] = function(p,v,l){ + if ( !('matrix' in K.dom) ) { + K.dom['matrix'] = function(w,p,v) { + var m = [], i, l = w._vS[p].length, t = l===6 ? 'matrix' : 'matrix3d'; + for (i=0; i 0.001) { + L = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + L * bounciness, + H: curve.H * bounciness * bounciness + }; + } + return curve.b; + })(); + + (function() { + var L2, b, curve, _results; + b = Math.sqrt(2 / (gravity * L * L)); + curve = { + a: -b, + b: b, + H: 1 + }; + if (initialForce) { + curve.a = 0; + curve.b = curve.b * 2; + } + curves.push(curve); + L2 = L; + _results = []; + while (curve.b < 1 && curve.H > 0.001) { + L2 = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + L2 * bounciness, + H: curve.H * elasticity + }; + _results.push(curves.push(curve)); + } + return _results; + })(); + return function(t) { + var curve, i, v; + i = 0; + curve = curves[i]; + while (!(t >= curve.a && t <= curve.b)) { + i += 1; + curve = curves[i]; + if (!curve) { + break; + } + } + if (!curve) { + v = initialForce ? 0 : 1; + } else { + v = _kpg.getPointInCurve(curve.a, curve.b, curve.H, t, options, L); + } + return v; + }; + }; + + var _kpg = g.gravity.prototype; + _kpg.getPointInCurve = function(a, b, H, t, o, L) { + var c, t2; + L = b - a; + t2 = (2 / L) * t - 1 - (a * 2 / L); + c = t2 * t2 * H - H + 1; + if (o.initialForce) { + c = 1 - c; + } + return c; + }; + + //throw up and pull down by gravity + g.forceWithGravity = function(o) { + var ops = o || {}; + ops.initialForce = true; + return g.gravity(ops); + }; + + // multi point bezier + g.BezierMultiPoint = function(options) { + options = options || {}; + var points = options.points, + returnsToSelf = false, Bs = []; + + (function() { + var i, k; + + for (i in points) { + k = parseInt(i); + if (k >= points.length - 1) { + break; + } + _kpb.fn(points[k], points[k + 1], Bs); + } + return Bs; + })(); + + return function(t) { + if (t === 0) { + return 0; + } else if (t === 1) { + return 1; + } else { + return _kpb.yForX(t, Bs, returnsToSelf); + } + }; + }; + + var _kpb = g.BezierMultiPoint.prototype; + + _kpb.fn = function(pointA, pointB, Bs) { + var B2 = function(t) { + return _kpb.Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB); + }; + return Bs.push(B2); + }; + + _kpb.Bezier = function(t, p0, p1, p2, p3) { + return { + x: (Math.pow(1 - t, 3) * p0.x) + (3 * Math.pow(1 - t, 2) * t * p1.x) + (3 * (1 - t) * Math.pow(t, 2) * p2.x) + Math.pow(t, 3) * p3.x, + y: (Math.pow(1 - t, 3) * p0.y) + (3 * Math.pow(1 - t, 2) * t * p1.y) + (3 * (1 - t) * Math.pow(t, 2) * p2.y) + Math.pow(t, 3) * p3.y + }; + }; + + _kpb.yForX = function(xTarget, Bs, rTS) { + var B, aB, i, lower, percent, upper, x, xT, _i = 0, _len = Bs.length; + B = null; + for (_i; _i < _len; _i++) { + aB = Bs[_i]; + if (xTarget >= aB(0).x && xTarget <= aB(1).x) { + B = aB; + } + if (B !== null) { + break; + } + } + if (!B) { + return ( rTS ? 0 : 1 ); + } + xT = 0.0001; // xTolerance + lower = 0; upper = 1; + percent = (upper + lower) / 2; + x = B(percent).x; i = 0; + while (Math.abs(xTarget - x) > xT && i < 100) { + if (xTarget > x) { + lower = percent; + } else { + upper = percent; + } + percent = (upper + lower) / 2; + x = B(percent).x; + i++; + } + return B(percent).y; + }; + + // export predefined BezierMultiPoint functions to window + g.Physics = { + physicsInOut : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] } ] }); + }, + physicsIn : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 1, y: 1 } ] } ] }); + }, + physicsOut : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [ { x: 0, y: 0, cp: [ { x: 0, y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] }] }); + }, + physicsBackOut : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [{x:0,y:0,cp:[{x:0,y:0}]},{x:1,y:1,cp:[{x:0.735+(friction/1000),y:1.3}]}] }); + }, + physicsBackIn : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [{x:0,y:0,cp:[{x:0.28-(friction / 1000),y:-0.6}]},{x:1,y:1,cp:[{x:1,y:1}]}] }); + }, + physicsBackInOut : function(options) { + var friction; + options = options || {}; + friction = options.friction|| 200; + return g.BezierMultiPoint({ points: [{x:0,y:0,cp:[{x:0.68-(friction / 1000),y:-0.55}]},{x:1,y:1,cp:[{x:0.265+(friction / 1000),y:1.45}]}] }); + } + }; + +}); diff --git a/kute-textticker.js b/kute-textticker.js new file mode 100644 index 0000000..59f57d6 --- /dev/null +++ b/kute-textticker.js @@ -0,0 +1,63 @@ +/*! + * TextTickerPlugin.js + * version 1.0.0 + * A string character tweening + * special for KUTE.js + * by @dalisoft (https://github.com/dalisoft) + * Licensed under MIT-License + */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(["./kute.js"], function(KUTE){ factory(KUTE); return KUTE; }); + } else if(typeof module == "object" && typeof require == "function") { + var KUTE = require("./kute.js"); + module.exports = factory(KUTE); + } else if ( typeof window.KUTE !== 'undefined' ) { + factory(window.KUTE); + } else { + throw new Error("TextTicker-Plugin requires KUTE.js."); + } +}( function (KUTE) { + + function TextTicker( element, _a ) { + + return function ( _b ) { + + var len = Math.max(_a.length, _b.length); + + return function( value ) { + + var substr = Math.floor( Math.min( value * len, len ) ); + + element.innerHTML = _b.substring( 0, substr ) + _a.substr( substr ); + + }; + + } + +} + +KUTE.pp['text'] = function( prop, value, element ){ + + if ( typeof value === "string" ) { + + var t = TextTicker( element, element.innerHTML )( value ); + + if ( !( 'text' in KUTE.dom ) ) { + + KUTE.dom['text'] = function (elem, prop, value) { + + t(value); + } + + } + + } + + return this; + +} + + return this; + +})); diff --git a/package.json b/package.json deleted file mode 100644 index bdf657b..0000000 --- a/package.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "kute.js", - "version": "2.2.3", - "description": "JavaScript animation engine", - "main": "dist/kute.min.js", - "module": "dist/kute.esm.js", - "jsnext": "src/index.js", - "types": "types/index.d.ts", - "files": [ - "dist", - "types", - "src" - ], - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "help": "rollup --help", - "build1": "npm-run-all --parallel copy-build build-*", - "build": "npm run lint:js && npm-run-all --parallel copy-build build-*", - "custom": "rollup -c --environment", - "fix:js": "eslint src/ --config .eslintrc --fix", - "lint:js": "eslint src/ --config .eslintrc", - "copy-build": "rollup --environment OUTPUTFILE:demo/src/kute.min.js,DIST:standard,MIN:true,FORMAT:umd -c", - "build-standard": "rollup --environment DIST:standard,MIN:false,FORMAT:umd -c", - "build:ts": "tsc -d", - "build-standard-min": "rollup --environment DIST:standard,MIN:true,FORMAT:umd -c", - "build-standard-esm": "rollup --environment DIST:standard,MIN:false,FORMAT:esm -c", - "build-standard-esm-min": "rollup --environment DIST:standard,MIN:true,FORMAT:esm -c", - "build-base": "rollup --environment OUTPUTFILE:demo/src/kute-base.js,DIST:base,MIN:false,FORMAT:umd -c", - "build-base-min": "rollup --environment OUTPUTFILE:demo/src/kute-base.min.js,DIST:base,MIN:true,FORMAT:umd -c", - "build-extra": "rollup --environment OUTPUTFILE:demo/src/kute-extra.js,DIST:extra,MIN:false,FORMAT:umd -c", - "build-extra-min": "rollup --environment OUTPUTFILE:demo/src/kute-extra.min.js,DIST:extra,MIN:true,FORMAT:umd -c", - "polyfill": "npm-run-all --parallel polyfill-unminified polyfill-minified copy-polyfill copy-polyfill-legacy", - "copy-polyfill-legacy": "rollup --environment INPUTFILE:src/util/polyfill-legacy.js,OUTPUTFILE:demo/src/polyfill-legacy.min.js,MIN:true -c rollup.polyfill.js", - "copy-polyfill": "rollup --environment OUTPUTFILE:demo/src/polyfill.min.js,MIN:true -c rollup.polyfill.js", - "polyfill-unminified": "rollup --environment MIN:false -c rollup.polyfill.js", - "polyfill-minified": "rollup --environment MIN:true -c rollup.polyfill.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/thednp/kute.js.git" - }, - "keywords": [ - "kute.js", - "svg morph", - "svg transform", - "css3 transform", - "matrix transform", - "tweening engine", - "animation engine", - "javascript animation engine", - "javascript animation", - "animation", - "native javascript" - ], - "author": "thednp", - "license": "MIT", - "bugs": { - "url": "https://github.com/thednp/kute.js/issues" - }, - "homepage": "http://thednp.github.io/kute.js", - "dependencies": { - "cubic-bezier-easing": "^1.0.18", - "minifill": "^0.0.16", - "shorter-js": "^0.2.6", - "svg-path-commander": "0.1.23" - }, - "devDependencies": { - "@rollup/plugin-buble": "^0.21.3", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^9.0.0", - "eslint": "^7.22.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-vue": "^7.7.0", - "npm-run-all": "^4.1.5", - "rollup": "^2.38.4", - "rollup-plugin-terser": "^7.0.2", - "typescript": "^4.5.2" - } -} diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 7c71cce..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict' -import buble from '@rollup/plugin-buble' -import {terser} from 'rollup-plugin-terser' -import node from '@rollup/plugin-node-resolve' -import json from '@rollup/plugin-json' -import * as pkg from "./package.json" - - -let INPUTFILE = process.env.INPUTFILE -let OUTPUTFILE = process.env.OUTPUTFILE -const DIST = process.env.DIST // base|standard|extra -const NAME = DIST.charAt(0).toUpperCase() + DIST.slice(1); // Base|Standard|Extra -const MIN = process.env.MIN === 'true' // true/false|unset -const FORMAT = process.env.FORMAT // umd|iife|esm - -const year = (new Date).getFullYear() -const banner = -`/*! -* KUTE.js ${NAME} v${pkg.version} (${pkg.homepage}) -* Copyright 2015-${year} © ${pkg.author} -* Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) -*/` -const miniBanner = `// KUTE.js ${NAME} v${pkg.version} | ${pkg.author} © ${year} | ${pkg.license}-License` - -INPUTFILE = INPUTFILE ? INPUTFILE : (DIST === 'standard' ? 'src/index.js' : 'src/index-'+DIST+'.js') -OUTPUTFILE = OUTPUTFILE ? OUTPUTFILE : ('dist/kute'+(DIST!=='standard'?'-'+DIST:'')+(FORMAT==='esm'?'.esm':'')+(MIN?'.min':'')+'.js') - -const OUTPUT = { - file: OUTPUTFILE, - format: FORMAT, // or iife -} - -const PLUGINS = [ - node({mainFields: ['jsnext','module'], dedupe: ['svg-path-commander']}) , - json(), -] - -if (FORMAT!=='esm'){ - PLUGINS.push(buble({objectAssign: 'Object.assign'})); -} - -if (MIN){ - PLUGINS.push(terser({output: {preamble: miniBanner}})); -} else { - OUTPUT.banner = banner; -} - -if (FORMAT!=='esm') { - OUTPUT.name = 'KUTE'; -} - -export default [ - { - input: INPUTFILE, - output: OUTPUT, - plugins: PLUGINS - } -] diff --git a/rollup.polyfill.js b/rollup.polyfill.js deleted file mode 100644 index 89f9f09..0000000 --- a/rollup.polyfill.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict' -import buble from '@rollup/plugin-buble' -import node from '@rollup/plugin-node-resolve' -import json from '@rollup/plugin-json' -import {terser} from 'rollup-plugin-terser' -import * as pkg from "./package.json"; - -// set headers -const year = (new Date).getFullYear() -const banner = `/*! - * KUTE.js Polyfill v${pkg.version} (${pkg.homepage}) - * Copyright 2015-${year} © ${pkg.author} - * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) - */ - "use strict";` - -const miniBanner = `// KUTE.js Polyfill v${pkg.version} | ${year} © ${pkg.author} | ${pkg.license}-License -"use strict";` - -// set config -const MIN = process.env.MIN === 'true' // true/false|unset -const FORMAT = 'esm' // umd|iife|esm|cjs - -const INPUTFILE = process.env.INPUTFILE ? process.env.INPUTFILE : 'src/util/polyfill.js' -const OUTPUTFILE = process.env.OUTPUTFILE ? process.env.OUTPUTFILE : 'dist/polyfill'+(MIN?'.min':'')+'.js' - -const OUTPUT = { - file: OUTPUTFILE, - format: FORMAT, // or iife -} - -const PLUGINS = [ - node(), - json(), - buble(), -] - -if (MIN){ - PLUGINS.push(terser({output: {preamble: miniBanner}})); -} else { - OUTPUT.banner = banner; -} - -// if (FORMAT!=='esm') { -// OUTPUT.name = 'BSN'; -// } - -export default [ - { - input: INPUTFILE, - output: OUTPUT, - plugins: PLUGINS - } -] \ No newline at end of file diff --git a/src/animation/animation.js b/src/animation/animation.js deleted file mode 100644 index f221c76..0000000 --- a/src/animation/animation.js +++ /dev/null @@ -1,137 +0,0 @@ -import supportedProperties from '../objects/supportedProperties'; -import defaultValues from '../objects/defaultValues'; -import defaultOptions from '../objects/defaultOptions'; -import prepareProperty from '../objects/prepareProperty'; -import prepareStart from '../objects/prepareStart'; -import onStart from '../objects/onStart'; -import onComplete from '../objects/onComplete'; -import crossCheck from '../objects/crossCheck'; -import linkProperty from '../objects/linkProperty'; -import Util from '../objects/util'; -import Interpolate from '../objects/interpolate'; - -/** - * Animation Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - */ -export default class Animation { - /** - * @constructor - * @param {KUTE.fullComponent} Component - */ - constructor(Component) { - try { - if (Component.component in supportedProperties) { - throw Error(`KUTE - ${Component.component} already registered`); - } else if (Component.property in defaultValues) { - throw Error(`KUTE - ${Component.property} already registered`); - } - } catch (e) { - throw Error(e); - } - - const propertyInfo = this; - const ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - const Functions = { - prepareProperty, prepareStart, onStart, onComplete, crossCheck, - }; - const Category = Component.category; - const Property = Component.property; - const Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // single property - // {property,defaultvalue,defaultOptions,Interpolate,functions} - - // category colors, boxModel, borderRadius - // {category,properties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg transform, filter - // {property,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // property with multiple sub properties. Eg htmlAttributes - // {category,subProperties,defaultvalues,defaultOptions,Interpolate,functions} - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - defaultValues[Property] = Component.defaultValue; - - // minimal info - propertyInfo.supports = `${Property} property`; - } else if (Component.defaultValues) { - Object.keys(Component.defaultValues).forEach((dv) => { - defaultValues[dv] = Component.defaultValues[dv]; - }); - - // minimal info - propertyInfo.supports = `${Length || Property} ${Property || Category} properties`; - } - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach((fn) => { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach((ofn) => { - // !Functions[fn][ofn] && (Functions[fn][ofn] = Component.functions[fn][ofn]) - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][ofn]) { - Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]; - } - }); - } - } - }); - } - - // set component interpolation functions - if (Component.Interpolate) { - Object.keys(Component.Interpolate).forEach((fni) => { - const compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !Interpolate[fni]) { - Interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach((sfn) => { - if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) { - Interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach((fnu) => { - if (!Util[fnu]) Util[fnu] = Component.Util[fnu]; - }); - } - - return propertyInfo; - } -} diff --git a/src/animation/animationBase.js b/src/animation/animationBase.js deleted file mode 100644 index ae3d763..0000000 --- a/src/animation/animationBase.js +++ /dev/null @@ -1,97 +0,0 @@ -import supportedProperties from '../objects/supportedProperties'; -import defaultOptions from '../objects/defaultOptions'; -import onStart from '../objects/onStart'; -import onComplete from '../objects/onComplete'; -import linkProperty from '../objects/linkProperty'; -import Util from '../objects/util'; -import Interpolate from '../objects/interpolate'; - -/** - * Animation Base Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * This class only registers the minimal amount of component information - * required to enable components animation, which means value processing - * as well as `to()` and `allTo()` methods are not supported. - */ -export default class AnimationBase { - /** - * @class - * @param {KUTE.baseComponent} Component - */ - constructor(Component) { - const ComponentName = Component.component; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty } - const Functions = { onStart, onComplete }; - const Category = Component.category; - const Property = Component.property; - // ESLint - this._ = 0; - - // set supported category/property - supportedProperties[ComponentName] = Component.properties - || Component.subProperties || Component.property; - - // set additional options - if (Component.defaultOptions) { - // Object.keys(Component.defaultOptions).forEach((op) => { - // defaultOptions[op] = Component.defaultOptions[op]; - // }); - Object.assign(defaultOptions, Component.defaultOptions); - } - - // set functions - if (Component.functions) { - Object.keys(Functions).forEach((fn) => { - if (fn in Component.functions) { - if (typeof (Component.functions[fn]) === 'function') { - // if (!Functions[fn][ Category||Property ]) { - // Functions[fn][ Category||Property ] = Component.functions[fn]; - // } - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][Category || Property]) { - Functions[fn][ComponentName][Category || Property] = Component.functions[fn]; - } - } else { - Object.keys(Component.functions[fn]).forEach((ofn) => { - // if (!Functions[fn][ofn]) Functions[fn][ofn] = Component.functions[fn][ofn]; - if (!Functions[fn][ComponentName]) Functions[fn][ComponentName] = {}; - if (!Functions[fn][ComponentName][ofn]) { - Functions[fn][ComponentName][ofn] = Component.functions[fn][ofn]; - } - }); - } - } - }); - } - - // set interpolate - if (Component.Interpolate) { - Object.keys(Component.Interpolate).forEach((fni) => { - const compIntObj = Component.Interpolate[fni]; - if (typeof (compIntObj) === 'function' && !Interpolate[fni]) { - Interpolate[fni] = compIntObj; - } else { - Object.keys(compIntObj).forEach((sfn) => { - if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) { - Interpolate[fni] = compIntObj[sfn]; - } - }); - } - }); - - linkProperty[ComponentName] = Component.Interpolate; - } - - // set component util - if (Component.Util) { - Object.keys(Component.Util).forEach((fnu) => { - if (!Util[fnu]) Util[fnu] = Component.Util[fnu]; - }); - } - - return { name: ComponentName }; - } -} diff --git a/src/animation/animationDevelopment.js b/src/animation/animationDevelopment.js deleted file mode 100644 index dc067d4..0000000 --- a/src/animation/animationDevelopment.js +++ /dev/null @@ -1,137 +0,0 @@ -import prepareProperty from '../objects/prepareProperty'; -import prepareStart from '../objects/prepareStart'; -import onStart from '../objects/onStart'; -import onComplete from '../objects/onComplete'; -import crossCheck from '../objects/crossCheck'; -import Interpolate from '../objects/interpolate'; - -import Animation from './animation'; - -/** - * Animation Development Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * In addition to the default class, this one provides more component - * information to help you with custom component development. - */ -export default class AnimationDevelopment extends Animation { - /** - * - * @param {KUTE.fullComponent} args - */ - constructor(Component) { - super(Component); - - const propertyInfo = this; - // const Objects = { defaultValues, defaultOptions, Interpolate, linkProperty, Util } - const Functions = { - prepareProperty, prepareStart, onStart, onComplete, crossCheck, - }; - const Category = Component.category; - const Property = Component.property; - const Length = (Component.properties && Component.properties.length) - || (Component.subProperties && Component.subProperties.length); - - // set defaultValues - if ('defaultValue' in Component) { // value 0 will invalidate - propertyInfo.supports = `${Property} property`; - propertyInfo.defaultValue = `${(`${Component.defaultValue}`).length ? 'YES' : 'not set or incorrect'}`; - } else if (Component.defaultValues) { - propertyInfo.supports = `${Length || Property} ${Property || Category} properties`; - propertyInfo.defaultValues = Object.keys(Component.defaultValues).length === Length ? 'YES' : 'Not set or incomplete'; - } - - // set additional options - if (Component.defaultOptions) { - propertyInfo.extends = []; - - Object.keys(Component.defaultOptions).forEach((op) => { - propertyInfo.extends.push(op); - }); - - if (propertyInfo.extends.length) { - propertyInfo.extends = `with <${propertyInfo.extends.join(', ')}> new option(s)`; - } else { - delete propertyInfo.extends; - } - } - - // set functions - if (Component.functions) { - propertyInfo.interface = []; - propertyInfo.render = []; - propertyInfo.warning = []; - - Object.keys(Functions).forEach((fnf) => { - if (fnf in Component.functions) { - if (fnf === 'prepareProperty') propertyInfo.interface.push('fromTo()'); - if (fnf === 'prepareStart') propertyInfo.interface.push('to()'); - if (fnf === 'onStart') propertyInfo.render = 'can render update'; - } else { - if (fnf === 'prepareProperty') propertyInfo.warning.push('fromTo()'); - if (fnf === 'prepareStart') propertyInfo.warning.push('to()'); - if (fnf === 'onStart') propertyInfo.render = 'no function to render update'; - } - }); - - if (propertyInfo.interface.length) { - propertyInfo.interface = `${Category || Property} can use [${propertyInfo.interface.join(', ')}] method(s)`; - } else { - delete propertyInfo.uses; - } - - if (propertyInfo.warning.length) { - propertyInfo.warning = `${Category || Property} can't use [${propertyInfo.warning.join(', ')}] method(s) because values aren't processed`; - } else { - delete propertyInfo.warning; - } - } - - // register Interpolation functions - if (Component.Interpolate) { - propertyInfo.uses = []; - propertyInfo.adds = []; - - Object.keys(Component.Interpolate).forEach((fni) => { - const compIntObj = Component.Interpolate[fni]; - // register new Interpolation functions - if (typeof (compIntObj) === 'function') { - if (!Interpolate[fni]) { - propertyInfo.adds.push(`${fni}`); - } - propertyInfo.uses.push(`${fni}`); - } else { - Object.keys(compIntObj).forEach((sfn) => { - if (typeof (compIntObj[sfn]) === 'function' && !Interpolate[fni]) { - propertyInfo.adds.push(`${sfn}`); - } - propertyInfo.uses.push(`${sfn}`); - }); - } - }); - - if (propertyInfo.uses.length) { - propertyInfo.uses = `[${propertyInfo.uses.join(', ')}] interpolation function(s)`; - } else { - delete propertyInfo.uses; - } - - if (propertyInfo.adds.length) { - propertyInfo.adds = `new [${propertyInfo.adds.join(', ')}] interpolation function(s)`; - } else { - delete propertyInfo.adds; - } - } else { - propertyInfo.critical = `For ${Property || Category} no interpolation function[s] is set`; - } - - // set component util - if (Component.Util) { - propertyInfo.hasUtil = Object.keys(Component.Util).join(','); - } - - return propertyInfo; - } -} diff --git a/src/components/backgroundPosition.js b/src/components/backgroundPosition.js deleted file mode 100644 index d6cb99b..0000000 --- a/src/components/backgroundPosition.js +++ /dev/null @@ -1,57 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import numbers from '../interpolation/numbers'; -import trueDimension from '../util/trueDimension'; -import { onStartBgPos } from './backgroundPositionBase'; - -// Component Functions - -/** - * Returns the property computed style. - * @param {string} prop the property - * @returns {string} the property computed style - */ -function getBgPos(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ -function prepareBgPos(/* prop, */_, value) { - if (value instanceof Array) { - const x = trueDimension(value[0]).v; - const y = trueDimension(value[1]).v; - return [!Number.isNaN(x * 1) ? x : 50, !Number.isNaN(y * 1) ? y : 50]; - } - - let posxy = value.replace(/top|left/g, 0) - .replace(/right|bottom/g, 100) - .replace(/center|middle/g, 50); - - posxy = posxy.split(/(,|\s)/g); - posxy = posxy.length === 2 ? posxy : [posxy[0], 50]; - return [trueDimension(posxy[0]).v, trueDimension(posxy[1]).v]; -} - -// All Component Functions -const bgPositionFunctions = { - prepareStart: getBgPos, - prepareProperty: prepareBgPos, - onStart: onStartBgPos, -}; - -// Component Full Object -const BackgroundPosition = { - component: 'backgroundPositionProp', - property: 'backgroundPosition', - defaultValue: [50, 50], - Interpolate: { numbers }, - functions: bgPositionFunctions, - Util: { trueDimension }, -}; - -export default BackgroundPosition; diff --git a/src/components/backgroundPositionBase.js b/src/components/backgroundPositionBase.js deleted file mode 100644 index 5105372..0000000 --- a/src/components/backgroundPositionBase.js +++ /dev/null @@ -1,26 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions -/** - * Sets the property update function. - * @param {string} prop the property name - */ -export function onStartBgPos(prop) { - if (this.valuesEnd[prop] && !KEC[prop]) { - KEC[prop] = (elem, a, b, v) => { - /* eslint-disable -- no-bitwise & no-param-reassign impossible to satisfy */ - elem.style[prop] = `${(numbers(a[0], b[0], v) * 100 >> 0) / 100}% ${((numbers(a[1], b[1], v) * 100 >> 0) / 100)}%`; - /* eslint-enable -- no-bitwise & no-param-reassign impossible to satisfy */ - }; - } -} - -// Component Base Object -const BackgroundPositionBase = { - component: 'baseBackgroundPosition', - property: 'backgroundPosition', - Interpolate: { numbers }, - functions: { onStart: onStartBgPos }, -}; -export default BackgroundPositionBase; diff --git a/src/components/borderRadius.js b/src/components/borderRadius.js deleted file mode 100644 index 17cef65..0000000 --- a/src/components/borderRadius.js +++ /dev/null @@ -1,58 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueDimension from '../util/trueDimension'; -import units from '../interpolation/units'; -import { radiusOnStartFn } from './borderRadiusBase'; - -// Component Properties -const radiusProps = [ - 'borderRadius', - 'borderTopLeftRadius', 'borderTopRightRadius', - 'borderBottomLeftRadius', 'borderBottomRightRadius']; - -const radiusValues = {}; -radiusProps.forEach((x) => { radiusValues[x] = 0; }); - -// Component Functions -const radiusOnStart = {}; -radiusProps.forEach((tweenProp) => { - radiusOnStart[tweenProp] = radiusOnStartFn; -}); - -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} the property computed style - */ -export function getRadius(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} value the property value - * @returns {{v: number, u: string}} the property tween object - */ -export function prepareRadius(/* tweenProp, */_, value) { - return trueDimension(value); -} - -// All Component Functions -export const radiusFunctions = { - prepareStart: getRadius, - prepareProperty: prepareRadius, - onStart: radiusOnStart, -}; - -// Full Component -const BorderRadius = { - component: 'borderRadiusProperties', - category: 'borderRadius', - properties: radiusProps, - defaultValues: radiusValues, - Interpolate: { units }, - functions: radiusFunctions, - Util: { trueDimension }, -}; - -export default BorderRadius; diff --git a/src/components/borderRadiusBase.js b/src/components/borderRadiusBase.js deleted file mode 100644 index 1a48e4e..0000000 --- a/src/components/borderRadiusBase.js +++ /dev/null @@ -1,43 +0,0 @@ -import KEC from '../objects/kute'; -import units from '../interpolation/units'; - -/* borderRadius = { - category: 'borderRadius', - properties : [..], - defaultValues: {..}, - interpolation: {units} -} */ - -// Component Properties -const radiusProps = [ - 'borderRadius', - 'borderTopLeftRadius', 'borderTopRightRadius', - 'borderBottomLeftRadius', 'borderBottomRightRadius', -]; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function radiusOnStartFn(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = units(a.v, b.v, b.u, v); - }; - } -} -const radiusOnStart = {}; -radiusProps.forEach((tweenProp) => { - radiusOnStart[tweenProp] = radiusOnStartFn; -}); - -// Base Component -const BorderRadiusBase = { - component: 'baseBorderRadius', - category: 'borderRadius', - Interpolate: { units }, - functions: { onStart: radiusOnStart }, -}; -export default BorderRadiusBase; diff --git a/src/components/boxModel.js b/src/components/boxModel.js deleted file mode 100644 index f40ac9e..0000000 --- a/src/components/boxModel.js +++ /dev/null @@ -1,57 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueDimension from '../util/trueDimension'; -import numbers from '../interpolation/numbers'; -import { boxModelOnStart } from './boxModelBase'; - -// Component Properties -const boxModelProperties = ['top', 'left', 'width', 'height', 'right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', - 'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', - 'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', - 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'outlineWidth']; - -const boxModelValues = {}; -boxModelProperties.forEach((x) => { boxModelValues[x] = 0; }); - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -function getBoxModel(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ -function prepareBoxModel(tweenProp, value) { - const boxValue = trueDimension(value); const - offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; - return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v; -} -const boxPropsOnStart = {}; -boxModelProperties.forEach((x) => { boxPropsOnStart[x] = boxModelOnStart; }); - -// All Component Functions -const boxModelFunctions = { - prepareStart: getBoxModel, - prepareProperty: prepareBoxModel, - onStart: boxPropsOnStart, -}; - -// Component Full Component -const BoxModel = { - component: 'boxModelProperties', - category: 'boxModel', - properties: boxModelProperties, - defaultValues: boxModelValues, - Interpolate: { numbers }, - functions: boxModelFunctions, -}; - -export default BoxModel; diff --git a/src/components/boxModelBase.js b/src/components/boxModelBase.js deleted file mode 100644 index 40b5ef6..0000000 --- a/src/components/boxModelBase.js +++ /dev/null @@ -1,37 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions -/** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ -export function boxModelOnStart(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - /* eslint-disable no-bitwise -- impossible to satisfy */ - elem.style[tweenProp] = `${v > 0.99 || v < 0.01 - ? ((numbers(a, b, v) * 10) >> 0) / 10 - : (numbers(a, b, v)) >> 0}px`; - /* eslint-enable no-bitwise */ - /* eslint-enable no-param-reassign */ - }; - } -} - -// Component Base Props -const baseBoxProps = ['top', 'left', 'width', 'height']; -const baseBoxOnStart = {}; -baseBoxProps.forEach((x) => { baseBoxOnStart[x] = boxModelOnStart; }); - -// Component Base -const BoxModelBase = { - component: 'baseBoxModel', - category: 'boxModel', - properties: baseBoxProps, - Interpolate: { numbers }, - functions: { onStart: baseBoxOnStart }, -}; - -export default BoxModelBase; diff --git a/src/components/boxModelEssential.js b/src/components/boxModelEssential.js deleted file mode 100644 index ff0fbed..0000000 --- a/src/components/boxModelEssential.js +++ /dev/null @@ -1,56 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueDimension from '../util/trueDimension'; -import numbers from '../interpolation/numbers'; -import { boxModelOnStart } from './boxModelBase'; - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -function getBoxModel(tweenProp) { - return getStyleForProperty(this.element, tweenProp) || defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property name - * @returns {number} the property tween object - */ -function prepareBoxModel(tweenProp, value) { - const boxValue = trueDimension(value); - const offsetProp = tweenProp === 'height' ? 'offsetHeight' : 'offsetWidth'; - return boxValue.u === '%' ? (boxValue.v * this.element[offsetProp]) / 100 : boxValue.v; -} - -// Component Base Props -const essentialBoxProps = ['top', 'left', 'width', 'height']; -const essentialBoxPropsValues = { - top: 0, left: 0, width: 0, height: 0, -}; - -const essentialBoxOnStart = {}; -essentialBoxProps.forEach((x) => { essentialBoxOnStart[x] = boxModelOnStart; }); - -// All Component Functions -const essentialBoxModelFunctions = { - prepareStart: getBoxModel, - prepareProperty: prepareBoxModel, - onStart: essentialBoxOnStart, -}; - -// Component Essential -const BoxModelEssential = { - component: 'essentialBoxModel', - category: 'boxModel', - properties: essentialBoxProps, - defaultValues: essentialBoxPropsValues, - Interpolate: { numbers }, - functions: essentialBoxModelFunctions, - Util: { trueDimension }, -}; - -export default BoxModelEssential; diff --git a/src/components/clipProperty.js b/src/components/clipProperty.js deleted file mode 100644 index d833ad9..0000000 --- a/src/components/clipProperty.js +++ /dev/null @@ -1,52 +0,0 @@ -import getStyleForProperty from '../process/getStyleForProperty'; -import trueDimension from '../util/trueDimension'; -import numbers from '../interpolation/numbers'; -import { onStartClip } from './clipPropertyBase'; - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string | number[]} computed style for property - */ -function getClip(tweenProp/* , value */) { - const { element } = this; - const currentClip = getStyleForProperty(element, tweenProp); - const width = getStyleForProperty(element, 'width'); - const height = getStyleForProperty(element, 'height'); - return !/rect/.test(currentClip) ? [0, width, height, 0] : currentClip; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ -function prepareClip(/* tweenProp, */_, value) { - if (value instanceof Array) { - return value.map((x) => trueDimension(x)); - } - let clipValue = value.replace(/rect|\(|\)/g, ''); - clipValue = /,/g.test(clipValue) ? clipValue.split(',') : clipValue.split(/\s/); - return clipValue.map((x) => trueDimension(x)); -} - -// All Component Functions -const clipFunctions = { - prepareStart: getClip, - prepareProperty: prepareClip, - onStart: onStartClip, -}; - -// Component Full -const ClipProperty = { - component: 'clipProperty', - property: 'clip', - defaultValue: [0, 0, 0, 0], - Interpolate: { numbers }, - functions: clipFunctions, - Util: { trueDimension }, -}; - -export default ClipProperty; diff --git a/src/components/clipPropertyBase.js b/src/components/clipPropertyBase.js deleted file mode 100644 index af1f807..0000000 --- a/src/components/clipPropertyBase.js +++ /dev/null @@ -1,36 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartClip(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - let h = 0; const - cl = []; - for (h; h < 4; h += 1) { - const c1 = a[h].v; - const c2 = b[h].v; - const cu = b[h].u || 'px'; - // eslint-disable-next-line no-bitwise -- impossible to satisfy - cl[h] = ((numbers(c1, c2, v) * 100 >> 0) / 100) + cu; - } - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.clip = `rect(${cl})`; - }; - } -} - -// Component Base -const ClipPropertyBase = { - component: 'baseClip', - property: 'clip', - // defaultValue: [0,0,0,0], - Interpolate: { numbers }, - functions: { onStart: onStartClip }, -}; - -export default ClipPropertyBase; diff --git a/src/components/colorProperties.js b/src/components/colorProperties.js deleted file mode 100644 index 7aed613..0000000 --- a/src/components/colorProperties.js +++ /dev/null @@ -1,65 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueColor from '../util/trueColor'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; -import { onStartColors } from './colorPropertiesBase'; - -// Component Properties -// supported formats -// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) -const supportedColors = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor', -]; - -const defaultColors = {}; -supportedColors.forEach((tweenProp) => { - defaultColors[tweenProp] = '#000'; -}); - -// Component Functions -const colorsOnStart = {}; -supportedColors.forEach((x) => { - colorsOnStart[x] = onStartColors; -}); - -/** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} property computed style - */ -function getColor(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.colorObject} the property tween object - */ -function prepareColor(/* prop, */_, value) { - return trueColor(value); -} - -// All Component Functions -const colorFunctions = { - prepareStart: getColor, - prepareProperty: prepareColor, - onStart: colorsOnStart, -}; - -// Component Full -const colorProperties = { - component: 'colorProperties', - category: 'colors', - properties: supportedColors, - defaultValues: defaultColors, - Interpolate: { numbers, colors }, - functions: colorFunctions, - Util: { trueColor }, -}; - -export default colorProperties; diff --git a/src/components/colorPropertiesBase.js b/src/components/colorPropertiesBase.js deleted file mode 100644 index 7b4d2e8..0000000 --- a/src/components/colorPropertiesBase.js +++ /dev/null @@ -1,45 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; - -// Component Interpolation -// rgba1, rgba2, progress - -// Component Properties -// supported formats -// 'hex', 'rgb', 'rgba' '#fff' 'rgb(0,0,0)' / 'rgba(0,0,0,0)' 'red' (IE9+) -const supportedColors = [ - 'color', 'backgroundColor', 'outlineColor', - 'borderColor', - 'borderTopColor', 'borderRightColor', - 'borderBottomColor', 'borderLeftColor', -]; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartColors(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = colors(a, b, v); - }; - } -} - -const colorsOnStart = {}; -supportedColors.forEach((x) => { colorsOnStart[x] = onStartColors; }); - -// Component Base -export const baseColors = { - component: 'baseColors', - category: 'colors', - // properties: supportedColors, - // defaultValues: defaultColors, - Interpolate: { numbers, colors }, - functions: { onStart: colorsOnStart }, -}; - -export default baseColors; diff --git a/src/components/crossBrowserMove.js b/src/components/crossBrowserMove.js deleted file mode 100644 index dea762d..0000000 --- a/src/components/crossBrowserMove.js +++ /dev/null @@ -1,95 +0,0 @@ -import KEC from '../objects/kute'; -import getInlineStyle from '../process/getInlineStyle'; -import defaultValues from '../objects/defaultValues'; -import trueProperty from '../util/trueProperty'; -import numbers from '../interpolation/numbers'; - -// Component Const -const transformProperty = trueProperty('transform'); -const supportTransform = transformProperty in document.body.style ? 1 : 0; - -// Component Functions -/** - * Returns the property current style. - */ -function getComponentCurrentValue(/* tweenProp, value */) { - const currentTransform = getInlineStyle(this.element); - const { left } = this.element.style; - const { top } = this.element.style; - let x = 0; - let y = 0; - - if (supportTransform && currentTransform.translate) { - [x, y] = currentTransform.translate; - } else { - x = Number.isFinite(left * 1) ? left : defaultValues.move[0]; - y = Number.isFinite(top * 1) ? top : defaultValues.move[1]; - } - - return [x, y]; -} -/** - * Returns the property tween object. - * @param {string} _ property name - * @param {string} value property value - * @returns {number[]} the property tween object - */ -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]; -} - -/** - * Sets the property update function. - * @param {string} tweenProp the `path` property - */ -export function onStartComponent(tweenProp/* , value */) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - if (supportTransform) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable-next-line no-param-reassign -- impossible to satisfy */ - elem.style[transformProperty] = `translate(${numbers(a[0], b[0], v)}px,${numbers(a[1], b[1], v)}px)`; - }; - } else { - KEC[tweenProp] = (elem, a, b, v) => { - if (a[0] || b[0]) { - /* eslint-disable-next-line no-param-reassign -- impossible to satisfy */ - elem.style.left = `${numbers(a[0], b[0], v)}px`; - } - if (a[1] || b[1]) { - /* eslint-disable-next-line no-param-reassign -- impossible to satisfy */ - elem.style.top = `${numbers(a[1], b[1], v)}px`; - } - }; - } - } -} - -// All Component Functions -const componentFunctions = { - prepareStart: getComponentCurrentValue, - prepareProperty: prepareComponentValue, - onStart: onStartComponent, -}; - -// Base Component -export const baseCrossBrowserMove = { - component: 'baseCrossBrowserMove', - property: 'move', - Interpolate: { numbers }, - functions: { onStart: onStartComponent }, -}; - -// Full Component -const crossBrowserMove = { - component: 'crossBrowserMove', - property: 'move', - defaultValue: [0, 0], - Interpolate: { numbers }, - functions: componentFunctions, - Util: { trueProperty }, -}; - -export default crossBrowserMove; diff --git a/src/components/filterEffects.js b/src/components/filterEffects.js deleted file mode 100644 index 0294f59..0000000 --- a/src/components/filterEffects.js +++ /dev/null @@ -1,201 +0,0 @@ -import getStyleForProperty from '../process/getStyleForProperty'; -import defaultValues from '../objects/defaultValues'; -import trueColor from '../util/trueColor'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; -import { dropshadow, onStartFilter } from './filterEffectsBase'; - -/* filterEffects = { - property: 'filter', - subProperties: {}, - defaultValue: {}, - interpolators: {}, - functions = { prepareStart, prepareProperty, onStart, crossCheck } -} */ - -// Component Util -/** - * Returns camelCase filter sub-property. - * @param {string} str source string - * @returns {string} camelCase property name - */ -function replaceDashNamespace(str) { - return str.replace('-r', 'R').replace('-s', 'S'); -} - -/** - * Returns `drop-shadow` sub-property object. - * @param {(string | number)[]} shadow and `Array` with `drop-shadow` parameters - * @returns {KUTE.filterList['dropShadow']} the expected `drop-shadow` values - */ -function parseDropShadow(shadow) { - let newShadow; - - if (shadow.length === 3) { // [h-shadow, v-shadow, color] - newShadow = [shadow[0], shadow[1], 0, shadow[2]]; - } else if (shadow.length === 4) { // ideal [, , , ] - newShadow = [shadow[0], shadow[1], shadow[2], shadow[3]]; - } - - // make sure the values are ready to tween - for (let i = 0; i < 3; i += 1) { - newShadow[i] = parseFloat(newShadow[i]); - } - // also the color must be a rgb object - newShadow[3] = trueColor(newShadow[3]); - return newShadow; -} - -/** - * Returns an array with current filter sub-properties values. - * @param {string} currentStyle the current filter computed style - * @returns {{[x: string]: number}} the filter tuple - */ -function parseFilterString(currentStyle) { - const result = {}; - const fnReg = /(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g; - const matches = currentStyle.match(fnReg); - const fnArray = currentStyle !== 'none' ? matches : 'none'; - - if (fnArray instanceof Array) { - for (let j = 0, jl = fnArray.length; j < jl; j += 1) { - const p = fnArray[j].trim().split(/\((.+)/); - const pp = replaceDashNamespace(p[0]); - if (pp === 'dropShadow') { - const shadowColor = p[1].match(/(([a-z].*?)\(.*?\))(?=\s(.*?))/)[0]; - const params = p[1].replace(shadowColor, '').split(/\s/).map(parseFloat); - result[pp] = params.filter((el) => !Number.isNaN(el)).concat(shadowColor); - } else { - result[pp] = p[1].replace(/'|"|\)/g, ''); - } - } - } - - return result; -} - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {string} computed style for property - */ -function getFilter(tweenProp, value) { - const currentStyle = getStyleForProperty(this.element, tweenProp); - const filterObject = parseFilterString(currentStyle); - let fnp; - - Object.keys(value).forEach((fn) => { - fnp = replaceDashNamespace(fn); - if (!filterObject[fnp]) { - filterObject[fnp] = defaultValues[tweenProp][fn]; - } - }); - - return filterObject; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property name - * @returns {KUTE.filterList} the property tween object - */ -function prepareFilter(/* tweenProp, */_, value) { - const filterObject = {}; - let fnp; - - // property: range | default - // opacity: [0-100%] | 100 - // blur: [0-Nem] | 0 - // saturate: [0-N%] | 100 - // invert: [0-100%] | 0 - // grayscale: [0-100%] | 0 - // brightness: [0-N%] | 100 - // contrast: [0-N%] | 100 - // sepia: [0-N%] | 0 - // 'hueRotate': [0-Ndeg] | 0 - // 'dropShadow': [0,0,0,(r:0,g:0,b:0)] | 0 - // url: '' | '' - - Object.keys(value).forEach((fn) => { - fnp = replaceDashNamespace(fn); - if (/hue/.test(fn)) { - filterObject[fnp] = parseFloat(value[fn]); - } else if (/drop/.test(fn)) { - filterObject[fnp] = parseDropShadow(value[fn]); - } else if (fn === 'url') { - filterObject[fn] = value[fn]; - // } else if ( /blur|opacity|grayscale|sepia/.test(fn) ) { - } else { - filterObject[fn] = parseFloat(value[fn]); - } - }); - - return filterObject; -} - -/** - * Adds missing sub-properties in `valuesEnd` from `valuesStart`. - * @param {string} tweenProp the property name - */ -function crossCheckFilter(tweenProp) { - if (this.valuesEnd[tweenProp]) { - Object.keys(this.valuesStart[tweenProp]).forEach((fn) => { - if (!this.valuesEnd[tweenProp][fn]) { - this.valuesEnd[tweenProp][fn] = this.valuesStart[tweenProp][fn]; - } - }); - } -} - -// All Component Functions -const filterFunctions = { - prepareStart: getFilter, - prepareProperty: prepareFilter, - onStart: onStartFilter, - crossCheck: crossCheckFilter, -}; - -// Full Component -const filterEffects = { - component: 'filterEffects', - property: 'filter', - // opacity function interfere with opacityProperty - // subProperties: [ - // 'blur', 'brightness','contrast','dropShadow', - // 'hueRotate','grayscale','invert','opacity','saturate','sepia','url' - // ], - defaultValue: { - opacity: 100, - blur: 0, - saturate: 100, - grayscale: 0, - brightness: 100, - contrast: 100, - sepia: 0, - invert: 0, - hueRotate: 0, - dropShadow: [0, 0, 0, { r: 0, g: 0, b: 0 }], - url: '', - }, - Interpolate: { - opacity: numbers, - blur: numbers, - saturate: numbers, - grayscale: numbers, - brightness: numbers, - contrast: numbers, - sepia: numbers, - invert: numbers, - hueRotate: numbers, - dropShadow: { numbers, colors, dropshadow }, - }, - functions: filterFunctions, - Util: { - parseDropShadow, parseFilterString, replaceDashNamespace, trueColor, - }, -}; - -export default filterEffects; diff --git a/src/components/filterEffectsBase.js b/src/components/filterEffectsBase.js deleted file mode 100644 index 884b1e1..0000000 --- a/src/components/filterEffectsBase.js +++ /dev/null @@ -1,74 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; - -// Component Interpolation -/** - * Sets the `drop-shadow` sub-property update function. - * * disimbiguation `dropshadow` interpolation function and `dropShadow` property - * @param {string} tweenProp the property name - */ -export function dropshadow(a, b, v) { - const params = []; - const unit = 'px'; - - for (let i = 0; i < 3; i += 1) { - // eslint-disable-next-line no-bitwise - params[i] = ((numbers(a[i], b[i], v) * 100 >> 0) / 100) + unit; - } - return `drop-shadow(${params.concat(colors(a[3], b[3], v)).join(' ')})`; -} -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartFilter(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable-next-line no-param-reassign -- impossible to satisfy */ - elem.style[tweenProp] = (b.url ? `url(${b.url})` : '') - /* eslint-disable no-bitwise -- impossible to satisfy */ - + (a.opacity || b.opacity ? `opacity(${((numbers(a.opacity, b.opacity, v) * 100) >> 0) / 100}%)` : '') - + (a.blur || b.blur ? `blur(${((numbers(a.blur, b.blur, v) * 100) >> 0) / 100}em)` : '') - + (a.saturate || b.saturate ? `saturate(${((numbers(a.saturate, b.saturate, v) * 100) >> 0) / 100}%)` : '') - + (a.invert || b.invert ? `invert(${((numbers(a.invert, b.invert, v) * 100) >> 0) / 100}%)` : '') - + (a.grayscale || b.grayscale ? `grayscale(${((numbers(a.grayscale, b.grayscale, v) * 100) >> 0) / 100}%)` : '') - + (a.hueRotate || b.hueRotate ? `hue-rotate(${((numbers(a.hueRotate, b.hueRotate, v) * 100) >> 0) / 100}deg)` : '') - + (a.sepia || b.sepia ? `sepia(${((numbers(a.sepia, b.sepia, v) * 100) >> 0) / 100}%)` : '') - + (a.brightness || b.brightness ? `brightness(${((numbers(a.brightness, b.brightness, v) * 100) >> 0) / 100}%)` : '') - + (a.contrast || b.contrast ? `contrast(${((numbers(a.contrast, b.contrast, v) * 100) >> 0) / 100}%)` : '') - + (a.dropShadow || b.dropShadow ? dropshadow(a.dropShadow, b.dropShadow, v) : ''); - /* eslint-enable no-bitwise -- impossible to satisfy */ - }; - } -} - -// Base Component -const baseFilter = { - component: 'baseFilter', - property: 'filter', - // opacity function interfere with opacityProperty - // subProperties: ['blur', 'brightness','contrast','dropShadow', - // 'hueRotate','grayscale','invert','opacity','saturate','sepia','url'], - // defaultValue: { - // opacity: 100, blur: 0, saturate: 100, grayscale: 0, - // brightness: 100, contrast: 100, sepia: 0, invert: 0, hueRotate:0, - // dropShadow: [0,0,0,{r:0,g:0,b:0}], url:'' - // }, - Interpolate: { - opacity: numbers, - blur: numbers, - saturate: numbers, - grayscale: numbers, - brightness: numbers, - contrast: numbers, - sepia: numbers, - invert: numbers, - hueRotate: numbers, - dropShadow: { numbers, colors, dropshadow }, - }, - functions: { onStart: onStartFilter }, -}; - -export default baseFilter; diff --git a/src/components/htmlAttributes.js b/src/components/htmlAttributes.js deleted file mode 100644 index d72f861..0000000 --- a/src/components/htmlAttributes.js +++ /dev/null @@ -1,131 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import onStart from '../objects/onStart'; -import trueColor from '../util/trueColor'; -import trueDimension from '../util/trueDimension'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; -import { attributes, onStartAttr } from './htmlAttributesBase'; - -// Component Name -const ComponentName = 'htmlAttributes'; - -// Component Properties -const svgColors = ['fill', 'stroke', 'stop-color']; - -// Component Util -/** - * Returns non-camelcase property name. - * @param {string} a the camelcase property name - * @returns {string} the non-camelcase property name - */ -function replaceUppercase(a) { return a.replace(/[A-Z]/g, '-$&').toLowerCase(); } - -// Component Functions -/** - * Returns the current attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {{[x:string]: string}} attribute value - */ -export function getAttr(/* tweenProp, */_, value) { - const attrStartValues = {}; - Object.keys(value).forEach((attr) => { - // get the value for 'fill-opacity' not fillOpacity - // also 'width' not the internal 'width_px' - const attribute = replaceUppercase(attr).replace(/_+[a-z]+/, ''); - const currentValue = this.element.getAttribute(attribute); - attrStartValues[attribute] = svgColors.includes(attribute) - ? (currentValue || 'rgba(0,0,0,0)') - : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); - }); - - return attrStartValues; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} attrObj the property value - * @returns {number} the property tween object - */ -export function prepareAttr(tweenProp, attrObj) { // attr (string),attrObj (object) - const attributesObject = {}; - - Object.keys(attrObj).forEach((p) => { - const prop = replaceUppercase(p); - const regex = /(%|[a-z]+)$/; - const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/, '')); - - if (!svgColors.includes(prop)) { - // attributes set with unit suffixes - if (currentValue !== null && regex.test(currentValue)) { - const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - const suffix = /%/.test(unit) ? '_percent' : `_${unit}`; - - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop + suffix] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - const _p = oneAttr.replace(suffix, ''); - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - elem.setAttribute(_p, ((numbers(a.v, b.v, v) * 1000 >> 0) / 1000) + b.u); - }; - } - }; - attributesObject[prop + suffix] = trueDimension(attrObj[p]); - } else if (!regex.test(attrObj[p]) || currentValue === null - || (currentValue !== null && !regex.test(currentValue))) { - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - elem.setAttribute(oneAttr, (numbers(a, b, v) * 1000 >> 0) / 1000); - }; - } - }; - attributesObject[prop] = parseFloat(attrObj[p]); - } - } else { // colors - // most "unknown" attributes cannot register into onStart, so we manually add them - onStart[ComponentName][prop] = (tp) => { - if (this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes)) { - attributes[tp] = (elem, oneAttr, a, b, v) => { - elem.setAttribute(oneAttr, colors(a, b, v)); - }; - } - }; - attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; - } - }); - - return attributesObject; -} - -// All Component Functions -const attrFunctions = { - prepareStart: getAttr, - prepareProperty: prepareAttr, - onStart: onStartAttr, -}; - -// Component Full -const htmlAttributes = { - component: ComponentName, - property: 'attr', - // the Animation class will need some values to validate this Object attribute - subProperties: ['fill', 'stroke', 'stop-color', 'fill-opacity', 'stroke-opacity'], - defaultValue: { - fill: 'rgb(0,0,0)', - stroke: 'rgb(0,0,0)', - 'stop-color': 'rgb(0,0,0)', - opacity: 1, - 'stroke-opacity': 1, - 'fill-opacity': 1, // same here - }, - Interpolate: { numbers, colors }, - functions: attrFunctions, - // export to global for faster execution - Util: { replaceUppercase, trueColor, trueDimension }, -}; - -export default htmlAttributes; diff --git a/src/components/htmlAttributesBase.js b/src/components/htmlAttributesBase.js deleted file mode 100644 index 187abf6..0000000 --- a/src/components/htmlAttributesBase.js +++ /dev/null @@ -1,59 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; - -// Component Name -const ComponentName = 'baseHTMLAttributes'; - -// Component Special -const attributes = {}; -export { attributes }; - -export const onStartAttr = { - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - attr(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, vS, vE, v) => { - Object.keys(vE).forEach((oneAttr) => { - KEC.attributes[oneAttr](elem, oneAttr, vS[oneAttr], vE[oneAttr], v); - }); - }; - } - }, - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - attributes(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd.attr) { - KEC[tweenProp] = attributes; - } - }, -}; - -// Component Base -const baseAttributes = { - component: ComponentName, - property: 'attr', - // the Animation class will need some values to validate this Object attribute - // subProperties: ['fill','stroke','stop-color','fill-opacity','stroke-opacity'], - // defaultValue: - // fill : 'rgb(0,0,0)', - // stroke: 'rgb(0,0,0)', - // 'stop-color': 'rgb(0,0,0)', - // opacity: 1, - // 'stroke-opacity': 1, - // 'fill-opacity': 1 // same here - // }, - Interpolate: { numbers, colors }, - functions: { onStart: onStartAttr }, -}; - -export default baseAttributes; diff --git a/src/components/opacityProperty.js b/src/components/opacityProperty.js deleted file mode 100644 index c54eae7..0000000 --- a/src/components/opacityProperty.js +++ /dev/null @@ -1,41 +0,0 @@ -import getStyleForProperty from '../process/getStyleForProperty'; -import numbers from '../interpolation/numbers'; -import { onStartOpacity } from './opacityPropertyBase'; - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -function getOpacity(tweenProp/* , value */) { - return getStyleForProperty(this.element, tweenProp); -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ -function prepareOpacity(/* tweenProp, */_, value) { - return parseFloat(value); // opacity always FLOAT -} - -// All Component Functions -const opacityFunctions = { - prepareStart: getOpacity, - prepareProperty: prepareOpacity, - onStart: onStartOpacity, -}; - -// Full Component -const OpacityProperty = { - component: 'opacityProperty', - property: 'opacity', - defaultValue: 1, - Interpolate: { numbers }, - functions: opacityFunctions, -}; - -export default OpacityProperty; diff --git a/src/components/opacityPropertyBase.js b/src/components/opacityPropertyBase.js deleted file mode 100644 index 6eaf1d2..0000000 --- a/src/components/opacityPropertyBase.js +++ /dev/null @@ -1,36 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -/* opacityProperty = { - property: 'opacity', - defaultValue: 1, - interpolators: {numbers}, - functions = { prepareStart, prepareProperty, onStart } -} */ - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartOpacity(tweenProp/* , value */) { - // opacity could be 0 sometimes, we need to check regardless - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable */ - elem.style[tweenProp] = ((numbers(a, b, v) * 1000) >> 0) / 1000; - /* eslint-enable */ - }; - } -} - -// Base Component -const OpacityPropertyBase = { - component: 'baseOpacity', - property: 'opacity', - // defaultValue: 1, - Interpolate: { numbers }, - functions: { onStart: onStartOpacity }, -}; - -export default OpacityPropertyBase; diff --git a/src/components/scrollProperty.js b/src/components/scrollProperty.js deleted file mode 100644 index de3e66b..0000000 --- a/src/components/scrollProperty.js +++ /dev/null @@ -1,59 +0,0 @@ -import numbers from '../interpolation/numbers'; - -import { - scrollContainer, - onStartScroll, - onCompleteScroll, - scrollIn, - scrollOut, - getScrollTargets, - preventScroll, - toggleScrollEvents, -} from './scrollPropertyBase'; - -// Component Functions -/** - * Returns the current property computed style. - * @returns {number} computed style for property - */ -function getScroll() { - this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) - ? scrollContainer : this.element; - - return this.element === scrollContainer - ? (window.pageYOffset || scrollContainer.scrollTop) - : this.element.scrollTop; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ -function prepareScroll(/* prop, */_, value) { - return parseInt(value, 10); -} - -// All Component Functions -const scrollFunctions = { - prepareStart: getScroll, - prepareProperty: prepareScroll, - onStart: onStartScroll, - onComplete: onCompleteScroll, -}; - -// Full Component -const ScrollProperty = { - component: 'scrollProperty', - property: 'scroll', - defaultValue: 0, - Interpolate: { numbers }, - functions: scrollFunctions, - // export stuff to global - Util: { - preventScroll, scrollIn, scrollOut, getScrollTargets, toggleScrollEvents, - }, -}; - -export default ScrollProperty; diff --git a/src/components/scrollPropertyBase.js b/src/components/scrollPropertyBase.js deleted file mode 100644 index d15b3a7..0000000 --- a/src/components/scrollPropertyBase.js +++ /dev/null @@ -1,113 +0,0 @@ -import passiveHandler from 'shorter-js/src/misc/passiveHandler'; -import mouseHoverEvents from 'shorter-js/src/strings/mouseHoverEvents'; -import supportTouch from 'shorter-js/src/boolean/supportTouch'; -import numbers from '../interpolation/numbers'; -import KEC from '../objects/kute'; - -// Component Util -// events preventing scroll -const touchOrWheel = supportTouch ? 'touchstart' : 'mousewheel'; - -// true scroll container -// very important and specific to the component -export const scrollContainer = navigator && /(EDGE|Mac)/i.test(navigator.userAgent) - ? document.body - : document.documentElement; - -/** - * Prevent further scroll events until scroll animation is over. - * @param {Event} e event object - */ -export function preventScroll(e) { - if (this.scrolling) e.preventDefault(); -} - -/** - * Returns the scroll element / target. - * @returns {{el: Element, st: Element}} - */ -export function getScrollTargets() { - const el = this.element; - return el === scrollContainer ? { el: document, st: document.body } : { el, st: el }; -} - -/** - * Toggles scroll prevention callback on scroll events. - * @param {string} action addEventListener / removeEventListener - * @param {Element} element target - */ -export function toggleScrollEvents(action, element) { - element[action](mouseHoverEvents[0], preventScroll, passiveHandler); - element[action](touchOrWheel, preventScroll, passiveHandler); -} - -/** - * Action performed before scroll animation start. - */ -export function scrollIn() { - const targets = getScrollTargets.call(this); - - if ('scroll' in this.valuesEnd && !targets.el.scrolling) { - targets.el.scrolling = 1; - toggleScrollEvents('addEventListener', targets.el); - targets.st.style.pointerEvents = 'none'; - } -} -/** - * Action performed when scroll animation ends. - */ -export function scrollOut() { // prevent scroll when tweening scroll - const targets = getScrollTargets.call(this); - - if ('scroll' in this.valuesEnd && targets.el.scrolling) { - targets.el.scrolling = 0; - toggleScrollEvents('removeEventListener', targets.el); - targets.st.style.pointerEvents = ''; - } -} - -// Component Functions -/** - * * Sets the scroll target. - * * Adds the scroll prevention event listener. - * * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartScroll(tweenProp) { - // checking 0 will NOT add the render function - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - this.element = ('scroll' in this.valuesEnd) && (!this.element || this.element === window) - ? scrollContainer : this.element; - scrollIn.call(this); - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable */ - elem.scrollTop = (numbers(a, b, v)) >> 0; - /* eslint-enable */ - }; - } -} - -/** - * Removes the scroll prevention event listener. - */ -export function onCompleteScroll(/* tweenProp */) { - scrollOut.call(this); -} - -// Base Component -const ScrollPropertyBase = { - component: 'baseScroll', - property: 'scroll', - // defaultValue: 0, - Interpolate: { numbers }, - functions: { - onStart: onStartScroll, - onComplete: onCompleteScroll, - }, - // unfortunatelly scroll needs all them no matter the packaging - Util: { - preventScroll, scrollIn, scrollOut, getScrollTargets, - }, -}; - -export default ScrollPropertyBase; diff --git a/src/components/shadowProperties.js b/src/components/shadowProperties.js deleted file mode 100644 index 952ec1c..0000000 --- a/src/components/shadowProperties.js +++ /dev/null @@ -1,127 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueColor from '../util/trueColor'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; -import { onStartShadow } from './shadowPropertiesBase'; - -// Component Properties -const shadowProps = ['boxShadow', 'textShadow']; - -// Component Util - -/** - * Return the box-shadow / text-shadow tween object. - * * box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit - * * text-shadow: none | offset-x offset-y blur-radius color |initial|inherit - * * numbers must be floats and color must be rgb object - * - * @param {(number | string)[]} shadow an `Array` with shadow parameters - * @param {string} tweenProp the property name - * @returns {KUTE.shadowObject} the property tween object - */ -function processShadowArray(shadow, tweenProp) { - let newShadow; - - // [h-shadow, v-shadow, color] - if (shadow.length === 3) { - newShadow = [shadow[0], shadow[1], 0, 0, shadow[2], 'none']; - // [h-shadow, v-shadow, color, inset] | [h-shadow, v-shadow, blur, color] - } else if (shadow.length === 4) { - newShadow = /inset|none/.test(shadow[3]) - ? [shadow[0], shadow[1], 0, 0, shadow[2], shadow[3]] - : [shadow[0], shadow[1], shadow[2], 0, shadow[3], 'none']; - // [h-shadow, v-shadow, blur, color, inset] | [h-shadow, v-shadow, blur, spread, color] - } else if (shadow.length === 5) { - newShadow = /inset|none/.test(shadow[4]) - ? [shadow[0], shadow[1], shadow[2], 0, shadow[3], shadow[4]] - : [shadow[0], shadow[1], shadow[2], shadow[3], shadow[4], 'none']; - // ideal [h-shadow, v-shadow, blur, spread, color, inset] - } else if (shadow.length === 6) { - newShadow = shadow; - } - - // make sure the values are ready to tween - for (let i = 0; i < 4; i += 1) { - newShadow[i] = parseFloat(newShadow[i]); - } - - // also the color must be a rgb object - newShadow[4] = trueColor(newShadow[4]); - - newShadow = tweenProp === 'boxShadow' - ? newShadow - : newShadow.filter((_, i) => [0, 1, 2, 4].includes(i)); - - return newShadow; -} - -// Component Functions -/** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ -export function getShadow(tweenProp/* , value */) { - const cssShadow = getStyleForProperty(this.element, tweenProp); - // '0px 0px 0px 0px rgb(0,0,0)' - return /^none$|^initial$|^inherit$|^inset$/.test(cssShadow) - ? defaultValues[tweenProp] - : cssShadow; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} propValue the property value - * @returns {KUTE.shadowObject} the property tween object - */ -export function prepareShadow(tweenProp, propValue) { - // [horizontal, vertical, blur, spread, color: {r:0,g:0,b:0}, inset] - // parseProperty for boxShadow, builds basic structure with ready to tween values - let value = propValue; - if (typeof value === 'string') { - let inset = 'none'; - // a full RegEx for color strings - const colRegEx = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi; - const currentColor = value.match(colRegEx); - - // make sure to always have the inset last if possible - inset = /inset/.test(value) ? 'inset' : inset; - value = /inset/.test(value) ? value.replace(/(\s+inset|inset+\s)/g, '') : value; - - // also getComputedStyle often returns color first "rgb(0, 0, 0) 15px 15px 6px 0px inset" - value = value.replace(currentColor[0], '').split(' ').concat([currentColor[0].replace(/\s/g, '')], [inset]); - - value = processShadowArray(value, tweenProp); - } else if (value instanceof Array) { - value = processShadowArray(value, tweenProp); - } - - return value; -} - -const shadowPropOnStart = {}; -shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; }); - -// All Component Functions -const shadowFunctions = { - prepareStart: getShadow, - prepareProperty: prepareShadow, - onStart: shadowPropOnStart, -}; - -// Component Full -const ShadowProperties = { - component: 'shadowProperties', - properties: shadowProps, - defaultValues: { - boxShadow: '0px 0px 0px 0px rgb(0,0,0)', - textShadow: '0px 0px 0px rgb(0,0,0)', - }, - Interpolate: { numbers, colors }, - functions: shadowFunctions, - Util: { processShadowArray, trueColor }, -}; - -export default ShadowProperties; diff --git a/src/components/shadowPropertiesBase.js b/src/components/shadowPropertiesBase.js deleted file mode 100644 index 40167c2..0000000 --- a/src/components/shadowPropertiesBase.js +++ /dev/null @@ -1,46 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import colors from '../interpolation/colors'; - -// Component Properties -const shadowProps = ['boxShadow', 'textShadow']; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartShadow(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // let's start with the numbers | set unit | also determine inset - const params = []; - const unit = 'px'; - const sl = tweenProp === 'textShadow' ? 3 : 4; - const colA = sl === 3 ? a[3] : a[4]; - const colB = sl === 3 ? b[3] : b[4]; - const inset = (a[5] && a[5] !== 'none') || (b[5] && b[5] !== 'none') ? ' inset' : false; - - for (let i = 0; i < sl; i += 1) { - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - params.push(((numbers(a[i], b[i], v) * 1000 >> 0) / 1000) + unit); - } - // the final piece of the puzzle, the DOM update - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = inset - ? colors(colA, colB, v) + params.join(' ') + inset - : colors(colA, colB, v) + params.join(' '); - }; - } -} -const shadowPropOnStart = {}; -shadowProps.forEach((x) => { shadowPropOnStart[x] = onStartShadow; }); - -// Component Base -const ShadowPropertiesBase = { - component: 'baseShadow', - Interpolate: { numbers, colors }, - functions: { onStart: shadowPropOnStart }, -}; - -export default ShadowPropertiesBase; diff --git a/src/components/svgCubicMorph.js b/src/components/svgCubicMorph.js deleted file mode 100644 index a553477..0000000 --- a/src/components/svgCubicMorph.js +++ /dev/null @@ -1,229 +0,0 @@ -import parsePathString from 'svg-path-commander/src/parser/parsePathString'; -import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute'; -import pathToCurve from 'svg-path-commander/src/convert/pathToCurve'; -import pathToString from 'svg-path-commander/src/convert/pathToString'; -import reverseCurve from 'svg-path-commander/src/process/reverseCurve'; -import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection'; -import clonePath from 'svg-path-commander/src/process/clonePath'; -import splitCubic from 'svg-path-commander/src/process/splitCubic'; -import splitPath from 'svg-path-commander/src/process/splitPath'; -import fixPath from 'svg-path-commander/src/process/fixPath'; -import segmentCubicFactory from 'svg-path-commander/src/util/segmentCubicFactory'; -import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot'; - -import { onStartCubicMorph } from './svgCubicMorphBase'; -import numbers from '../interpolation/numbers'; -import selector from '../util/selector'; - -// Component Util -/** - * Returns first `pathArray` from multi-paths path. - * @param {SVGPathCommander.pathArray | string} source the source `pathArray` or string - * @returns {KUTE.curveSpecs[]} an `Array` with a custom tuple for `equalizeSegments` - */ -function getCurveArray(source) { - return pathToCurve(splitPath(source)[0]) - .map((segment, i, pathArray) => { - const segmentData = i && [...pathArray[i - 1].slice(-2), ...segment.slice(1)]; - const curveLength = i ? segmentCubicFactory(...segmentData) : 0; - - let subsegs; - if (i) { - // must be [segment,segment] - subsegs = curveLength ? splitCubic(segmentData) : [segment, segment]; - } else { - subsegs = [segment]; - } - - return { - s: segment, - ss: subsegs, - l: curveLength, - }; - }); -} - -/** - * Returns two `curveArray` with same amount of segments. - * @param {SVGPathCommander.curveArray} path1 the first `curveArray` - * @param {SVGPathCommander.curveArray} path2 the second `curveArray` - * @param {number} TL the maximum `curveArray` length - * @returns {SVGPathCommander.curveArray[]} equalized segments - */ -function equalizeSegments(path1, path2, TL) { - const c1 = getCurveArray(path1); - const c2 = getCurveArray(path2); - const L1 = c1.length; - const L2 = c2.length; - const l1 = c1.filter((x) => x.l).length; - const l2 = c2.filter((x) => x.l).length; - const m1 = c1.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l1 || 0; - const m2 = c2.filter((x) => x.l).reduce((a, { l }) => a + l, 0) / l2 || 0; - const tl = TL || Math.max(L1, L2); - const mm = [m1, m2]; - const dif = [tl - L1, tl - L2]; - let canSplit = 0; - const result = [c1, c2] - .map((x, i) => (x.l === tl - ? x.map((y) => y.s) - : x.map((y, j) => { - canSplit = j && dif[i] && y.l >= mm[i]; - dif[i] -= canSplit ? 1 : 0; - return canSplit ? y.ss : [y.s]; - }).flat())); - - return result[0].length === result[1].length - ? result - : equalizeSegments(result[0], result[1], tl); -} - -/** - * Returns all possible path rotations for `curveArray`. - * @param {SVGPathCommander.curveArray} a the source `curveArray` - * @returns {SVGPathCommander.curveArray[]} all rotations for source - */ -function getRotations(a) { - const segCount = a.length; - const pointCount = segCount - 1; - - return a.map((_, idx) => a.map((__, i) => { - let oldSegIdx = idx + i; - let seg; - - if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) { - seg = a[oldSegIdx]; - return ['M', ...seg.slice(-2)]; - } - if (oldSegIdx >= segCount) oldSegIdx -= pointCount; - return a[oldSegIdx]; - })); -} - -/** - * Returns the `curveArray` rotation for the best morphing animation. - * @param {SVGPathCommander.curveArray} a the target `curveArray` - * @param {SVGPathCommander.curveArray} b the reference `curveArray` - * @returns {SVGPathCommander.curveArray} the best `a` rotation - */ -function getRotatedCurve(a, b) { - const segCount = a.length - 1; - const lineLengths = []; - let computedIndex = 0; - let sumLensSqrd = 0; - const rotations = getRotations(a); - - rotations.forEach((_, i) => { - a.slice(1).forEach((__, j) => { - sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2)); - }); - lineLengths[i] = sumLensSqrd; - sumLensSqrd = 0; - }); - - computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths)); - - return rotations[computedIndex]; -} - -// Component Functions -/** - * Returns the current `d` attribute value. - * @returns {string} - */ -function getCubicMorph(/* tweenProp, value */) { - return this.element.getAttribute('d'); -} - -/** - * Returns the property tween object. - * @see KUTE.curveObject - * - * @param {string} _ is the `path` property name, not needed - * @param {string | KUTE.curveObject} value the `path` property value - * @returns {KUTE.curveObject} - */ -function prepareCubicMorph(/* tweenProp, */_, value) { - // get path d attribute or create a path from string value - const pathObject = {}; - // remove newlines, they break some JSON strings - const pathReg = new RegExp('\\n', 'ig'); - - let el = null; - if (value instanceof SVGElement) { - el = value; - } else if (/^\.|^#/.test(value)) { - el = selector(value); - } - - // make sure to return pre-processed values - if (typeof (value) === 'object' && value.curve) { - return value; - } if (el && /path|glyph/.test(el.tagName)) { - pathObject.original = el.getAttribute('d').replace(pathReg, ''); - // maybe it's a string path already - } else if (!el && typeof (value) === 'string') { - pathObject.original = value.replace(pathReg, ''); - } - return pathObject; -} - -/** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} tweenProp is `path` tween property, but it's not needed - */ -function crossCheckCubicMorph(tweenProp/** , value */) { - if (this.valuesEnd[tweenProp]) { - const pathCurve1 = this.valuesStart[tweenProp].curve; - const pathCurve2 = this.valuesEnd[tweenProp].curve; - - if (!pathCurve1 || !pathCurve2 - || (pathCurve1 && pathCurve2 && pathCurve1[0][0] === 'M' && pathCurve1.length !== pathCurve2.length)) { - const path1 = this.valuesStart[tweenProp].original; - const path2 = this.valuesEnd[tweenProp].original; - const curves = equalizeSegments(path1, path2); - const curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) - ? reverseCurve(curves[0]) - : clonePath(curves[0]); - - this.valuesStart[tweenProp].curve = curve0; - this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1], curve0); - } - } -} - -// All Component Functions -const svgCubicMorphFunctions = { - prepareStart: getCubicMorph, - prepareProperty: prepareCubicMorph, - onStart: onStartCubicMorph, - crossCheck: crossCheckCubicMorph, -}; - -// Component Full -const svgCubicMorph = { - component: 'svgCubicMorph', - property: 'path', - defaultValue: [], - Interpolate: { numbers, pathToString }, - functions: svgCubicMorphFunctions, - // export utils to global for faster execution - Util: { - pathToCurve, - pathToAbsolute, - pathToString, - parsePathString, - getRotatedCurve, - getRotations, - equalizeSegments, - reverseCurve, - clonePath, - getDrawDirection, - segmentCubicFactory, - splitCubic, - splitPath, - fixPath, - getCurveArray, - }, -}; - -export default svgCubicMorph; diff --git a/src/components/svgCubicMorphBase.js b/src/components/svgCubicMorphBase.js deleted file mode 100644 index eca424f..0000000 --- a/src/components/svgCubicMorphBase.js +++ /dev/null @@ -1,38 +0,0 @@ -import pathToString from 'svg-path-commander/src/convert/pathToString'; -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions - -/** - * Sets the property update function. - * @param {string} tweenProp the `path` property - */ -export function onStartCubicMorph(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = function updateMorph(elem, a, b, v) { - const curve = []; - const path1 = a.curve; - const path2 = b.curve; - for (let i = 0, l = path2.length; i < l; i += 1) { // each path command - curve.push([path1[i][0]]); - for (let j = 1, l2 = path1[i].length; j < l2; j += 1) { // each command coordinate - /* eslint-disable-next-line no-bitwise -- impossible to satisfy */ - curve[i].push((numbers(path1[i][j], path2[i][j], v) * 1000 >> 0) / 1000); - } - } - elem.setAttribute('d', v === 1 ? b.original : pathToString(curve)); - }; - } -} - -// Component Base -const baseSvgCubicMorph = { - component: 'baseSVGCubicMorph', - property: 'path', - // defaultValue: [], - Interpolate: { numbers, pathToString }, - functions: { onStart: onStartCubicMorph }, -}; - -export default baseSvgCubicMorph; diff --git a/src/components/svgDraw.js b/src/components/svgDraw.js deleted file mode 100644 index 346e09d..0000000 --- a/src/components/svgDraw.js +++ /dev/null @@ -1,210 +0,0 @@ -import getStyleForProperty from '../process/getStyleForProperty'; -import numbers from '../interpolation/numbers'; -import { onStartDraw } from './svgDrawBase'; - -// Component Util -/** - * Convert a `` length percent value to absolute. - * @param {string} v raw value - * @param {number} l length value - * @returns {number} the absolute value - */ -function percent(v, l) { - return (parseFloat(v) / 100) * l; -} - -/** - * Returns the `` length. - * It doesn't compute `rx` and / or `ry` of the element. - * @see http://stackoverflow.com/a/30376660 - * @param {SVGRectElement} el target element - * @returns {number} the `` length - */ -function getRectLength(el) { - const w = el.getAttribute('width'); - const h = el.getAttribute('height'); - return (w * 2) + (h * 2); -} - -/** - * Returns the `` / `` length. - * @param {SVGPolylineElement | SVGPolygonElement} el target element - * @returns {number} the element length - */ -function getPolyLength(el) { - const points = el.getAttribute('points').split(' '); - - let len = 0; - if (points.length > 1) { - const coord = (p) => { - const c = p.split(','); - if (c.length !== 2) { return 0; } // return undefined - if (Number.isNaN(c[0] * 1) || Number.isNaN(c[1] * 1)) { return 0; } - return [parseFloat(c[0]), parseFloat(c[1])]; - }; - - const dist = (c1, c2) => { - if (c1 !== undefined && c2 !== undefined) { - return Math.sqrt((c2[0] - c1[0]) ** 2 + (c2[1] - c1[1]) ** 2); - } - return 0; - }; - - if (points.length > 2) { - for (let i = 0; i < points.length - 1; i += 1) { - len += dist(coord(points[i]), coord(points[i + 1])); - } - } - len += el.tagName === 'polygon' - ? dist(coord(points[0]), coord(points[points.length - 1])) : 0; - } - return len; -} - -/** - * Returns the `` length. - * @param {SVGLineElement} el target element - * @returns {number} the element length - */ -function getLineLength(el) { - const x1 = el.getAttribute('x1'); - const x2 = el.getAttribute('x2'); - const y1 = el.getAttribute('y1'); - const y2 = el.getAttribute('y2'); - return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); -} - -/** - * Returns the `` length. - * @param {SVGCircleElement} el target element - * @returns {number} the element length - */ -function getCircleLength(el) { - const r = el.getAttribute('r'); - return 2 * Math.PI * r; -} - -// returns the length of an ellipse -/** - * Returns the `` length. - * @param {SVGEllipseElement} el target element - * @returns {number} the element length - */ -function getEllipseLength(el) { - const rx = el.getAttribute('rx'); - const ry = el.getAttribute('ry'); - const len = 2 * rx; - const wid = 2 * ry; - return ((Math.sqrt(0.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; -} - -/** - * Returns the shape length. - * @param {SVGPathCommander.shapeTypes} el target element - * @returns {number} the element length - */ -function getTotalLength(el) { - if (el.tagName === 'rect') { - return getRectLength(el); - } if (el.tagName === 'circle') { - return getCircleLength(el); - } if (el.tagName === 'ellipse') { - return getEllipseLength(el); - } if (['polygon', 'polyline'].includes(el.tagName)) { - return getPolyLength(el); - } if (el.tagName === 'line') { - return getLineLength(el); - } - // ESLint - return 0; -} - -/** - * Returns the property tween object. - * @param {SVGPathCommander.shapeTypes} element the target element - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ -function getDraw(element, value) { - const length = /path|glyph/.test(element.tagName) - ? element.getTotalLength() - : getTotalLength(element); - let start; - let end; - let dasharray; - let offset; - - if (value instanceof Object && Object.keys(value).every((v) => ['s', 'e', 'l'].includes(v))) { - return value; - } if (typeof value === 'string') { - const v = value.split(/,|\s/); - start = /%/.test(v[0]) ? percent(v[0].trim(), length) : parseFloat(v[0]); - end = /%/.test(v[1]) ? percent(v[1].trim(), length) : parseFloat(v[1]); - } else if (typeof value === 'undefined') { - offset = parseFloat(getStyleForProperty(element, 'stroke-dashoffset')); - dasharray = getStyleForProperty(element, 'stroke-dasharray').split(','); - - start = 0 - offset; - end = parseFloat(dasharray[0]) + start || length; - } - return { s: start, e: end, l: length }; -} - -/** - * Reset CSS properties associated with the `draw` property. - * @param {SVGPathCommander.shapeTypes} element target - */ -function resetDraw(elem) { - /* eslint-disable no-param-reassign -- impossible to satisfy */ - elem.style.strokeDashoffset = ''; - elem.style.strokeDasharray = ''; - /* eslint-disable no-param-reassign -- impossible to satisfy */ -} - -// Component Functions -/** - * Returns the property tween object. - * @returns {KUTE.drawObject} the property tween object - */ -function getDrawValue(/* prop, value */) { - return getDraw(this.element); -} -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ -function prepareDraw(_, value) { - return getDraw(this.element, value); -} - -// All Component Functions -const svgDrawFunctions = { - prepareStart: getDrawValue, - prepareProperty: prepareDraw, - onStart: onStartDraw, -}; - -// Component Full -const SvgDrawProperty = { - component: 'svgDraw', - property: 'draw', - defaultValue: '0% 0%', - Interpolate: { numbers }, - functions: svgDrawFunctions, - // Export to global for faster execution - Util: { - getRectLength, - getPolyLength, - getLineLength, - getCircleLength, - getEllipseLength, - getTotalLength, - resetDraw, - getDraw, - percent, - }, -}; - -export default SvgDrawProperty; diff --git a/src/components/svgDrawBase.js b/src/components/svgDrawBase.js deleted file mode 100644 index 5ad6680..0000000 --- a/src/components/svgDrawBase.js +++ /dev/null @@ -1,35 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartDraw(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable no-bitwise -- impossible to satisfy */ - const pathLength = (a.l * 100 >> 0) / 100; - const start = (numbers(a.s, b.s, v) * 100 >> 0) / 100; - const end = (numbers(a.e, b.e, v) * 100 >> 0) / 100; - const offset = 0 - start; - const dashOne = end + offset; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDashoffset = `${offset}px`; - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style.strokeDasharray = `${((dashOne < 1 ? 0 : dashOne) * 100 >> 0) / 100}px, ${pathLength}px`; - /* eslint-disable no-bitwise -- impossible to satisfy */ - }; - } -} - -// Component Base -const SvgDrawBase = { - component: 'baseSVGDraw', - property: 'draw', - Interpolate: { numbers }, - functions: { onStart: onStartDraw }, -}; - -export default SvgDrawBase; diff --git a/src/components/svgMorph.js b/src/components/svgMorph.js deleted file mode 100644 index f945d89..0000000 --- a/src/components/svgMorph.js +++ /dev/null @@ -1,367 +0,0 @@ -import pathToCurve from 'svg-path-commander/src/convert/pathToCurve'; -import pathToString from 'svg-path-commander/src/convert/pathToString'; -import normalizePath from 'svg-path-commander/src/process/normalizePath'; -import splitPath from 'svg-path-commander/src/process/splitPath'; -import roundPath from 'svg-path-commander/src/process/roundPath'; -import getTotalLength from 'svg-path-commander/src/util/getTotalLength'; -import invalidPathValue from 'svg-path-commander/src/parser/invalidPathValue'; -import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength'; -import polygonArea from 'svg-path-commander/src/math/polygonArea'; -import polygonLength from 'svg-path-commander/src/math/polygonLength'; -import epsilon from 'svg-path-commander/src/math/epsilon'; -import midPoint from 'svg-path-commander/src/math/midPoint'; -import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot'; -import { onStartSVGMorph } from './svgMorphBase'; -import coords from '../interpolation/coords'; -import defaultOptions from '../objects/defaultOptions'; -import selector from '../util/selector'; - -// Component Util -// original script flubber -// https://github.com/veltman/flubber - -/** - * Returns an existing polygon or false if it's not a polygon. - * @param {SVGPathCommander.pathArray} pathArray target `pathArray` - * @returns {KUTE.exactPolygon | false} the resulted polygon - */ -function exactPolygon(pathArray) { - const polygon = []; - const pathlen = pathArray.length; - let segment = []; - let pathCommand = ''; - - if (!pathArray.length || pathArray[0][0] !== 'M') { - return false; - } - - for (let i = 0; i < pathlen; i += 1) { - segment = pathArray[i]; - [pathCommand] = segment; - - if ((pathCommand === 'M' && i) || pathCommand === 'Z') { - break; // !! - } else if ('ML'.includes(pathCommand)) { - polygon.push([segment[1], segment[2]]); - } else { - return false; - } - } - - return pathlen ? { polygon } : false; -} - -/** - * Returns a new polygon polygon. - * @param {SVGPathCommander.pathArray} parsed target `pathArray` - * @param {number} maxLength the maximum segment length - * @returns {KUTE.exactPolygon} the resulted polygon - */ -function approximatePolygon(parsed, maxLength) { - const ringPath = splitPath(pathToString(parsed))[0]; - const normalPath = normalizePath(ringPath); - const pathLength = getTotalLength(normalPath); - const polygon = []; - let numPoints = 3; - let point; - - if (maxLength && !Number.isNaN(maxLength) && +maxLength > 0) { - numPoints = Math.max(numPoints, Math.ceil(pathLength / maxLength)); - } - - for (let i = 0; i < numPoints; i += 1) { - point = getPointAtLength(normalPath, (pathLength * i) / numPoints); - polygon.push([point.x, point.y]); - } - - // Make all rings clockwise - if (polygonArea(polygon) > 0) { - polygon.reverse(); - } - - return { - polygon, - skipBisect: true, - }; -} - -/** - * Parses a path string and returns a polygon array. - * @param {string} str path string - * @param {number} maxLength maximum amount of points - * @returns {KUTE.exactPolygon} the polygon array we need - */ -function pathStringToPolygon(str, maxLength) { - const parsed = normalizePath(str); - return exactPolygon(parsed) || approximatePolygon(parsed, maxLength); -} - -/** - * Rotates a polygon to better match its pair. - * @param {KUTE.polygonMorph} polygon the target polygon - * @param {KUTE.polygonMorph} vs the reference polygon - */ -function rotatePolygon(polygon, vs) { - const len = polygon.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; - - for (let i = 0; i < vs.length; i += 1) { - p = vs[i]; - d = distanceSquareRoot(polygon[(offset + i) % len], p); - sumOfSquares += d * d; - } - - if (sumOfSquares < min) { - min = sumOfSquares; - bestOffset = offset; - } - } - - if (bestOffset) { - spliced = polygon.splice(0, bestOffset); - polygon.splice(polygon.length, 0, ...spliced); - } -} - -/** - * Sample additional points for a polygon to better match its pair. - * @param {KUTE.polygonObject} polygon the target polygon - * @param {number} numPoints the amount of points needed - */ -function addPoints(polygon, numPoints) { - const desiredLength = polygon.length + numPoints; - const step = polygonLength(polygon) / numPoints; - - let i = 0; - let cursor = 0; - let insertAt = step / 2; - let a; - let b; - let segment; - - while (polygon.length < desiredLength) { - a = polygon[i]; - b = polygon[(i + 1) % polygon.length]; - - segment = distanceSquareRoot(a, b); - - if (insertAt <= cursor + segment) { - polygon.splice(i + 1, 0, segment - ? midPoint(a, b, (insertAt - cursor) / segment) - : a.slice(0)); - insertAt += step; - } else { - cursor += segment; - i += 1; - } - } -} - -/** - * Split segments of a polygon until it reaches a certain - * amount of points. - * @param {number[][]} polygon the target polygon - * @param {number} maxSegmentLength the maximum amount of points - */ -function bisect(polygon, maxSegmentLength = Infinity) { - let a = []; - let b = []; - - for (let i = 0; i < polygon.length; i += 1) { - a = polygon[i]; - b = i === polygon.length - 1 ? polygon[0] : polygon[i + 1]; - - // Could splice the whole set for a segment instead, but a bit messy - while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = midPoint(a, b, 0.5); - polygon.splice(i + 1, 0, b); - } - } -} - -/** - * Checks the validity of a polygon. - * @param {KUTE.polygonMorph} polygon the target polygon - * @returns {boolean} the result of the check - */ -function validPolygon(polygon) { - return Array.isArray(polygon) - && polygon.every((point) => Array.isArray(point) - && point.length === 2 - && !Number.isNaN(point[0]) - && !Number.isNaN(point[1])); -} - -/** - * Returns a new polygon and its length from string or another `Array`. - * @param {KUTE.polygonMorph | string} input the target polygon - * @param {number} maxSegmentLength the maximum amount of points - * @returns {KUTE.polygonMorph} normalized polygon - */ -function getPolygon(input, maxSegmentLength) { - let skipBisect; - let polygon; - - if (typeof (input) === 'string') { - const converted = pathStringToPolygon(input, maxSegmentLength); - ({ polygon, skipBisect } = converted); - } else if (!Array.isArray(input)) { - throw Error(`${invalidPathValue}: ${input}`); - } - - /** @type {KUTE.polygonMorph} */ - const points = [...polygon]; - - if (!validPolygon(points)) { - throw Error(`${invalidPathValue}: ${points}`); - } - - // TODO skip this test to avoid scale issues? - // Chosen epsilon (1e-6) is problematic for small coordinate range, we now use 1e-9 - if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { - points.pop(); - } - - if (!skipBisect && maxSegmentLength - && !Number.isNaN(maxSegmentLength) && (+maxSegmentLength) > 0) { - bisect(points, maxSegmentLength); - } - - return points; -} - -/** - * Returns two new polygons ready to tween. - * @param {string} path1 the first path string - * @param {string} path2 the second path string - * @param {number} precision the morphPrecision option value - * @returns {KUTE.polygonMorph[]} the two polygons - */ -function getInterpolationPoints(path1, path2, precision) { - const morphPrecision = precision || defaultOptions.morphPrecision; - const fromRing = getPolygon(path1, morphPrecision); - const toRing = getPolygon(path2, morphPrecision); - const diff = fromRing.length - toRing.length; - - addPoints(fromRing, diff < 0 ? diff * -1 : 0); - addPoints(toRing, diff > 0 ? diff : 0); - - rotatePolygon(fromRing, toRing); - - return [roundPath(fromRing), roundPath(toRing)]; -} - -// Component functions -/** - * Returns the current `d` attribute value. - * @returns {string} the `d` attribute value - */ -function getSVGMorph(/* tweenProp */) { - return this.element.getAttribute('d'); -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.polygonObject} value the property value - * @returns {KUTE.polygonObject} the property tween object - */ -function prepareSVGMorph(/* tweenProp */_, value) { - const pathObject = {}; - // remove newlines, they brake JSON strings sometimes - const pathReg = new RegExp('\\n', 'ig'); - let elem = null; - - if (value instanceof SVGPathElement) { - elem = value; - } else if (/^\.|^#/.test(value)) { - elem = selector(value); - } - - // first make sure we return pre-processed values - if (typeof (value) === 'object' && value.polygon) { - return value; - } if (elem && ['path', 'glyph'].includes(elem.tagName)) { - pathObject.original = elem.getAttribute('d').replace(pathReg, ''); - // maybe it's a string path already - } else if (!elem && typeof (value) === 'string') { - pathObject.original = value.replace(pathReg, ''); - } - - return pathObject; -} - -/** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} prop the `path` property name - */ -function crossCheckSVGMorph(prop) { - if (this.valuesEnd[prop]) { - const pathArray1 = this.valuesStart[prop].polygon; - const pathArray2 = this.valuesEnd[prop].polygon; - // skip already processed paths - // allow the component to work with pre-processed values - if (!pathArray1 || !pathArray2 - || (pathArray1 && pathArray2 && pathArray1.length !== pathArray2.length)) { - const p1 = this.valuesStart[prop].original; - const p2 = this.valuesEnd[prop].original; - // process morphPrecision - const morphPrecision = this._morphPrecision - ? parseInt(this._morphPrecision, 10) - : defaultOptions.morphPrecision; - - const [path1, path2] = getInterpolationPoints(p1, p2, morphPrecision); - this.valuesStart[prop].polygon = path1; - this.valuesEnd[prop].polygon = path2; - } - } -} - -// All Component Functions -const svgMorphFunctions = { - prepareStart: getSVGMorph, - prepareProperty: prepareSVGMorph, - onStart: onStartSVGMorph, - crossCheck: crossCheckSVGMorph, -}; - -// Component Full -const SVGMorph = { - component: 'svgMorph', - property: 'path', - defaultValue: [], - Interpolate: coords, - defaultOptions: { morphPrecision: 10 }, - functions: svgMorphFunctions, - // Export utils to global for faster execution - Util: { - // component - addPoints, - bisect, - getPolygon, - validPolygon, - getInterpolationPoints, - pathStringToPolygon, - distanceSquareRoot, - midPoint, - approximatePolygon, - rotatePolygon, - // svg-path-commander - pathToString, - pathToCurve, - getTotalLength, - getPointAtLength, - polygonArea, - roundPath, - }, -}; - -export default SVGMorph; diff --git a/src/components/svgMorphBase.js b/src/components/svgMorphBase.js deleted file mode 100644 index 6c63d81..0000000 --- a/src/components/svgMorphBase.js +++ /dev/null @@ -1,34 +0,0 @@ -import KEC from '../objects/kute'; -import coords from '../interpolation/coords'; - -/* SVGMorph = { - property: 'path', - defaultValue: [], - interpolators: {numbers,coords} }, - functions = { prepareStart, prepareProperty, onStart, crossCheck } -} */ - -// Component functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartSVGMorph(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - const path1 = a.polygon; const path2 = b.polygon; - const len = path2.length; - elem.setAttribute('d', (v === 1 ? b.original : `M${coords(path1, path2, len, v).join('L')}Z`)); - }; - } -} - -// Component Base -const SVGMorphBase = { - component: 'baseSVGMorph', - property: 'path', - Interpolate: coords, - functions: { onStart: onStartSVGMorph }, -}; - -export default SVGMorphBase; diff --git a/src/components/svgTransform.js b/src/components/svgTransform.js deleted file mode 100644 index 82c2599..0000000 --- a/src/components/svgTransform.js +++ /dev/null @@ -1,196 +0,0 @@ -import numbers from '../interpolation/numbers'; -import { svgTransformOnStart } from './svgTransformBase'; - -// Component Util -/** - * Returns a correct transform origin consistent with the shape bounding box. - * @param {string} origin transform origin string - * @param {SVGPathCommander.pathBBox} bbox path bounding box - * @returns {number} - */ -function parseStringOrigin(origin, bbox) { - let result; - const { x, width } = bbox; - if (/[a-z]/i.test(origin) && !/px/.test(origin)) { - result = origin.replace(/top|left/, 0) - .replace(/right|bottom/, 100) - .replace(/center|middle/, 50); - } else { - result = /%/.test(origin) ? (x + (parseFloat(origin) * width) / 100) : parseFloat(origin); - } - return result; -} - -/** - * Parse SVG transform string and return an object. - * @param {string} a transform string - * @returns {Object} - */ -function parseTransformString(a) { - const c = {}; - const d = a && /\)/.test(a) - ? a.substring(0, a.length - 1).split(/\)\s|\)/) - : 'none'; - - if (d instanceof Array) { - for (let j = 0, jl = d.length; j < jl; j += 1) { - const [prop, val] = d[j].trim().split('('); - c[prop] = val; - } - } - return c; -} - -/** - * Returns the SVG transform tween object. - * @param {string} _ property name - * @param {Object} v property value object - * @returns {KUTE.transformSVGObject} the SVG transform tween object - */ -function parseTransformSVG(/* prop */_, v) { - /** @type {KUTE.transformSVGObject} */ - const svgTransformObject = {}; - - // by default the transformOrigin is "50% 50%" of the shape box - const bb = this.element.getBBox(); - const cx = bb.x + bb.width / 2; - const cy = bb.y + bb.height / 2; - - let origin = this._transformOrigin; - let translation; - - if (typeof (origin) !== 'undefined') { - origin = origin instanceof Array ? origin : origin.split(/\s/); - } else { - origin = [cx, cy]; - } - - origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0], bb); - origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1], bb); - - svgTransformObject.origin = origin; - - // populate the valuesStart and / or valuesEnd - Object.keys(v).forEach((i) => { - if (i === 'rotate') { - if (typeof v[i] === 'number') { - svgTransformObject[i] = v[i]; - } else if (v[i] instanceof Array) { - [svgTransformObject[i]] = v[i]; - } else { - svgTransformObject[i] = v[i].split(/\s/)[0] * 1; - } - } else if (i === 'translate') { - if (v[i] instanceof Array) { - translation = v[i]; - } else if (/,|\s/.test(v[i])) { - translation = v[i].split(','); - } else { - translation = [v[i], 0]; - } - svgTransformObject[i] = [translation[0] * 1 || 0, translation[1] * 1 || 0]; - } else if (/skew/.test(i)) { - svgTransformObject[i] = v[i] * 1 || 0; - } else if (i === 'scale') { - svgTransformObject[i] = parseFloat(v[i]) || 1; - } - }); - - return svgTransformObject; -} - -// Component Functions -/** - * Returns the property tween object. - * @param {string} prop the property name - * @param {string} value the property value - * @returns {KUTE.transformSVGObject} the property tween object - */ -function prepareSvgTransform(prop, value) { - return parseTransformSVG.call(this, prop, value); -} - -/** - * Returns an object with the current transform attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {string} current transform object - */ -function getStartSvgTransform(/* tweenProp */_, value) { - const transformObject = {}; - const currentTransform = parseTransformString(this.element.getAttribute('transform')); - - // find a value in current attribute value or add a default value - Object.keys(value).forEach((j) => { - const scaleValue = j === 'scale' ? 1 : 0; - transformObject[j] = j in currentTransform ? currentTransform[j] : scaleValue; - }); - - return transformObject; -} - -function svgTransformCrossCheck(prop) { - if (!this._resetStart) return; // fix since 1.6.1 for fromTo() method - - if (this.valuesEnd[prop]) { - const valuesStart = this.valuesStart[prop]; - const valuesEnd = this.valuesEnd[prop]; - const currentTransform = parseTransformSVG.call(this, prop, - parseTransformString(this.element.getAttribute('transform'))); - - // populate the valuesStart first - Object.keys(currentTransform).forEach((tp) => { - valuesStart[tp] = currentTransform[tp]; - }); - - // now try to determine the REAL translation - const parentSVG = this.element.ownerSVGElement; - const startMatrix = parentSVG.createSVGTransformFromMatrix( - parentSVG.createSVGMatrix() - .translate(-valuesStart.origin[0], -valuesStart.origin[1]) // - origin - .translate('translate' in valuesStart // the current translate - ? valuesStart.translate[0] : 0, 'translate' in valuesStart ? valuesStart.translate[1] - : 0) - .rotate(valuesStart.rotate || 0) - .skewX(valuesStart.skewX || 0) - .skewY(valuesStart.skewY || 0) - .scale(valuesStart.scale || 1)// the other functions - .translate(+valuesStart.origin[0], +valuesStart.origin[1]), // + origin - ); - // finally the translate we're looking for - valuesStart.translate = [startMatrix.matrix.e, startMatrix.matrix.f]; - - // copy existing and unused properties to the valuesEnd - Object.keys(valuesStart).forEach((s) => { - if (!(s in valuesEnd) || s === 'origin') { - valuesEnd[s] = valuesStart[s]; - } - }); - } -} - -// All Component Functions -export const svgTransformFunctions = { - prepareStart: getStartSvgTransform, - prepareProperty: prepareSvgTransform, - onStart: svgTransformOnStart, - crossCheck: svgTransformCrossCheck, -}; - -// Component Full -export const svgTransform = { - component: 'svgTransformProperty', - property: 'svgTransform', - // subProperties: ['translate','rotate','skewX','skewY','scale'], - defaultOptions: { transformOrigin: '50% 50%' }, - defaultValue: { - translate: 0, rotate: 0, skewX: 0, skewY: 0, scale: 1, - }, - Interpolate: { numbers }, - functions: svgTransformFunctions, - - // export utils to globals for faster execution - Util: { parseStringOrigin, parseTransformString, parseTransformSVG }, -}; - -export default svgTransform; diff --git a/src/components/svgTransformBase.js b/src/components/svgTransformBase.js deleted file mode 100644 index 290ddd5..0000000 --- a/src/components/svgTransformBase.js +++ /dev/null @@ -1,63 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function svgTransformOnStart(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (l, a, b, v) => { - let x = 0; - let y = 0; - const deg = Math.PI / 180; - const scale = 'scale' in b ? numbers(a.scale, b.scale, v) : 1; - const rotate = 'rotate' in b ? numbers(a.rotate, b.rotate, v) : 0; - const sin = Math.sin(rotate * deg); - const cos = Math.cos(rotate * deg); - const skewX = 'skewX' in b ? numbers(a.skewX, b.skewX, v) : 0; - const skewY = 'skewY' in b ? numbers(a.skewY, b.skewY, v) : 0; - const complex = rotate || skewX || skewY || scale !== 1 || 0; - - // start normalizing the translation, we start from last to first - // (from last chained translation) - // the normalized translation will handle the transformOrigin tween option - // and makes sure to have a consistent transformation - - // we start with removing transformOrigin from translation - x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0; - x *= scale; y *= scale; // we now apply the scale - // now we apply skews - y += skewY ? x * Math.tan(skewY * deg) : 0; x += skewX ? y * Math.tan(skewX * deg) : 0; - const cxsy = cos * x - sin * y; // apply rotation as well - y = rotate ? sin * x + cos * y : y; x = rotate ? cxsy : x; - // now we apply the actual translation - x += 'translate' in b ? numbers(a.translate[0], b.translate[0], v) : 0; - y += 'translate' in b ? numbers(a.translate[1], b.translate[1], v) : 0; - // normalizing ends with the addition of the transformOrigin to the translation - x += complex ? b.origin[0] : 0; y += complex ? b.origin[1] : 0; - - // finally we apply the transform attribute value - /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ - l.setAttribute('transform', (x || y ? (`translate(${(x * 1000 >> 0) / 1000}${y ? (`,${(y * 1000 >> 0) / 1000}`) : ''})`) : '') - + (rotate ? `rotate(${(rotate * 1000 >> 0) / 1000})` : '') - + (skewX ? `skewX(${(skewX * 1000 >> 0) / 1000})` : '') - + (skewY ? `skewY(${(skewY * 1000 >> 0) / 1000})` : '') - + (scale !== 1 ? `scale(${(scale * 1000 >> 0) / 1000})` : '')); - }; - } -} - -// Component Base -const baseSVGTransform = { - component: 'baseSVGTransform', - property: 'svgTransform', - // subProperties: ['translate','rotate','skewX','skewY','scale'], - // defaultValue: {translate:0, rotate:0, skewX:0, skewY:0, scale:1}, - defaultOptions: { transformOrigin: '50% 50%' }, - Interpolate: { numbers }, - functions: { onStart: svgTransformOnStart }, -}; - -export default baseSVGTransform; diff --git a/src/components/textProperties.js b/src/components/textProperties.js deleted file mode 100644 index 4f831ab..0000000 --- a/src/components/textProperties.js +++ /dev/null @@ -1,55 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getStyleForProperty from '../process/getStyleForProperty'; -import trueDimension from '../util/trueDimension'; -import units from '../interpolation/units'; -import { textPropOnStart } from './textPropertiesBase'; - -// Component Properties -const textProps = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing']; -const textOnStart = {}; - -// Component Functions -textProps.forEach((tweenProp) => { - textOnStart[tweenProp] = textPropOnStart; -}); - -/** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} computed style for property - */ -export function getTextProp(prop/* , value */) { - return getStyleForProperty(this.element, prop) || defaultValues[prop]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ -export function prepareTextProp(/* prop */_, value) { - return trueDimension(value); -} - -// All Component Functions -const textPropFunctions = { - prepareStart: getTextProp, - prepareProperty: prepareTextProp, - onStart: textOnStart, -}; - -// Component Full -const TextProperties = { - component: 'textProperties', - category: 'textProperties', - properties: textProps, - defaultValues: { - fontSize: 0, lineHeight: 0, letterSpacing: 0, wordSpacing: 0, - }, - Interpolate: { units }, - functions: textPropFunctions, - Util: { trueDimension }, -}; - -export default TextProperties; diff --git a/src/components/textPropertiesBase.js b/src/components/textPropertiesBase.js deleted file mode 100644 index 58dfa14..0000000 --- a/src/components/textPropertiesBase.js +++ /dev/null @@ -1,35 +0,0 @@ -import KEC from '../objects/kute'; -import units from '../interpolation/units'; - -// Component Properties -const textProperties = ['fontSize', 'lineHeight', 'letterSpacing', 'wordSpacing']; -const textOnStart = {}; - -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function textPropOnStart(tweenProp) { - if (this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign -- impossible to satisfy - elem.style[tweenProp] = units(a.v, b.v, b.u, v); - }; - } -} - -textProperties.forEach((tweenProp) => { - textOnStart[tweenProp] = textPropOnStart; -}); - -// Component Base -const TextPropertiesBase = { - component: 'baseTextProperties', - category: 'textProps', - // properties: textProperties, - // defaultValues: {fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0}, - Interpolate: { units }, - functions: { onStart: textOnStart }, -}; - -export default TextPropertiesBase; diff --git a/src/components/textWrite.js b/src/components/textWrite.js deleted file mode 100644 index e3d9363..0000000 --- a/src/components/textWrite.js +++ /dev/null @@ -1,188 +0,0 @@ -import connect from '../objects/connect'; -import numbers from '../interpolation/numbers'; - -import { onStartWrite, charSet } from './textWriteBase'; - -// Component Util -// utility for multi-child targets -// wrapContentsSpan returns an [Element] with the SPAN.tagName and a desired class -function wrapContentsSpan(el, classNAME) { - let textWriteWrapper; - let newElem; - if (typeof (el) === 'string') { - newElem = document.createElement('SPAN'); - newElem.innerHTML = el; - newElem.className = classNAME; - return newElem; - } - if (!el.children.length || (el.children.length && el.children[0].className !== classNAME)) { - const elementInnerHTML = el.innerHTML; - textWriteWrapper = document.createElement('SPAN'); - textWriteWrapper.className = classNAME; - textWriteWrapper.innerHTML = elementInnerHTML; - /* eslint-disable no-param-reassign -- impossible to satisfy */ - el.appendChild(textWriteWrapper); - el.innerHTML = textWriteWrapper.outerHTML; - /* eslint-enable no-param-reassign -- impossible to satisfy */ - } else if (el.children.length && el.children[0].className === classNAME) { - [textWriteWrapper] = el.children; - } - return textWriteWrapper; -} - -function getTextPartsArray(el, classNAME) { - let elementsArray = []; - const len = el.children.length; - if (len) { - const textParts = []; - let remainingMarkup = el.innerHTML; - let wrapperParts; - - for (let i = 0, currentChild, childOuter, unTaggedContent; i < len; i += 1) { - currentChild = el.children[i]; - childOuter = currentChild.outerHTML; - wrapperParts = remainingMarkup.split(childOuter); - - if (wrapperParts[0] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0], ''); - } else if (wrapperParts[1] !== '') { - unTaggedContent = wrapContentsSpan(wrapperParts[1].split('<')[0], classNAME); - textParts.push(unTaggedContent); - remainingMarkup = remainingMarkup.replace(wrapperParts[0].split('<')[0], ''); - } - - if (!currentChild.classList.contains(classNAME)) currentChild.classList.add(classNAME); - textParts.push(currentChild); - remainingMarkup = remainingMarkup.replace(childOuter, ''); - } - - if (remainingMarkup !== '') { - const unTaggedRemaining = wrapContentsSpan(remainingMarkup, classNAME); - textParts.push(unTaggedRemaining); - } - - elementsArray = elementsArray.concat(textParts); - } else { - elementsArray = elementsArray.concat([wrapContentsSpan(el, classNAME)]); - } - return elementsArray; -} - -function setSegments(target, newText) { - const oldTargetSegs = getTextPartsArray(target, 'text-part'); - const newTargetSegs = getTextPartsArray(wrapContentsSpan(newText), 'text-part'); - - /* eslint-disable no-param-reassign */ - target.innerHTML = ''; - target.innerHTML += oldTargetSegs.map((s) => { s.className += ' oldText'; return s.outerHTML; }).join(''); - target.innerHTML += newTargetSegs.map((s) => { s.className += ' newText'; return s.outerHTML.replace(s.innerHTML, ''); }).join(''); - /* eslint-enable no-param-reassign */ - - return [oldTargetSegs, newTargetSegs]; -} - -export function createTextTweens(target, newText, ops) { - if (target.playing) return false; - - const options = ops || {}; - options.duration = 1000; - - if (ops.duration === 'auto') { - options.duration = 'auto'; - } else if (Number.isFinite(ops.duration * 1)) { - options.duration = ops.duration * 1; - } - - const TweenContructor = connect.tween; - const segs = setSegments(target, newText); - const oldTargetSegs = segs[0]; - const newTargetSegs = segs[1]; - const oldTargets = [].slice.call(target.getElementsByClassName('oldText')).reverse(); - const newTargets = [].slice.call(target.getElementsByClassName('newText')); - - let textTween = []; - let totalDelay = 0; - - textTween = textTween.concat(oldTargets.map((el, i) => { - options.duration = options.duration === 'auto' - ? oldTargetSegs[i].innerHTML.length * 75 - : options.duration; - options.delay = totalDelay; - options.onComplete = null; - - totalDelay += options.duration; - return new TweenContructor(el, { text: el.innerHTML }, { text: '' }, options); - })); - textTween = textTween.concat(newTargets.map((el, i) => { - function onComplete() { - /* eslint-disable no-param-reassign */ - target.innerHTML = newText; - target.playing = false; - /* eslint-enable no-param-reassign */ - } - - options.duration = options.duration === 'auto' ? newTargetSegs[i].innerHTML.length * 75 : options.duration; - options.delay = totalDelay; - options.onComplete = i === newTargetSegs.length - 1 ? onComplete : null; - totalDelay += options.duration; - - return new TweenContructor(el, { text: '' }, { text: newTargetSegs[i].innerHTML }, options); - })); - - textTween.start = function startTweens() { - if (!target.playing) { - textTween.forEach((tw) => tw.start()); - // eslint-disable-next-line no-param-reassign - target.playing = true; - } - }; - - return textTween; -} - -// Component Functions -/** - * Returns the current element `innerHTML`. - * @returns {string} computed style for property - */ -function getWrite(/* tweenProp, value */) { - return this.element.innerHTML; -} - -/** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number | string} the property tween object - */ -function prepareText(tweenProp, value) { - if (tweenProp === 'number') { - return parseFloat(value); - } - // empty strings crash the update function - return value === '' ? ' ' : value; -} - -// All Component Functions -export const textWriteFunctions = { - prepareStart: getWrite, - prepareProperty: prepareText, - onStart: onStartWrite, -}; - -// Full Component -export const TextWrite = { - component: 'textWriteProperties', - category: 'textWrite', - properties: ['text', 'number'], - defaultValues: { text: ' ', number: '0' }, - defaultOptions: { textChars: 'alpha' }, - Interpolate: { numbers }, - functions: textWriteFunctions, - // export to global for faster execution - Util: { charSet, createTextTweens }, -}; - -export default TextWrite; diff --git a/src/components/textWriteBase.js b/src/components/textWriteBase.js deleted file mode 100644 index 329c3e6..0000000 --- a/src/components/textWriteBase.js +++ /dev/null @@ -1,102 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import defaultOptions from '../objects/defaultOptions'; - -// Component Values -const lowerCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').split(''); // lowercase -const upperCaseAlpha = String('abcdefghijklmnopqrstuvwxyz').toUpperCase().split(''); // uppercase -const nonAlpha = String("~!@#$%^&*()_+{}[];'<>,./?=-").split(''); // symbols -const numeric = String('0123456789').split(''); // numeric -const alphaNumeric = lowerCaseAlpha.concat(upperCaseAlpha, numeric); // alpha numeric -const allTypes = alphaNumeric.concat(nonAlpha); // all caracters - -const charSet = { - alpha: lowerCaseAlpha, // lowercase - upper: upperCaseAlpha, // uppercase - symbols: nonAlpha, // symbols - numeric, - alphanumeric: alphaNumeric, - all: allTypes, -}; - -export { charSet }; - -// Component Functions -export const onStartWrite = { - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - text(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - const chars = this._textChars; - let charsets = charSet[defaultOptions.textChars]; - - if (chars in charSet) { - charsets = charSet[chars]; - } else if (chars && chars.length) { - charsets = chars; - } - - KEC[tweenProp] = (elem, a, b, v) => { - let initialText = ''; - let endText = ''; - const finalText = b === '' ? ' ' : b; - const firstLetterA = a.substring(0); - const firstLetterB = b.substring(0); - /* eslint-disable */ - const pointer = charsets[(Math.random() * charsets.length) >> 0]; - - if (a === ' ') { - endText = firstLetterB - .substring(Math.min(v * firstLetterB.length, firstLetterB.length) >> 0, 0); - elem.innerHTML = v < 1 ? ((endText + pointer)) : finalText; - } else if (b === ' ') { - initialText = firstLetterA - .substring(0, Math.min((1 - v) * firstLetterA.length, firstLetterA.length) >> 0); - elem.innerHTML = v < 1 ? ((initialText + pointer)) : finalText; - } else { - initialText = firstLetterA - .substring(firstLetterA.length, - Math.min(v * firstLetterA.length, firstLetterA.length) >> 0); - endText = firstLetterB - .substring(0, Math.min(v * firstLetterB.length, firstLetterB.length) >> 0); - elem.innerHTML = v < 1 ? ((endText + pointer + initialText)) : finalText; - } - /* eslint-enable */ - }; - } - }, - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - number(tweenProp) { - if (tweenProp in this.valuesEnd && !KEC[tweenProp]) { // numbers can be 0 - KEC[tweenProp] = (elem, a, b, v) => { - /* eslint-disable */ - elem.innerHTML = numbers(a, b, v) >> 0; - /* eslint-enable */ - }; - } - }, -}; - -// Base Component -export const TextWriteBase = { - component: 'baseTextWrite', - category: 'textWrite', - // properties: ['text','number'], - // defaultValues: {text: ' ',numbers:'0'}, - defaultOptions: { textChars: 'alpha' }, - Interpolate: { numbers }, - functions: { onStart: onStartWrite }, - // export to global for faster execution - Util: { charSet }, -}; - -export default TextWriteBase; diff --git a/src/components/transformFunctions.js b/src/components/transformFunctions.js deleted file mode 100644 index 0c912cf..0000000 --- a/src/components/transformFunctions.js +++ /dev/null @@ -1,152 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import getInlineStyle from '../process/getInlineStyle'; -import perspective from '../interpolation/perspective'; -import translate3d from '../interpolation/translate3d'; -import rotate3d from '../interpolation/rotate3d'; -import translate from '../interpolation/translate'; -import rotate from '../interpolation/rotate'; -import scale from '../interpolation/scale'; -import skew from '../interpolation/skew'; -import { onStartTransform } from './transformFunctionsBase'; - -// same to svg transform, attr -// the component developed for modern browsers supporting non-prefixed transform - -// Component Functions -/** - * Returns the current property inline style. - * @param {string} tweenProp the property name - * @returns {string} inline style for property - */ -function getTransform(tweenProp/* , value */) { - const currentStyle = getInlineStyle(this.element); - return currentStyle[tweenProp] ? currentStyle[tweenProp] : defaultValues[tweenProp]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ -function prepareTransform(/* prop, */_, obj) { - const prepAxis = ['X', 'Y', 'Z']; // coordinates - const transformObject = {}; - const translateArray = []; const rotateArray = []; const skewArray = []; - const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew']; - - Object.keys(obj).forEach((x) => { - const pv = typeof obj[x] === 'object' && obj[x].length - ? obj[x].map((v) => parseInt(v, 10)) - : parseInt(obj[x], 10); - - if (arrayFunctions.includes(x)) { - const propId = x === 'translate' || x === 'rotate' ? `${x}3d` : x; - - if (x === 'skew') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0] - : [pv || 0, 0]; - } else if (x === 'translate') { - transformObject[propId] = pv.length - ? [pv[0] || 0, pv[1] || 0, pv[2] || 0] - : [pv || 0, 0, 0]; - } else { // translate3d | rotate3d - transformObject[propId] = [pv[0] || 0, pv[1] || 0, pv[2] || 0]; - } - } else if (/[XYZ]/.test(x)) { - const fn = x.replace(/[XYZ]/, ''); - const fnId = fn === 'skew' ? fn : `${fn}3d`; - const fnLen = fn === 'skew' ? 2 : 3; - let fnArray = []; - - if (fn === 'translate') { - fnArray = translateArray; - } else if (fn === 'rotate') { - fnArray = rotateArray; - } else if (fn === 'skew') { - fnArray = skewArray; - } - - for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) { - const fnAxis = prepAxis[fnIndex]; - fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0; - } - transformObject[fnId] = fnArray; - } else if (x === 'rotate') { // rotate - transformObject.rotate3d = [0, 0, pv]; - } else { // scale | perspective - transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv; - } - }); - - return transformObject; -} - -/** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ -function crossCheckTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } - } -} - -// All Component Functions -const transformFunctions = { - prepareStart: getTransform, - prepareProperty: prepareTransform, - onStart: onStartTransform, - crossCheck: crossCheckTransform, -}; - -const supportedTransformProperties = [ - 'perspective', - 'translate3d', 'translateX', 'translateY', 'translateZ', 'translate', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate', - 'skewX', 'skewY', 'skew', - 'scale', -]; - -const defaultTransformValues = { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - translate: [0, 0], - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - rotate: 0, - skewX: 0, - skewY: 0, - skew: [0, 0], - scale: 1, -}; - -// Full Component -const TransformFunctions = { - component: 'transformFunctions', - property: 'transform', - subProperties: supportedTransformProperties, - defaultValues: defaultTransformValues, - functions: transformFunctions, - Interpolate: { - perspective, - translate3d, - rotate3d, - translate, - rotate, - scale, - skew, - }, -}; - -export default TransformFunctions; diff --git a/src/components/transformFunctionsBase.js b/src/components/transformFunctionsBase.js deleted file mode 100644 index c1e9290..0000000 --- a/src/components/transformFunctionsBase.js +++ /dev/null @@ -1,45 +0,0 @@ -import KEC from '../objects/kute'; -import perspective from '../interpolation/perspective'; -import translate3d from '../interpolation/translate3d'; -import rotate3d from '../interpolation/rotate3d'; -import translate from '../interpolation/translate'; -import rotate from '../interpolation/rotate'; -import scale from '../interpolation/scale'; -import skew from '../interpolation/skew'; - -// Component Functions -/** - * Sets the property update function. - * * same to svgTransform, htmlAttributes - * @param {string} tweenProp the property name - */ -export function onStartTransform(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0 - + (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z] - + (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z] - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } -} - -// Base Component -const TransformFunctionsBase = { - component: 'baseTransform', - property: 'transform', - functions: { onStart: onStartTransform }, - Interpolate: { - perspective, - translate3d, - rotate3d, - translate, - rotate, - scale, - skew, - }, -}; - -export default TransformFunctionsBase; diff --git a/src/components/transformLegacy.js b/src/components/transformLegacy.js deleted file mode 100644 index 6a3453f..0000000 --- a/src/components/transformLegacy.js +++ /dev/null @@ -1,172 +0,0 @@ -import support3DTransform from 'shorter-js/src/boolean/support3DTransform'; -import defaultValues from '../objects/defaultValues'; -import getInlineStyleLegacy from '../process/getInlineStyleLegacy'; -import perspective from '../interpolation/perspective'; -import translate3d from '../interpolation/translate3d'; -import rotate3d from '../interpolation/rotate3d'; -import translate from '../interpolation/translate'; -import rotate from '../interpolation/rotate'; -import scale from '../interpolation/scale'; -import skew from '../interpolation/skew'; - -import { onStartLegacyTransform } from './transformLegacyBase'; -import transformProperty from '../util/transformProperty'; -import supportTransform from '../util/supportLegacyTransform'; - -// same to svg transform, attr -// the component to handle all kinds of input values and process according to browser supported API, -// the component that handles all browsers IE9+ - -// Component Functions -/** - * Returns the current property inline style. - * @param {string} tweenProperty the property name - * @returns {string} inline style for property - */ -function getLegacyTransform(tweenProperty/* , value */) { - const currentStyle = getInlineStyleLegacy(this.element); - return currentStyle[tweenProperty] ? currentStyle[tweenProperty] : defaultValues[tweenProperty]; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ -function prepareLegacyTransform(/* prop */_, obj) { - const prepAxis = ['X', 'Y', 'Z']; // coordinates - const translateArray = []; const rotateArray = []; const skewArray = []; - const transformObject = {}; - const arrayFunctions = ['translate3d', 'translate', 'rotate3d', 'skew']; - - Object.keys(obj).forEach((x) => { - const pv = typeof (obj[x]) === 'object' && obj[x].length - ? obj[x].map((v) => parseInt(v, 10)) - : parseInt(obj[x], 10); - - if (arrayFunctions.includes(x)) { - if (support3DTransform) { - if (x === 'translate3d' || x === 'rotate3d') { - transformObject[x] = pv; - } else if (x === 'translate') { - transformObject.translate3d = pv.length ? pv.concat(0) : [pv || 0, 0, 0]; - } else if (x === 'rotate') { - transformObject.rotate3d = [0, 0, pv || 0]; - } else if (x === 'skew') { - transformObject[x] = pv.length ? pv : [pv || 0, 0]; - } - } else if (supportTransform) { - if (x === 'translate3d') { - transformObject.translate = [pv[0] || 0, pv[1] || 0]; - } else if (x === 'translate' || x === 'skew') { - transformObject[x] = pv.length ? pv : [pv || 0, 0]; - } else if (x === 'rotate3d') { - transformObject.rotate = pv[2] || pv[1] || pv[0]; - } else if (x === 'rotate') { - transformObject[x] = pv; - } - } - } else if (/[XYZ]/.test(x)) { - const fn = x.replace(/[XYZ]/, ''); - const fnId = fn === 'skew' || !support3DTransform ? fn : `${fn}3d`; - const fnLen = fn === 'skew' || (!support3DTransform && fn === 'translate') ? 2 : 3; - let fnArray = []; - - if (fn === 'translate') { - fnArray = translateArray; - } else if (fn === 'rotate') { - fnArray = rotateArray; - } else if (fn === 'skew') { - fnArray = skewArray; - } - - for (let fnIndex = 0; fnIndex < fnLen; fnIndex += 1) { - const fnAxis = prepAxis[fnIndex]; - fnArray[fnIndex] = (`${fn}${fnAxis}` in obj) ? parseInt(obj[`${fn}${fnAxis}`], 10) : 0; - } - - if (support3DTransform) { - transformObject[fnId] = fnArray; - } else { - transformObject[fnId] = fn === 'rotate' ? (fnArray[2] || fnArray[1] || fnArray[0]) : fnArray; - } - } else if (x === 'rotate') { // 2d rotate - const pType = support3DTransform ? 'rotate3d' : 'rotate'; - transformObject[pType] = support3DTransform ? [0, 0, pv] : pv; - } else { // scale | perspective - transformObject[x] = x === 'scale' ? parseFloat(obj[x]) : pv; - } - }); - - return transformObject; -} - -/** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ -function crossCheckLegacyTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp] && support3DTransform) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } - } -} - -// All Component Functions -const transformLegacyFunctions = { - prepareStart: getLegacyTransform, - prepareProperty: prepareLegacyTransform, - onStart: onStartLegacyTransform, - crossCheck: crossCheckLegacyTransform, -}; - -const legacyTransformValues = { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - translate: [0, 0], - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - rotate: 0, - skewX: 0, - skewY: 0, - skew: [0, 0], - scale: 1, -}; - -const legacyTransformProperties = [ - 'perspective', - 'translate3d', 'translateX', 'translateY', 'translateZ', 'translate', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'rotate', - 'skewX', 'skewY', 'skew', - 'scale', -]; - -// Full Component -const transformLegacyComponent = { - component: 'transformFunctions', - property: 'transform', - subProperties: legacyTransformProperties, - defaultValues: legacyTransformValues, - functions: transformLegacyFunctions, - Interpolate: { - perspective, - translate3d, - rotate3d, - translate, - rotate, - scale, - skew, - }, - Util: [transformProperty], -}; - -export default transformLegacyComponent; diff --git a/src/components/transformLegacyBase.js b/src/components/transformLegacyBase.js deleted file mode 100644 index e26315f..0000000 --- a/src/components/transformLegacyBase.js +++ /dev/null @@ -1,62 +0,0 @@ -import support3DTransform from 'shorter-js/src/boolean/support3DTransform'; -import KEC from '../objects/kute'; -import perspective from '../interpolation/perspective'; -import translate3d from '../interpolation/translate3d'; -import rotate3d from '../interpolation/rotate3d'; -import translate from '../interpolation/translate'; -import rotate from '../interpolation/rotate'; -import scale from '../interpolation/scale'; -import skew from '../interpolation/skew'; - -import supportTransform from '../util/supportLegacyTransform'; -import transformProperty from '../util/transformProperty'; - -// same as svgTransform, htmlAttributes -// the component that handles all browsers IE9+ - -// Component Functions -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ -export function onStartLegacyTransform(tweenProp) { - if (!KEC[tweenProp] && this.valuesEnd[tweenProp]) { - if (support3DTransform) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[transformProperty] = (a.perspective || b.perspective ? perspective(a.perspective, b.perspective, 'px', v) : '') // one side might be 0 - + (a.translate3d ? translate3d(a.translate3d, b.translate3d, 'px', v) : '') // array [x,y,z] - + (a.rotate3d ? rotate3d(a.rotate3d, b.rotate3d, 'deg', v) : '') // array [x,y,z] - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } else if (supportTransform) { - KEC[tweenProp] = (elem, a, b, v) => { - // eslint-disable-next-line no-param-reassign - elem.style[transformProperty] = (a.translate ? translate(a.translate, b.translate, 'px', v) : '') // array [x,y] - + ((a.rotate || b.rotate) ? rotate(a.rotate, b.rotate, 'deg', v) : '') // one side might be 0 - + (a.skew ? skew(a.skew, b.skew, 'deg', v) : '') // array [x,y] - + (a.scale || b.scale ? scale(a.scale, b.scale, v) : ''); // one side might be 0 - }; - } - } -} - -// Base Component -const BaseLegacyTransform = { - component: 'baseLegacyTransform', - property: 'transform', - functions: { onStart: onStartLegacyTransform }, - Interpolate: { - perspective, - translate3d, - rotate3d, - translate, - rotate, - scale, - skew, - }, - Util: { transformProperty }, -}; - -export default BaseLegacyTransform; diff --git a/src/components/transformMatrix.js b/src/components/transformMatrix.js deleted file mode 100644 index 1a03f8e..0000000 --- a/src/components/transformMatrix.js +++ /dev/null @@ -1,165 +0,0 @@ -import defaultValues from '../objects/defaultValues'; -import numbers from '../interpolation/numbers'; -import arrays from '../interpolation/arrays'; -import { onStartTransform } from './transformMatrixBase'; - -// Component name -const matrixComponent = 'transformMatrix'; - -// Component Functions -/** - * Returns the current transform object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.transformMObject} transform object - */ -function getTransform(/* tweenProp, */_, value) { - const transformObject = {}; - const currentValue = this.element[matrixComponent]; - - if (currentValue) { - Object.keys(currentValue).forEach((vS) => { - transformObject[vS] = currentValue[vS]; - }); - } else { - Object.keys(value).forEach((vE) => { - transformObject[vE] = vE === 'perspective' ? value[vE] : defaultValues.transform[vE]; - }); - } - return transformObject; -} - -/** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformMObject} the property tween object - */ -function prepareTransform(/* tweenProp, */_, value) { - if (typeof (value) === 'object' && !value.length) { - let pv; - const transformObject = {}; - const translate3dObj = {}; - const rotate3dObj = {}; - const scale3dObj = {}; - const skewObj = {}; - const axis = [{ translate3d: translate3dObj }, - { rotate3d: rotate3dObj }, - { skew: skewObj }, - { scale3d: scale3dObj }]; - - Object.keys(value).forEach((prop) => { - if (/3d/.test(prop) && typeof (value[prop]) === 'object' && value[prop].length) { - pv = value[prop].map((v) => (prop === 'scale3d' ? parseFloat(v) : parseInt(v, 10))); - transformObject[prop] = prop === 'scale3d' ? [pv[0] || 1, pv[1] || 1, pv[2] || 1] : [pv[0] || 0, pv[1] || 0, pv[2] || 0]; - } else if (/[XYZ]/.test(prop)) { - let obj = {}; - if (/translate/.test(prop)) { - obj = translate3dObj; - } else if (/rotate/.test(prop)) { - obj = rotate3dObj; - } else if (/scale/.test(prop)) { - obj = scale3dObj; - } else if (/skew/.test(prop)) { - obj = skewObj; - } - const idx = prop.replace(/translate|rotate|scale|skew/, '').toLowerCase(); - obj[idx] = /scale/.test(prop) ? parseFloat(value[prop]) : parseInt(value[prop], 10); - } else if (prop === 'skew') { - pv = value[prop].map((v) => parseInt(v, 10) || 0); - transformObject[prop] = [pv[0] || 0, pv[1] || 0]; - } else { // perspective - transformObject[prop] = parseInt(value[prop], 10); - } - }); - - axis.forEach((o) => { - const tp = Object.keys(o)[0]; - const tv = o[tp]; - if (Object.keys(tv).length && !transformObject[tp]) { - if (tp === 'scale3d') { - transformObject[tp] = [tv.x || 1, tv.y || 1, tv.z || 1]; - } else if (tp === 'skew') { - transformObject[tp] = [tv.x || 0, tv.y || 0]; - } else { // translate | rotate - transformObject[tp] = [tv.x || 0, tv.y || 0, tv.z || 0]; - } - } - }); - return transformObject; - } // string | array - // if ( typeof (value) === 'object' && value.length ) { - // } else if ( typeof (value) === string && value.includes('matrix')) { - // decompose matrix to object - throw Error(`KUTE.js - "${value}" is not valid/supported transform function`); -} - -/** - * Sets the end values for the next `to()` method call. - * @param {string} tweenProp the property name - */ -function onCompleteTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - this.element[matrixComponent] = { ...this.valuesEnd[tweenProp] }; - } -} - -/** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ -function crossCheckTransform(tweenProp) { - if (this.valuesEnd[tweenProp]) { - if (this.valuesEnd[tweenProp].perspective && !this.valuesStart[tweenProp].perspective) { - this.valuesStart[tweenProp].perspective = this.valuesEnd[tweenProp].perspective; - } - } -} - -// All Component Functions -const matrixFunctions = { - prepareStart: getTransform, - prepareProperty: prepareTransform, - onStart: onStartTransform, - onComplete: onCompleteTransform, - crossCheck: crossCheckTransform, -}; - -// Component Full Object -const matrixTransform = { - component: matrixComponent, - property: 'transform', - /* subProperties: [ - 'perspective', 'translate3d', 'translateX', 'translateY', 'translateZ', - 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', - 'skew','skewX','skewY', - 'scale3d', 'scaleX', 'scaleY', 'scaleZ'], */ - defaultValue: { - perspective: 400, - translate3d: [0, 0, 0], - translateX: 0, - translateY: 0, - translateZ: 0, - rotate3d: [0, 0, 0], - rotateX: 0, - rotateY: 0, - rotateZ: 0, - skew: [0, 0], - skewX: 0, - skewY: 0, - scale3d: [1, 1, 1], - scaleX: 1, - scaleY: 1, - scaleZ: 1, - }, - functions: matrixFunctions, - Interpolate: { - perspective: numbers, - translate3d: arrays, - rotate3d: arrays, - skew: arrays, - scale3d: arrays, - }, -}; - -export default matrixTransform; diff --git a/src/components/transformMatrixBase.js b/src/components/transformMatrixBase.js deleted file mode 100644 index e4c483c..0000000 --- a/src/components/transformMatrixBase.js +++ /dev/null @@ -1,85 +0,0 @@ -import KEC from '../objects/kute'; -import numbers from '../interpolation/numbers'; -import arrays from '../interpolation/arrays'; - -// Component name -const matrixComponent = 'transformMatrixBase'; - -// Component special -// this component is restricted to modern browsers only -const CSS3Matrix = typeof (DOMMatrix) !== 'undefined' ? DOMMatrix : null; - -// Component Functions -export const onStartTransform = { -/** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - transform(tweenProp) { - if (CSS3Matrix && this.valuesEnd[tweenProp] && !KEC[tweenProp]) { - KEC[tweenProp] = (elem, a, b, v) => { - let matrix = new CSS3Matrix(); - const tObject = {}; - - Object.keys(b).forEach((p) => { - tObject[p] = p === 'perspective' ? numbers(a[p], b[p], v) : arrays(a[p], b[p], v); - }); - - // set perspective - if (tObject.perspective) matrix.m34 = -1 / tObject.perspective; - - // set translate - matrix = tObject.translate3d - ? matrix.translate(tObject.translate3d[0], tObject.translate3d[1], tObject.translate3d[2]) - : matrix; - - // set rotation - matrix = tObject.rotate3d - ? matrix.rotate(tObject.rotate3d[0], tObject.rotate3d[1], tObject.rotate3d[2]) - : matrix; - - // set skew - if (tObject.skew) { - matrix = tObject.skew[0] ? matrix.skewX(tObject.skew[0]) : matrix; - matrix = tObject.skew[1] ? matrix.skewY(tObject.skew[1]) : matrix; - } - - // set scale - matrix = tObject.scale3d - ? matrix.scale(tObject.scale3d[0], tObject.scale3d[1], tObject.scale3d[2]) - : matrix; - - // set element style - // eslint-disable-next-line no-param-reassign - elem.style[tweenProp] = matrix.toString(); - }; - } - }, - /** - * onStartTransform.CSS3Matrix - * - * Sets the update function for the property. - * @param {string} prop the property name - */ - CSS3Matrix(prop) { - if (CSS3Matrix && this.valuesEnd.transform) { - if (!KEC[prop]) KEC[prop] = CSS3Matrix; - } - }, -}; - -// Component Base Object -export const TransformMatrixBase = { - component: matrixComponent, - property: 'transform', - functions: { onStart: onStartTransform }, - Interpolate: { - perspective: numbers, - translate3d: arrays, - rotate3d: arrays, - skew: arrays, - scale3d: arrays, - }, -}; - -export default TransformMatrixBase; diff --git a/src/core/add.js b/src/core/add.js deleted file mode 100644 index 5541819..0000000 --- a/src/core/add.js +++ /dev/null @@ -1,10 +0,0 @@ -import Tweens from '../objects/tweens'; - -/** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ -const add = (tw) => Tweens.push(tw); - -export default add; diff --git a/src/core/getAll.js b/src/core/getAll.js deleted file mode 100644 index 11804ef..0000000 --- a/src/core/getAll.js +++ /dev/null @@ -1,10 +0,0 @@ -import Tweens from '../objects/tweens'; - -/** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ -const getAll = () => Tweens; - -export default getAll; diff --git a/src/core/internals.js b/src/core/internals.js deleted file mode 100644 index 5acd67b..0000000 --- a/src/core/internals.js +++ /dev/null @@ -1,17 +0,0 @@ -import add from './add'; -import remove from './remove'; -import getAll from './getAll'; -import removeAll from './removeAll'; -import { stop } from './render'; -import linkInterpolation from './linkInterpolation'; - -const internals = { - add, - remove, - getAll, - removeAll, - stop, - linkInterpolation, -}; - -export default internals; diff --git a/src/core/linkInterpolation.js b/src/core/linkInterpolation.js deleted file mode 100644 index a4313de..0000000 --- a/src/core/linkInterpolation.js +++ /dev/null @@ -1,39 +0,0 @@ -import KEC from '../objects/kute'; -import linkProperty from '../objects/linkProperty'; -import supportedProperties from '../objects/supportedProperties'; - -/** - * linkInterpolation - * @this {KUTE.Tween} - */ -export default function linkInterpolation() { // DON'T change - Object.keys(linkProperty).forEach((component) => { - const componentLink = linkProperty[component]; - const componentProps = supportedProperties[component]; - - Object.keys(componentLink).forEach((fnObj) => { - if (typeof (componentLink[fnObj]) === 'function' // ATTR, colors, scroll, boxModel, borderRadius - && Object.keys(this.valuesEnd).some((i) => (componentProps && componentProps.includes(i)) - || (i === 'attr' && Object.keys(this.valuesEnd[i]).some((j) => componentProps && componentProps.includes(j))))) { - if (!KEC[fnObj]) KEC[fnObj] = componentLink[fnObj]; - } else { - Object.keys(this.valuesEnd).forEach((prop) => { - const propObject = this.valuesEnd[prop]; - if (propObject instanceof Object) { - Object.keys(propObject).forEach((i) => { - if (typeof (componentLink[i]) === 'function') { // transformCSS3 - if (!KEC[i]) KEC[i] = componentLink[i]; - } else { - Object.keys(componentLink[fnObj]).forEach((j) => { - if (componentLink[i] && typeof (componentLink[i][j]) === 'function') { // transformMatrix - if (!KEC[j]) KEC[j] = componentLink[i][j]; - } - }); - } - }); - } - }); - } - }); - }); -} diff --git a/src/core/queueStart.js b/src/core/queueStart.js deleted file mode 100644 index 8facc72..0000000 --- a/src/core/queueStart.js +++ /dev/null @@ -1,18 +0,0 @@ -import onStart from '../objects/onStart'; -import linkInterpolation from './linkInterpolation'; - -export default function queueStart() { - // fire onStart actions - Object.keys(onStart).forEach((obj) => { - if (typeof (onStart[obj]) === 'function') { - onStart[obj].call(this, obj); // easing functions - } else { - Object.keys(onStart[obj]).forEach((prop) => { - onStart[obj][prop].call(this, prop); - }); - } - }); - - // add interpolations - linkInterpolation.call(this); -} diff --git a/src/core/remove.js b/src/core/remove.js deleted file mode 100644 index 3839303..0000000 --- a/src/core/remove.js +++ /dev/null @@ -1,13 +0,0 @@ -import Tweens from '../objects/tweens'; - -/** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ -const remove = (tw) => { - const i = Tweens.indexOf(tw); - if (i !== -1) Tweens.splice(i, 1); -}; - -export default remove; diff --git a/src/core/removeAll.js b/src/core/removeAll.js deleted file mode 100644 index 7760fd0..0000000 --- a/src/core/removeAll.js +++ /dev/null @@ -1,8 +0,0 @@ -import Tweens from '../objects/tweens'; - -/** - * KUTE.removeAll() - */ -const removeAll = () => { Tweens.length = 0; }; - -export default removeAll; diff --git a/src/core/render.js b/src/core/render.js deleted file mode 100644 index c810476..0000000 --- a/src/core/render.js +++ /dev/null @@ -1,67 +0,0 @@ -import KEC from '../objects/kute'; -import Tweens from '../objects/tweens'; -import globalObject from '../objects/globalObject'; -import Interpolate from '../objects/interpolate'; -import onStart from '../objects/onStart'; -import now from '../util/now'; - -const Time = {}; -Time.now = now; - -// eslint-disable-next-line import/no-mutable-exports -- impossible to satisfy -let Tick = 0; -export { Tick }; - -/** - * - * @param {number | Date} time - */ -const Ticker = (time) => { - let i = 0; - while (i < Tweens.length) { - if (Tweens[i].update(time)) { - i += 1; - } else { - Tweens.splice(i, 1); - } - } - Tick = requestAnimationFrame(Ticker); -}; -export { Ticker }; - -// stop requesting animation frame -export function stop() { - setTimeout(() => { // re-added for #81 - if (!Tweens.length && Tick) { - cancelAnimationFrame(Tick); - Tick = null; - Object.keys(onStart).forEach((obj) => { - if (typeof (onStart[obj]) === 'function') { - if (KEC[obj]) delete KEC[obj]; - } else { - Object.keys(onStart[obj]).forEach((prop) => { - if (KEC[prop]) delete KEC[prop]; - }); - } - }); - - Object.keys(Interpolate).forEach((i) => { - if (KEC[i]) delete KEC[i]; - }); - } - }, 64); -} - -// render update functions -// ======================= -const Render = { - Tick, Ticker, Tweens, Time, -}; -Object.keys(Render).forEach((blob) => { - if (!KEC[blob]) { - KEC[blob] = blob === 'Time' ? Time.now : Render[blob]; - } -}); - -globalObject._KUTE = KEC; -export default Render; diff --git a/src/easing/easing-base.js b/src/easing/easing-base.js deleted file mode 100644 index 752a682..0000000 --- a/src/easing/easing-base.js +++ /dev/null @@ -1,64 +0,0 @@ -import connect from '../objects/connect'; - -// Select Robert Penner's Easing Functions -// updated for ESLint -const Easing = { - /** @type {KUTE.easingFunction} */ - linear: (t) => t, - /** @type {KUTE.easingFunction} */ - easingQuadraticIn: (t) => t * t, - /** @type {KUTE.easingFunction} */ - easingQuadraticOut: (t) => t * (2 - t), - /** @type {KUTE.easingFunction} */ - easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t), - /** @type {KUTE.easingFunction} */ - easingCubicIn: (t) => t * t * t, - /** @type {KUTE.easingFunction} */ - easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; }, - /** @type {KUTE.easingFunction} */ - easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1), - /** @type {KUTE.easingFunction} */ - easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1), - /** @type {KUTE.easingFunction} */ - easingCircularOut: (t0) => { const t = t0 - 1; return Math.sqrt(1 - t * t); }, - /** @type {KUTE.easingFunction} */ - 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); - }, - /** @type {KUTE.easingFunction} */ - easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); }, - /** @type {KUTE.easingFunction} */ - easingBackOut: (t0) => { - const s = 1.70158; - const t = t0 - 1; - return t * t * ((s + 1) * t + s) + 1; - }, - /** @type {KUTE.easingFunction} */ - easingBackInOut: (t0) => { - const s = 1.70158 * 1.525; - let t = t0 * 2; - if (t < 1) return 0.5 * (t * t * ((s + 1) * t - s)); - t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2); - }, -}; - -/** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easing function - */ -function processEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof Easing[fn] === 'function') { - return Easing[fn]; // regular Robert Penner Easing Functions - } - return Easing.linear; -} - -connect.processEasing = processEasing; - -export default Easing; diff --git a/src/easing/easing-bezier.js b/src/easing/easing-bezier.js deleted file mode 100644 index 47a511b..0000000 --- a/src/easing/easing-bezier.js +++ /dev/null @@ -1,62 +0,0 @@ -import CubicBezier from 'cubic-bezier-easing'; -import connect from '../objects/connect'; - -const Easing = { - linear: new CubicBezier(0, 0, 1, 1, 'linear'), - easingSinusoidalIn: new CubicBezier(0.47, 0, 0.745, 0.715, 'easingSinusoidalIn'), - easingSinusoidalOut: new CubicBezier(0.39, 0.575, 0.565, 1, 'easingSinusoidalOut'), - easingSinusoidalInOut: new CubicBezier(0.445, 0.05, 0.55, 0.95, 'easingSinusoidalInOut'), - - easingQuadraticIn: new CubicBezier(0.550, 0.085, 0.680, 0.530, 'easingQuadraticIn'), - easingQuadraticOut: new CubicBezier(0.250, 0.460, 0.450, 0.940, 'easingQuadraticOut'), - easingQuadraticInOut: new CubicBezier(0.455, 0.030, 0.515, 0.955, 'easingQuadraticInOut'), - - easingCubicIn: new CubicBezier(0.55, 0.055, 0.675, 0.19, 'easingCubicIn'), - easingCubicOut: new CubicBezier(0.215, 0.61, 0.355, 1, 'easingCubicOut'), - easingCubicInOut: new CubicBezier(0.645, 0.045, 0.355, 1, 'easingCubicInOut'), - - easingQuarticIn: new CubicBezier(0.895, 0.03, 0.685, 0.22, 'easingQuarticIn'), - easingQuarticOut: new CubicBezier(0.165, 0.84, 0.44, 1, 'easingQuarticOut'), - easingQuarticInOut: new CubicBezier(0.77, 0, 0.175, 1, 'easingQuarticInOut'), - - easingQuinticIn: new CubicBezier(0.755, 0.05, 0.855, 0.06, 'easingQuinticIn'), - easingQuinticOut: new CubicBezier(0.23, 1, 0.32, 1, 'easingQuinticOut'), - easingQuinticInOut: new CubicBezier(0.86, 0, 0.07, 1, 'easingQuinticInOut'), - - easingExponentialIn: new CubicBezier(0.95, 0.05, 0.795, 0.035, 'easingExponentialIn'), - easingExponentialOut: new CubicBezier(0.19, 1, 0.22, 1, 'easingExponentialOut'), - easingExponentialInOut: new CubicBezier(1, 0, 0, 1, 'easingExponentialInOut'), - - easingCircularIn: new CubicBezier(0.6, 0.04, 0.98, 0.335, 'easingCircularIn'), - easingCircularOut: new CubicBezier(0.075, 0.82, 0.165, 1, 'easingCircularOut'), - easingCircularInOut: new CubicBezier(0.785, 0.135, 0.15, 0.86, 'easingCircularInOut'), - - easingBackIn: new CubicBezier(0.6, -0.28, 0.735, 0.045, 'easingBackIn'), - easingBackOut: new CubicBezier(0.175, 0.885, 0.32, 1.275, 'easingBackOut'), - easingBackInOut: new CubicBezier(0.68, -0.55, 0.265, 1.55, 'easingBackInOut'), -}; - -/** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor name - * @returns {KUTE.easingFunction} a valid easingfunction - */ -function processBezierEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof (Easing[fn]) === 'function') { - return Easing[fn]; - } if (/bezier/.test(fn)) { - const bz = fn.replace(/bezier|\s|\(|\)/g, '').split(','); - return new CubicBezier(bz[0] * 1, bz[1] * 1, bz[2] * 1, bz[3] * 1); // bezier easing - } - // if (/elastic|bounce/i.test(fn)) { - // throw TypeError(`KUTE - CubicBezier doesn't support ${fn} easing.`); - // } - return Easing.linear; -} - -connect.processEasing = processBezierEasing; - -export default Easing; diff --git a/src/easing/easing.js b/src/easing/easing.js deleted file mode 100644 index 2c58d86..0000000 --- a/src/easing/easing.js +++ /dev/null @@ -1,169 +0,0 @@ -import connect from '../objects/connect'; - -// Robert Penner's Easing Functions -// updated for ESLint -const Easing = { - /** @type {KUTE.easingFunction} */ - linear: (t) => t, - /** @type {KUTE.easingFunction} */ - easingSinusoidalIn: (t) => -Math.cos((t * Math.PI) / 2) + 1, - /** @type {KUTE.easingFunction} */ - easingSinusoidalOut: (t) => Math.sin((t * Math.PI) / 2), - /** @type {KUTE.easingFunction} */ - easingSinusoidalInOut: (t) => -0.5 * (Math.cos(Math.PI * t) - 1), - /** @type {KUTE.easingFunction} */ - easingQuadraticIn: (t) => t * t, - /** @type {KUTE.easingFunction} */ - easingQuadraticOut: (t) => t * (2 - t), - /** @type {KUTE.easingFunction} */ - easingQuadraticInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t), - /** @type {KUTE.easingFunction} */ - easingCubicIn: (t) => t * t * t, - /** @type {KUTE.easingFunction} */ - easingCubicOut: (t0) => { const t = t0 - 1; return t * t * t + 1; }, - /** @type {KUTE.easingFunction} */ - easingCubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1), - /** @type {KUTE.easingFunction} */ - easingQuarticIn: (t) => t * t * t * t, - /** @type {KUTE.easingFunction} */ - easingQuarticOut: (t0) => { const t = t0 - 1; return 1 - t * t * t * t; }, - /** @type {KUTE.easingFunction} */ - easingQuarticInOut: (t0) => { - let t = t0; - if (t < 0.5) return 8 * t * t * t * t; - t -= 1; return 1 - 8 * t * t * t * t; - }, - /** @type {KUTE.easingFunction} */ - easingQuinticIn: (t) => t * t * t * t * t, - /** @type {KUTE.easingFunction} */ - easingQuinticOut: (t0) => { const t = t0 - 1; return 1 + t * t * t * t * t; }, - /** @type {KUTE.easingFunction} */ - easingQuinticInOut: (t0) => { - let t = t0; - if (t < 0.5) return 16 * t * t * t * t * t; - t -= 1; return 1 + 16 * t * t * t * t * t; - }, - /** @type {KUTE.easingFunction} */ - easingCircularIn: (t) => -(Math.sqrt(1 - (t * t)) - 1), - /** @type {KUTE.easingFunction} */ - easingCircularOut: (t0) => { const t = t0 - 1; return Math.sqrt(1 - t * t); }, - /** @type {KUTE.easingFunction} */ - 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); - }, - /** @type {KUTE.easingFunction} */ - easingExponentialIn: (t) => 2 ** (10 * (t - 1)) - 0.001, - /** @type {KUTE.easingFunction} */ - easingExponentialOut: (t) => 1 - 2 ** (-10 * t), - /** @type {KUTE.easingFunction} */ - easingExponentialInOut: (t0) => { - const t = t0 * 2; - if (t < 1) return 0.5 * (2 ** (10 * (t - 1))); - return 0.5 * (2 - 2 ** (-10 * (t - 1))); - }, - /** @type {KUTE.easingFunction} */ - easingBackIn: (t) => { const s = 1.70158; return t * t * ((s + 1) * t - s); }, - /** @type {KUTE.easingFunction} */ - easingBackOut: (t0) => { - const s = 1.70158; - const t = t0 - 1; - return t * t * ((s + 1) * t + s) + 1; - }, - /** @type {KUTE.easingFunction} */ - easingBackInOut: (t0) => { - const s = 1.70158 * 1.525; - let t = t0 * 2; - if (t < 1) return 0.5 * (t * t * ((s + 1) * t - s)); - t -= 2; return 0.5 * (t * t * ((s + 1) * t + s) + 2); - }, - /** @type {KUTE.easingFunction} */ - easingElasticIn: (t0) => { - let s; - let k1 = 0.1; - const k2 = 0.4; - let t = t0; - if (t === 0) return 0; - if (t === 1) return 1; - if (!k1 || k1 < 1) { - k1 = 1; s = k2 / 4; - } else { - s = ((k2 * Math.asin(1 / k1)) / Math.PI) * 2; - } - t -= 1; - return -(k1 * (2 ** (10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2)); - }, - /** @type {KUTE.easingFunction} */ - easingElasticOut: (t) => { - let s; - let k1 = 0.1; - const k2 = 0.4; - if (t === 0) return 0; - if (t === 1) return 1; - if (!k1 || k1 < 1) { - k1 = 1; - s = k2 / 4; - } else { - s = ((k2 * Math.asin(1 / k1)) / Math.PI) * 2; - } - return k1 * (2 ** (-10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2) + 1; - }, - /** @type {KUTE.easingFunction} */ - easingElasticInOut: (t0) => { - let t = t0; - let s; - let k1 = 0.1; - const k2 = 0.4; - if (t === 0) return 0; - if (t === 1) return 1; - if (!k1 || k1 < 1) { - k1 = 1; s = k2 / 4; - } else { - s = k2 * (Math.asin(1 / k1) / Math.PI) * 2; - } - t *= 2; - if (t < 1) { - return -0.5 * (k1 * (2 ** (10 * (t - 1))) - * Math.sin(((t - 1 - s) * Math.PI * 2) / k2)); - } - t -= 1; - return k1 * (2 ** (-10 * t)) * Math.sin(((t - s) * Math.PI * 2) / k2) * 0.5 + 1; - }, - /** @type {KUTE.easingFunction} */ - easingBounceIn: (t) => 1 - Easing.easingBounceOut(1 - t), - /** @type {KUTE.easingFunction} */ - easingBounceOut: (t0) => { - let t = t0; - if (t < (1 / 2.75)) { return 7.5625 * t * t; } - if (t < (2 / 2.75)) { t -= (1.5 / 2.75); return 7.5625 * t * t + 0.75; } - if (t < (2.5 / 2.75)) { t -= (2.25 / 2.75); return 7.5625 * t * t + 0.9375; } - t -= (2.625 / 2.75); - return 7.5625 * t * t + 0.984375; - }, - /** @type {KUTE.easingFunction} */ - easingBounceInOut: (t) => { - if (t < 0.5) return Easing.easingBounceIn(t * 2) * 0.5; - return Easing.easingBounceOut(t * 2 - 1) * 0.5 + 0.5; - }, -}; - -/** - * Returns a valid `easingFunction`. - * - * @param {KUTE.easingFunction | string} fn function name or constructor - * @returns {KUTE.easingFunction} a valid easing function - */ -function processEasing(fn) { - if (typeof fn === 'function') { - return fn; - } if (typeof Easing[fn] === 'function') { - return Easing[fn]; // regular Robert Penner Easing Functions - } - return Easing.linear; -} - -// Tween constructor needs to know who will process easing functions -connect.processEasing = processEasing; - -export default Easing; diff --git a/src/index-base.js b/src/index-base.js deleted file mode 100644 index dde2f09..0000000 --- a/src/index-base.js +++ /dev/null @@ -1,36 +0,0 @@ -import Render from './core/render'; -import Interpolate from './objects/interpolate'; -import Objects from './objects/objectsBase'; -import Util from './objects/util'; -import Easing from './easing/easing-base'; -import Internals from './core/internals'; -import Selector from './util/selector'; - -// Animation -import Animation from './animation/animationBase'; -// Base Components -import Components from './objects/componentsBase'; - -// TweenConstructor -import Tween from './tween/tweenBase'; -// Interface only fromTo -import fromTo from './interface/fromTo'; - -import Version from './util/version'; - -export default { - Animation, - Components, - - Tween, - fromTo, - - Objects, - Easing, - Util, - Render, - Interpolate, - Internals, - Selector, - Version, -}; diff --git a/src/index-extra.js b/src/index-extra.js deleted file mode 100644 index dd6759c..0000000 --- a/src/index-extra.js +++ /dev/null @@ -1,54 +0,0 @@ -import CubicBezier from 'cubic-bezier-easing'; -import Render from './core/render'; -import Interpolate from './objects/interpolate'; -import Objects from './objects/objects'; -import Util from './objects/util'; -import Internals from './core/internals'; -import Process from './process/process'; -import Easing from './easing/easing-bezier'; -import Selector from './util/selector'; - -// TweenConstructor -import Tween from './tween/tweenExtra'; -import TweenCollection from './tween/tweenCollection'; -import ProgressBar from './util/progressBar'; -// interface -import to from './interface/to'; -import fromTo from './interface/fromTo'; -import allTo from './interface/allTo'; -import allFromTo from './interface/allFromTo'; - -// Animation -import Animation from './animation/animationDevelopment'; - -// Components Extra -import Components from './objects/componentsExtra'; - -import Version from './util/version'; - -export default { - Animation, - Components, - - // Tween Interface - Tween, - fromTo, - to, - // Tween Collection - TweenCollection, - ProgressBar, - allFromTo, - allTo, - // Tween Interface - - Objects, - Util, - Easing, - CubicBezier, - Render, - Interpolate, - Process, - Internals, - Selector, - Version, -}; diff --git a/src/index-legacy.js b/src/index-legacy.js deleted file mode 100644 index b472c71..0000000 --- a/src/index-legacy.js +++ /dev/null @@ -1,72 +0,0 @@ -import Render from './core/render'; -import Interpolate from './objects/interpolate'; -import Objects from './objects/objects'; -import Util from './objects/util'; -import Internals from './core/internals'; -import Process from './process/process'; -import Easing from './easing/easing'; -import Selector from './util/selector'; - -// TweenConstructor -import Tween from './tween/tween'; -import TweenCollection from './tween/tweenCollection'; -// interface -import to from './interface/to'; -import fromTo from './interface/fromTo'; -import allTo from './interface/allTo'; -import allFromTo from './interface/allFromTo'; -import Animation from './animation/animation'; - -// components -import BoxModel from './components/boxModelEssential'; -import ColorProperties from './components/colorProperties'; -import HTMLAttributes from './components/htmlAttributes'; -import OpacityProperty from './components/opacityProperty'; -import TextWriteProp from './components/textWrite'; -import TransformLegacy from './components/transformLegacy'; -import SVGDraw from './components/svgDraw'; -import SVGMorph from './components/svgMorph'; - -import Version from './util/version'; - -const Components = { - BoxModel, - ColorProperties, - HTMLAttributes, - OpacityProperty, - TextWriteProp, - 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, -}; diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 8cffa97..0000000 --- a/src/index.js +++ /dev/null @@ -1,55 +0,0 @@ -// KUTE.js standard distribution version -import CubicBezier from 'cubic-bezier-easing'; -import Render from './core/render'; -import Interpolate from './objects/interpolate'; -import Objects from './objects/objects'; -import Util from './objects/util'; -import Internals from './core/internals'; -import Process from './process/process'; -import Easing from './easing/easing-bezier'; -import Selector from './util/selector'; - -// TweenConstructor -import Tween from './tween/tween'; -import TweenCollection from './tween/tweenCollection'; -// interface -import to from './interface/to'; -import fromTo from './interface/fromTo'; -import allTo from './interface/allTo'; -import allFromTo from './interface/allFromTo'; - -// Animation -import Animation from './animation/animation'; - -// Default Components -import Components from './objects/componentsDefault'; - -import Version from './util/version'; - -const KUTE = { - Animation, - Components, - - // Tween Interface - Tween, - fromTo, - to, - // Tween Collection - TweenCollection, - allFromTo, - allTo, - // Tween Interface - - Objects, - Util, - Easing, - CubicBezier, - Render, - Interpolate, - Process, - Internals, - Selector, - Version, -}; - -export default KUTE; diff --git a/src/interface/allFromTo.js b/src/interface/allFromTo.js deleted file mode 100644 index b40ea35..0000000 --- a/src/interface/allFromTo.js +++ /dev/null @@ -1,18 +0,0 @@ -import selector from '../util/selector'; -import TweenCollection from '../tween/tweenCollection'; - -/** - * The `KUTE.allFromTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at a given state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {TweenCollection} the Tween object collection - */ -export default function allFromTo(elements, startObject, endObject, optionsObj) { - const options = optionsObj || {}; - return new TweenCollection(selector(elements, true), startObject, endObject, options); -} diff --git a/src/interface/allTo.js b/src/interface/allTo.js deleted file mode 100644 index 6b450f7..0000000 --- a/src/interface/allTo.js +++ /dev/null @@ -1,18 +0,0 @@ -import selector from '../util/selector'; -import TweenCollection from '../tween/tweenCollection'; - -/** - * The `KUTE.allTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at their current state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenProps} optionsObj progress - * @returns {TweenCollection} the Tween object collection - */ -export default function allTo(elements, endObject, optionsObj) { - const options = optionsObj || {}; - options.resetStart = endObject; - return new TweenCollection(selector(elements, true), endObject, endObject, options); -} diff --git a/src/interface/fromTo.js b/src/interface/fromTo.js deleted file mode 100644 index 56cb09c..0000000 --- a/src/interface/fromTo.js +++ /dev/null @@ -1,19 +0,0 @@ -import selector from '../util/selector'; -import connect from '../objects/connect'; - -const { tween: TweenConstructor } = connect; - -/** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ -export default function fromTo(element, startObject, endObject, optionsObj) { - const options = optionsObj || {}; - return new TweenConstructor(selector(element), startObject, endObject, options); -} diff --git a/src/interface/to.js b/src/interface/to.js deleted file mode 100644 index d2cf5ab..0000000 --- a/src/interface/to.js +++ /dev/null @@ -1,19 +0,0 @@ -import selector from '../util/selector'; -import connect from '../objects/connect'; - -const { tween: TweenConstructor } = connect; - -/** - * The `KUTE.to()` static method returns a new Tween object - * for a single `HTMLElement` at its current state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ -export default function to(element, endObject, optionsObj) { - const options = optionsObj || {}; - options.resetStart = endObject; - return new TweenConstructor(selector(element), endObject, endObject, options); -} diff --git a/src/interpolation/arrays.js b/src/interpolation/arrays.js deleted file mode 100644 index a959b0a..0000000 --- a/src/interpolation/arrays.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Array Interpolation Function. - * - * @param {number[]} a start array - * @param {number[]} b end array - * @param {number} v progress - * @returns {number[]} the resulting array - */ -export default function arrays(a, b, v) { - const result = []; const { length } = b; - for (let i = 0; i < length; i += 1) { - // eslint-disable-next-line no-bitwise - result[i] = ((a[i] + (b[i] - a[i]) * v) * 1000 >> 0) / 1000; - } - return result; -} diff --git a/src/interpolation/colors.js b/src/interpolation/colors.js deleted file mode 100644 index b9359aa..0000000 --- a/src/interpolation/colors.js +++ /dev/null @@ -1,28 +0,0 @@ -import numbers from './numbers'; -/** - * Color Interpolation Function. - * - * @param {KUTE.colorObject} a start color - * @param {KUTE.colorObject} b end color - * @param {number} v progress - * @returns {string} the resulting color - */ -export default function colors(a, b, v) { - const _c = {}; - const ep = ')'; - const cm = ','; - const rgb = 'rgb('; - const rgba = 'rgba('; - - Object.keys(b).forEach((c) => { - if (c !== 'a') { - _c[c] = numbers(a[c], b[c], v) >> 0 || 0; // eslint-disable-line no-bitwise - } else if (a[c] && b[c]) { - _c[c] = (numbers(a[c], b[c], v) * 100 >> 0) / 100; // eslint-disable-line no-bitwise - } - }); - - 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; -} diff --git a/src/interpolation/coords.js b/src/interpolation/coords.js deleted file mode 100644 index 35d3298..0000000 --- a/src/interpolation/coords.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Coordinates Interpolation Function. - * - * @param {number[][]} a start coordinates - * @param {number[][]} b end coordinates - * @param {string} l amount of coordinates - * @param {number} v progress - * @returns {number[][]} the interpolated coordinates - */ -export default function coords(a, b, l, v) { - const points = []; - for (let i = 0; i < l; i += 1) { // for each point - points[i] = []; - for (let j = 0; j < 2; j += 1) { // each point coordinate - // eslint-disable-next-line no-bitwise - points[i].push(((a[i][j] + (b[i][j] - a[i][j]) * v) * 1000 >> 0) / 1000); - } - } - return points; -} diff --git a/src/interpolation/numbers.js b/src/interpolation/numbers.js deleted file mode 100644 index 175fdda..0000000 --- a/src/interpolation/numbers.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ -export default function numbers(a, b, v) { - const A = +a; - const B = b - a; - // a = +a; b -= a; - return A + B * v; -} diff --git a/src/interpolation/perspective.js b/src/interpolation/perspective.js deleted file mode 100644 index cb108b9..0000000 --- a/src/interpolation/perspective.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Perspective Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the perspective function in string format - */ -export default function perspective(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `perspective(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} diff --git a/src/interpolation/rotate.js b/src/interpolation/rotate.js deleted file mode 100644 index d0fca7c..0000000 --- a/src/interpolation/rotate.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 2D Rotation Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated rotation - */ -export default function rotate(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `rotate(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} diff --git a/src/interpolation/rotate3d.js b/src/interpolation/rotate3d.js deleted file mode 100644 index c69907f..0000000 --- a/src/interpolation/rotate3d.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * 3D Rotation Interpolation Function. - * - * @param {number} a start [x,y,z] angles - * @param {number} b end [x,y,z] angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D rotation string - */ -export default function rotate3d(a, b, u, v) { - let rotateStr = ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[0] || b[0] ? `rotateX(${((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000}${u})` : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[1] || b[1] ? `rotateY(${((a[1] + (b[1] - a[1]) * v) * 1000 >> 0) / 1000}${u})` : ''; - // eslint-disable-next-line no-bitwise - rotateStr += a[2] || b[2] ? `rotateZ(${((a[2] + (b[2] - a[2]) * v) * 1000 >> 0) / 1000}${u})` : ''; - return rotateStr; -} diff --git a/src/interpolation/scale.js b/src/interpolation/scale.js deleted file mode 100644 index e4da74a..0000000 --- a/src/interpolation/scale.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Scale Interpolation Function. - * - * @param {number} a start scale - * @param {number} b end scale - * @param {number} v progress - * @returns {string} the interpolated scale - */ -export default function scale(a, b, v) { - // eslint-disable-next-line no-bitwise - return `scale(${((a + (b - a) * v) * 1000 >> 0) / 1000})`; -} diff --git a/src/interpolation/skew.js b/src/interpolation/skew.js deleted file mode 100644 index 46bbe56..0000000 --- a/src/interpolation/skew.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Skew Interpolation Function. - * - * @param {number} a start {x,y} angles - * @param {number} b end {x,y} angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated string value of skew(s) - */ -export default function skew(a, b, u, v) { - const skewArray = []; - // eslint-disable-next-line no-bitwise - skewArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')})`; -} diff --git a/src/interpolation/skewX.js b/src/interpolation/skewX.js deleted file mode 100644 index 172334d..0000000 --- a/src/interpolation/skewX.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * SkewX Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated skewX - */ -export default function skewX(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `skewX(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} diff --git a/src/interpolation/skewY.js b/src/interpolation/skewY.js deleted file mode 100644 index e7f3fc5..0000000 --- a/src/interpolation/skewY.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * SkewY Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated skewY - */ -export default function skewY(a, b, u, v) { - // eslint-disable-next-line no-bitwise - return `skewY(${((a + (b - a) * v) * 1000 >> 0) / 1000}${u})`; -} diff --git a/src/interpolation/translate.js b/src/interpolation/translate.js deleted file mode 100644 index dacc327..0000000 --- a/src/interpolation/translate.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Translate 2D Interpolation Function. - * - * @param {number[]} a start [x,y] position - * @param {number[]} b end [x,y] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 2D translation string - */ -export default function translate(a, b, u, v) { - const translateArray = []; - // eslint-disable-next-line no-bitwise - translateArray[0] = (a[0] === b[0] ? b[0] : ((a[0] + (b[0] - a[0]) * v) * 1000 >> 0) / 1000) + u; - // eslint-disable-next-line no-bitwise - 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(',')})`; -} diff --git a/src/interpolation/translate3d.js b/src/interpolation/translate3d.js deleted file mode 100644 index c71ffff..0000000 --- a/src/interpolation/translate3d.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Translate 3D Interpolation Function. - * - * @param {number[]} a start [x,y,z] position - * @param {number[]} b end [x,y,z] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D translation string - */ -export default function translate3d(a, b, u, v) { - const translateArray = []; - for (let ax = 0; ax < 3; ax += 1) { - translateArray[ax] = (a[ax] || b[ax] - // eslint-disable-next-line no-bitwise - ? ((a[ax] + (b[ax] - a[ax]) * v) * 1000 >> 0) / 1000 : 0) + u; - } - return `translate3d(${translateArray.join(',')})`; -} diff --git a/src/interpolation/units.js b/src/interpolation/units.js deleted file mode 100644 index 8e37df5..0000000 --- a/src/interpolation/units.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Units Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the interpolated value + unit string - */ -export default function units(a, b, u, v) { // number1, number2, unit, progress - const A = +a; - const B = b - a; - // a = +a; b -= a; - return (A + B * v) + u; -} diff --git a/src/objects/componentsBase.js b/src/objects/componentsBase.js deleted file mode 100644 index a4b2175..0000000 --- a/src/objects/componentsBase.js +++ /dev/null @@ -1,16 +0,0 @@ -import Animation from '../animation/animationBase'; - -// kute-base supported components -import baseTransform from '../components/transformFunctionsBase'; -import baseBoxModel from '../components/boxModelBase'; -import baseOpacity from '../components/opacityPropertyBase'; -// import {baseCrossBrowserMove} from '../components/crossBrowserMove' -// support for kute-base ends here - -const Components = { - Transform: new Animation(baseTransform), - BoxModel: new Animation(baseBoxModel), - Opacity: new Animation(baseOpacity), -}; - -export default Components; diff --git a/src/objects/componentsDefault.js b/src/objects/componentsDefault.js deleted file mode 100644 index 32ef35b..0000000 --- a/src/objects/componentsDefault.js +++ /dev/null @@ -1,29 +0,0 @@ -import Animation from '../animation/animation'; - -import EssentialBoxModel from '../components/boxModelEssential'; -import ColorsProperties from '../components/colorProperties'; -import HTMLAttributes from '../components/htmlAttributes'; -import OpacityProperty from '../components/opacityProperty'; -import TextWriteProp from '../components/textWrite'; -import TransformFunctions from '../components/transformFunctions'; -import SVGDraw from '../components/svgDraw'; -import SVGMorph from '../components/svgMorph'; - -const Components = { - EssentialBoxModel, - ColorsProperties, - HTMLAttributes, - OpacityProperty, - TextWriteProp, - TransformFunctions, - SVGDraw, - SVGMorph, -}; - -// init components -Object.keys(Components).forEach((component) => { - const compOps = Components[component]; - Components[component] = new Animation(compOps); -}); - -export default Components; diff --git a/src/objects/componentsExtra.js b/src/objects/componentsExtra.js deleted file mode 100644 index 6345540..0000000 --- a/src/objects/componentsExtra.js +++ /dev/null @@ -1,45 +0,0 @@ -import Animation from '../animation/animationDevelopment'; - -import BackgroundPosition from '../components/backgroundPosition'; -import BorderRadius from '../components/borderRadius'; -import BoxModel from '../components/boxModel'; -import ClipProperty from '../components/clipProperty'; -import ColorProperties from '../components/colorProperties'; -import FilterEffects from '../components/filterEffects'; -import HTMLAttributes from '../components/htmlAttributes'; -import OpacityProperty from '../components/opacityProperty'; -import SVGDraw from '../components/svgDraw'; -import SVGCubicMorph from '../components/svgCubicMorph'; -import SVGTransform from '../components/svgTransform'; -import ScrollProperty from '../components/scrollProperty'; -import ShadowProperties from '../components/shadowProperties'; -import TextProperties from '../components/textProperties'; -import TextWriteProperties from '../components/textWrite'; -import MatrixTransform from '../components/transformMatrix'; - -const Components = { - BackgroundPosition, - BorderRadius, - BoxModel, - ClipProperty, - ColorProperties, - FilterEffects, - HTMLAttributes, - OpacityProperty, - SVGDraw, - SVGCubicMorph, - SVGTransform, - ScrollProperty, - ShadowProperties, - TextProperties, - TextWriteProperties, - MatrixTransform, -}; - -// init components -Object.keys(Components).forEach((component) => { - const compOps = Components[component]; - Components[component] = new Animation(compOps); -}); - -export default Components; diff --git a/src/objects/connect.js b/src/objects/connect.js deleted file mode 100644 index 2d5f778..0000000 --- a/src/objects/connect.js +++ /dev/null @@ -1,6 +0,0 @@ -const connect = {}; -/** @type {KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra} */ -connect.tween = null; -connect.processEasing = null; - -export default connect; diff --git a/src/objects/crossCheck.js b/src/objects/crossCheck.js deleted file mode 100644 index e58a764..0000000 --- a/src/objects/crossCheck.js +++ /dev/null @@ -1,6 +0,0 @@ -// checks for differences between the processed start and end values, -// can be set to make sure start unit and end unit are same, -// stack transforms, process SVG paths, -// any type of post processing the component needs -const crossCheck = {}; -export default crossCheck; diff --git a/src/objects/defaultOptions.js b/src/objects/defaultOptions.js deleted file mode 100644 index bfb341f..0000000 --- a/src/objects/defaultOptions.js +++ /dev/null @@ -1,14 +0,0 @@ -const defaultOptions = { - duration: 700, - delay: 0, - easing: 'linear', - repeat: 0, - repeatDelay: 0, - yoyo: false, - resetStart: false, - offset: 0, -}; -// no need to set defaults for callbacks -// defaultOptions.onPause = undefined -// defaultOptions.onResume = undefined -export default defaultOptions; diff --git a/src/objects/defaultValues.js b/src/objects/defaultValues.js deleted file mode 100644 index aec2050..0000000 --- a/src/objects/defaultValues.js +++ /dev/null @@ -1,2 +0,0 @@ -const defaultValues = {}; -export default defaultValues; diff --git a/src/objects/globalObject.js b/src/objects/globalObject.js deleted file mode 100644 index 8961257..0000000 --- a/src/objects/globalObject.js +++ /dev/null @@ -1,8 +0,0 @@ -let gl0bal; - -if (typeof global !== 'undefined') gl0bal = global; -else if (typeof window !== 'undefined') gl0bal = window.self; -else gl0bal = {}; - -const globalObject = gl0bal; -export default globalObject; diff --git a/src/objects/interpolate.js b/src/objects/interpolate.js deleted file mode 100644 index 0f0a5e5..0000000 --- a/src/objects/interpolate.js +++ /dev/null @@ -1,4 +0,0 @@ -// KUTE.js INTERPOLATE FUNCTIONS -// ============================= -const interpolate = {}; -export default interpolate; diff --git a/src/objects/kute.js b/src/objects/kute.js deleted file mode 100644 index 7ed1d44..0000000 --- a/src/objects/kute.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * The KUTE.js Execution Context - */ -const KEC = {}; -export default KEC; diff --git a/src/objects/linkProperty.js b/src/objects/linkProperty.js deleted file mode 100644 index e3586e1..0000000 --- a/src/objects/linkProperty.js +++ /dev/null @@ -1,3 +0,0 @@ -// link properties to interpolate functions -const linkProperty = {}; -export default linkProperty; diff --git a/src/objects/objects.js b/src/objects/objects.js deleted file mode 100644 index 88fef2a..0000000 --- a/src/objects/objects.js +++ /dev/null @@ -1,23 +0,0 @@ -import supportedProperties from './supportedProperties'; -import defaultValues from './defaultValues'; -import defaultOptions from './defaultOptions'; -import prepareProperty from './prepareProperty'; -import prepareStart from './prepareStart'; -import crossCheck from './crossCheck'; -import onStart from './onStart'; -import onComplete from './onComplete'; -import linkProperty from './linkProperty'; - -const Objects = { - supportedProperties, - defaultValues, - defaultOptions, - prepareProperty, - prepareStart, - crossCheck, - onStart, - onComplete, - linkProperty, -}; - -export default Objects; diff --git a/src/objects/objectsBase.js b/src/objects/objectsBase.js deleted file mode 100644 index b504275..0000000 --- a/src/objects/objectsBase.js +++ /dev/null @@ -1,13 +0,0 @@ -import defaultOptions from './defaultOptions'; -import linkProperty from './linkProperty'; -import onStart from './onStart'; -import onComplete from './onComplete'; - -const Objects = { - defaultOptions, - linkProperty, - onStart, - onComplete, -}; - -export default Objects; diff --git a/src/objects/onComplete.js b/src/objects/onComplete.js deleted file mode 100644 index dbead27..0000000 --- a/src/objects/onComplete.js +++ /dev/null @@ -1,3 +0,0 @@ -// schedule property specific function on animation complete -const onComplete = {}; -export default onComplete; diff --git a/src/objects/onStart.js b/src/objects/onStart.js deleted file mode 100644 index b6a4ef7..0000000 --- a/src/objects/onStart.js +++ /dev/null @@ -1,4 +0,0 @@ -// schedule property specific function on animation start -// link property update function to KUTE.js execution context -const onStart = {}; -export default onStart; diff --git a/src/objects/prepareProperty.js b/src/objects/prepareProperty.js deleted file mode 100644 index 8e86ee1..0000000 --- a/src/objects/prepareProperty.js +++ /dev/null @@ -1,3 +0,0 @@ -// used in preparePropertiesObject -const prepareProperty = {}; -export default prepareProperty; diff --git a/src/objects/prepareStart.js b/src/objects/prepareStart.js deleted file mode 100644 index a946308..0000000 --- a/src/objects/prepareStart.js +++ /dev/null @@ -1,3 +0,0 @@ -// check current property value when .to() method is used -const prepareStart = {}; -export default prepareStart; diff --git a/src/objects/supportedProperties.js b/src/objects/supportedProperties.js deleted file mode 100644 index b3d41c3..0000000 --- a/src/objects/supportedProperties.js +++ /dev/null @@ -1,3 +0,0 @@ -// all supported properties -const supportedProperties = {}; -export default supportedProperties; diff --git a/src/objects/tweens.js b/src/objects/tweens.js deleted file mode 100644 index 5a2f8ff..0000000 --- a/src/objects/tweens.js +++ /dev/null @@ -1,2 +0,0 @@ -const Tweens = []; -export default Tweens; diff --git a/src/objects/util.js b/src/objects/util.js deleted file mode 100644 index bffef7f..0000000 --- a/src/objects/util.js +++ /dev/null @@ -1,3 +0,0 @@ -// util - a general object for utils like rgbToHex, processEasing -const Util = {}; -export default Util; diff --git a/src/process/getInlineStyle.js b/src/process/getInlineStyle.js deleted file mode 100644 index 8079267..0000000 --- a/src/process/getInlineStyle.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * getInlineStyle - * Returns the transform style for element from - * cssText. Used by for the `.to()` static method. - * - * @param {Element} el target element - * @returns {object} - */ -export default function getInlineStyle(el) { - // if the scroll applies to `window` it returns as it has no styling - if (!el.style) return false; - // the cssText | the resulting transform object - const css = el.style.cssText.replace(/\s/g, '').split(';'); - const transformObject = {}; - const arrayFn = ['translate3d', 'translate', 'scale3d', 'skew']; - - css.forEach((cs) => { - if (/transform/i.test(cs)) { - // all transform properties - const tps = cs.split(':')[1].split(')'); - tps.forEach((tpi) => { - const tpv = tpi.split('('); - const tp = tpv[0]; - // each transform property - const tv = tpv[1]; - if (!/matrix/.test(tp)) { - transformObject[tp] = arrayFn.includes(tp) ? tv.split(',') : tv; - } - }); - } - }); - - return transformObject; -} diff --git a/src/process/getInlineStyleLegacy.js b/src/process/getInlineStyleLegacy.js deleted file mode 100644 index 83e176b..0000000 --- a/src/process/getInlineStyleLegacy.js +++ /dev/null @@ -1,33 +0,0 @@ -import transformProperty from '../util/transformProperty'; - -/** - * getInlineStyle - * - * Returns the transform style for element from cssText. - * Used by for the `.to()` static method on legacy browsers. - * - * @param {Element} el target element - * @returns {object} a transform object - */ -export default function getInlineStyleLegacy(el) { - if (!el.style) return false; // if the scroll applies to `window` it returns as it has no styling - const css = el.style.cssText.replace(/\s/g, '').split(';'); // the cssText | the resulting transform object - const transformObject = {}; - const arrayFn = ['translate3d', 'translate', 'scale3d', 'skew']; - - css.forEach((cs) => { - const csi = cs.split(':'); - if (csi[0] === transformProperty) { - const tps = csi[1].split(')'); // all transform properties - tps.forEach((tpi) => { - const tpv = tpi.split('('); const tp = tpv[0]; const - tv = tpv[1]; // each transform property - if (!/matrix/.test(tp)) { - transformObject[tp] = arrayFn.includes(tp) ? tv.split(',') : tv; - } - }); - } - }); - - return transformObject; -} diff --git a/src/process/getStartValues.js b/src/process/getStartValues.js deleted file mode 100644 index 230dcd6..0000000 --- a/src/process/getStartValues.js +++ /dev/null @@ -1,48 +0,0 @@ -import getInlineStyle from './getInlineStyle'; -import prepareObject from './prepareObject'; -import defaultValues from '../objects/defaultValues'; -import prepareStart from '../objects/prepareStart'; -import supportedProperties from '../objects/supportedProperties'; - -/** - * getStartValues - * - * Returns the start values for to() method. - * Used by for the `.to()` static method. - * - * @this {KUTE.Tween} the tween instance - */ -export default function getStartValues() { - const startValues = {}; - const currentStyle = getInlineStyle(this.element); - - Object.keys(this.valuesStart).forEach((tweenProp) => { - Object.keys(prepareStart).forEach((component) => { - const componentStart = prepareStart[component]; - - Object.keys(componentStart).forEach((tweenCategory) => { - // clip, opacity, scroll - if (tweenCategory === tweenProp && componentStart[tweenProp]) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this, tweenProp, this.valuesStart[tweenProp]); - // find in an array of properties - } else if (supportedProperties[component] - && supportedProperties[component].includes(tweenProp)) { - startValues[tweenProp] = componentStart[tweenCategory] - .call(this, tweenProp, this.valuesStart[tweenProp]); - } - }); - }); - }); - - // stack transformCSS props for .to() chains - // also add to startValues values from previous tweens - Object.keys(currentStyle).forEach((current) => { - if (!(current in this.valuesStart)) { - startValues[current] = currentStyle[current] || defaultValues[current]; - } - }); - - this.valuesStart = {}; - prepareObject.call(this, startValues, 'start'); -} diff --git a/src/process/getStyleForProperty.js b/src/process/getStyleForProperty.js deleted file mode 100644 index b8e8b74..0000000 --- a/src/process/getStyleForProperty.js +++ /dev/null @@ -1,26 +0,0 @@ -import defaultValues from '../objects/defaultValues'; - -/** - * getStyleForProperty - * - * Returns the computed style property for element for .to() method. - * Used by for the `.to()` static method. - * - * @param {Element} elem - * @param {string} propertyName - * @returns {string} - */ -export default function getStyleForProperty(elem, propertyName) { - let result = defaultValues[propertyName]; - const styleAttribute = elem.style; - const computedStyle = getComputedStyle(elem) || elem.currentStyle; - const styleValue = styleAttribute[propertyName] && !/auto|initial|none|unset/.test(styleAttribute[propertyName]) - ? styleAttribute[propertyName] - : computedStyle[propertyName]; - - if (propertyName !== 'transform' && (propertyName in computedStyle || propertyName in styleAttribute)) { - result = styleValue; - } - - return result; -} diff --git a/src/process/prepareObject.js b/src/process/prepareObject.js deleted file mode 100644 index ead2490..0000000 --- a/src/process/prepareObject.js +++ /dev/null @@ -1,53 +0,0 @@ -import prepareProperty from '../objects/prepareProperty'; -import supportedProperties from '../objects/supportedProperties'; -import defaultValues from '../objects/defaultValues'; - -/** - * prepareObject - * - * Returns all processed valuesStart / valuesEnd. - * - * @param {Element} obj the values start/end object - * @param {string} fn toggles between the two - */ -export default function prepareObject(obj, fn) { // this, props object, type: start/end - const propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd; - - Object.keys(prepareProperty).forEach((component) => { - const prepareComponent = prepareProperty[component]; - const supportComponent = supportedProperties[component]; - - Object.keys(prepareComponent).forEach((tweenCategory) => { - const transformObject = {}; - - Object.keys(obj).forEach((tweenProp) => { - // scroll, opacity, other components - if (defaultValues[tweenProp] && prepareComponent[tweenProp]) { - propertiesObject[tweenProp] = prepareComponent[tweenProp] - .call(this, tweenProp, obj[tweenProp]); - - // transform - } else if (!defaultValues[tweenCategory] && tweenCategory === 'transform' - && supportComponent.includes(tweenProp)) { - transformObject[tweenProp] = obj[tweenProp]; - - // allow transformFunctions to work with preprocessed input values - } else if (!defaultValues[tweenProp] && tweenProp === 'transform') { - propertiesObject[tweenProp] = obj[tweenProp]; - - // colors, boxModel, category - } else if (!defaultValues[tweenCategory] - && supportComponent && supportComponent.includes(tweenProp)) { - propertiesObject[tweenProp] = prepareComponent[tweenCategory] - .call(this, tweenProp, obj[tweenProp]); - } - }); - - // we filter out older browsers by checking Object.keys - if (Object.keys(transformObject).length) { - propertiesObject[tweenCategory] = prepareComponent[tweenCategory] - .call(this, tweenCategory, transformObject); - } - }); - }); -} diff --git a/src/process/process.js b/src/process/process.js deleted file mode 100644 index d92656d..0000000 --- a/src/process/process.js +++ /dev/null @@ -1,11 +0,0 @@ -import getInlineStyle from './getInlineStyle'; -import getStyleForProperty from './getStyleForProperty'; -import getStartValues from './getStartValues'; -import prepareObject from './prepareObject'; - -export default { - getInlineStyle, - getStyleForProperty, - getStartValues, - prepareObject, -}; diff --git a/src/tween/tween.js b/src/tween/tween.js deleted file mode 100644 index 7ca6c34..0000000 --- a/src/tween/tween.js +++ /dev/null @@ -1,271 +0,0 @@ -import KEC from '../objects/kute'; -import TweenBase from './tweenBase'; -import connect from '../objects/connect'; -import add from '../core/add'; -import remove from '../core/remove'; -import defaultOptions from '../objects/defaultOptions'; -import crossCheck from '../objects/crossCheck'; -import prepareObject from '../process/prepareObject'; -import getStartValues from '../process/getStartValues'; -import { Tick, Ticker } from '../core/render'; -import queueStart from '../core/queueStart'; - -/** - * The `KUTE.Tween()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor adds additional functionality and is the default - * Tween object constructor in KUTE.js. - */ -export default class Tween extends TweenBase { - /** - * @param {KUTE.tweenParams} args (*target*, *startValues*, *endValues*, *options*) - * @returns {Tween} the resulting Tween object - */ - constructor(...args) { - super(...args); // this calls the constructor of TweenBase - - // reset interpolation values - this.valuesStart = {}; - this.valuesEnd = {}; - - // const startObject = args[1]; - // const endObject = args[2]; - const [startObject, endObject, options] = args.slice(1); - - // set valuesEnd - prepareObject.call(this, endObject, 'end'); - - // set valuesStart - if (this._resetStart) { - this.valuesStart = startObject; - } else { - prepareObject.call(this, startObject, 'start'); - } - - // ready for crossCheck - if (!this._resetStart) { - Object.keys(crossCheck).forEach((component) => { - Object.keys(crossCheck[component]).forEach((checkProp) => { - crossCheck[component][checkProp].call(this, checkProp); - }); - }); - } - - // set paused state - /** @type {boolean} */ - this.paused = false; - /** @type {number?} */ - this._pauseTime = null; - - // additional properties and options - /** @type {number?} */ - this._repeat = options.repeat || defaultOptions.repeat; - /** @type {number?} */ - this._repeatDelay = options.repeatDelay || defaultOptions.repeatDelay; - // we cache the number of repeats to be able to put it back after all cycles finish - /** @type {number?} */ - this._repeatOption = this._repeat; - - // yoyo needs at least repeat: 1 - /** @type {KUTE.tweenProps} */ - this.valuesRepeat = {}; // valuesRepeat - /** @type {boolean} */ - this._yoyo = options.yoyo || defaultOptions.yoyo; - /** @type {boolean} */ - this._reversed = false; - - // don't load extra callbacks - // this._onPause = options.onPause || defaultOptions.onPause - // this._onResume = options.onResume || defaultOptions.onResume - - // chained Tweens - // this._chain = options.chain || defaultOptions.chain; - return this; - } - - /** - * Starts tweening, extended method - * @param {number?} time the tween start time - * @returns {Tween} this instance - */ - start(time) { - // on start we reprocess the valuesStart for TO() method - if (this._resetStart) { - this.valuesStart = this._resetStart; - getStartValues.call(this); - - // this is where we do the valuesStart and valuesEnd check for fromTo() method - Object.keys(crossCheck).forEach((component) => { - Object.keys(crossCheck[component]).forEach((checkProp) => { - crossCheck[component][checkProp].call(this, checkProp); - }); - }); - } - // still not paused - this.paused = false; - - // set yoyo values - if (this._yoyo) { - Object.keys(this.valuesEnd).forEach((endProp) => { - this.valuesRepeat[endProp] = this.valuesStart[endProp]; - }); - } - - super.start(time); - - return this; - } - - /** - * Stops tweening, extended method - * @returns {Tween} this instance - */ - stop() { - super.stop(); - if (!this.paused && this.playing) { - this.paused = false; - this.stopChainedTweens(); - } - return this; - } - - /** - * Trigger internal completion callbacks. - */ - close() { - super.close(); - - if (this._repeatOption > 0) { - this._repeat = this._repeatOption; - } - if (this._yoyo && this._reversed === true) { - this.reverse(); - this._reversed = false; - } - - return this; - } - - /** - * Resume tweening - * @returns {Tween} this instance - */ - resume() { - if (this.paused && this.playing) { - this.paused = false; - if (this._onResume !== undefined) { - this._onResume.call(this); - } - // re-queue execution context - queueStart.call(this); - // update time and let it roll - this._startTime += KEC.Time() - this._pauseTime; - add(this); - // restart ticker if stopped - if (!Tick) Ticker(); - } - return this; - } - - /** - * Pause tweening - * @returns {Tween} this instance - */ - pause() { - if (!this.paused && this.playing) { - remove(this); - this.paused = true; - this._pauseTime = KEC.Time(); - if (this._onPause !== undefined) { - this._onPause.call(this); - } - } - return this; - } - - /** - * Reverses start values with end values - */ - reverse() { - Object.keys(this.valuesEnd).forEach((reverseProp) => { - const tmp = this.valuesRepeat[reverseProp]; - this.valuesRepeat[reverseProp] = this.valuesEnd[reverseProp]; - this.valuesEnd[reverseProp] = tmp; - this.valuesStart[reverseProp] = this.valuesRepeat[reverseProp]; - }); - } - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - update(time) { - const T = time !== undefined ? time : KEC.Time(); - - let elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - const progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach((tweenProp) => { - KEC[tweenProp](this.element, - this.valuesStart[tweenProp], - this.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - if (this._repeat > 0) { - if (Number.isFinite(this._repeat)) this._repeat -= 1; - - // set the right time for delay - this._startTime = T; - if (Number.isFinite(this._repeat) && this._yoyo && !this._reversed) { - this._startTime += this._repeatDelay; - } - - if (this._yoyo) { // handle yoyo - this._reversed = !this._reversed; - this.reverse(); - } - - return true; - } - - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.forEach((tw) => tw.start()); - } - - return false; - } - return true; - } -} - -// Update Tween Interface Update -connect.tween = Tween; diff --git a/src/tween/tweenBase.js b/src/tween/tweenBase.js deleted file mode 100644 index 8d070e5..0000000 --- a/src/tween/tweenBase.js +++ /dev/null @@ -1,211 +0,0 @@ -import KEC from '../objects/kute'; -import connect from '../objects/connect'; -import onStart from '../objects/onStart'; -import onComplete from '../objects/onComplete'; -import defaultOptions from '../objects/defaultOptions'; - -import { Tick, Ticker, stop } from '../core/render'; - -import add from '../core/add'; -import remove from '../core/remove'; -import queueStart from '../core/queueStart'; - -/** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ -export default class TweenBase { - /** - * @param {Element} targetElement the target element - * @param {KUTE.tweenProps} startObject the start values - * @param {KUTE.tweenProps} endObject the end values - * @param {KUTE.tweenOptions} opsObject the end values - * @returns {TweenBase} the resulting Tween object - */ - constructor(targetElement, startObject, endObject, opsObject) { - // element animation is applied to - this.element = targetElement; - - /** @type {boolean} */ - this.playing = false; - /** @type {number?} */ - this._startTime = null; - /** @type {boolean} */ - this._startFired = false; - - // type is set via KUTE.tweenProps - this.valuesEnd = endObject; - this.valuesStart = startObject; - - // OPTIONS - const options = opsObject || {}; - // internal option to process inline/computed style at start instead of init - // used by to() method and expects object : {} / false - this._resetStart = options.resetStart || 0; - // you can only set a core easing function as default - /** @type {KUTE.easingOption} */ - this._easing = typeof (options.easing) === 'function' ? options.easing : connect.processEasing(options.easing); - /** @type {number} */ - this._duration = options.duration || defaultOptions.duration; // duration option | default - /** @type {number} */ - this._delay = options.delay || defaultOptions.delay; // delay option | default - - // set other options - Object.keys(options).forEach((op) => { - const internalOption = `_${op}`; - if (!(internalOption in this)) this[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 - const easingFnName = this._easing.name; - if (!onStart[easingFnName]) { - onStart[easingFnName] = function easingFn(prop) { - if (!KEC[prop] && prop === this._easing.name) KEC[prop] = this._easing; - }; - } - - return this; - } - - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - start(time) { - // now it's a good time to start - add(this); - this.playing = true; - - this._startTime = typeof time !== 'undefined' ? time : KEC.Time(); - this._startTime += this._delay; - - if (!this._startFired) { - if (this._onStart) { - this._onStart.call(this); - } - - queueStart.call(this); - - this._startFired = true; - } - - if (!Tick) Ticker(); - return this; - } - - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - stop() { - if (this.playing) { - remove(this); - this.playing = false; - - if (this._onStop) { - this._onStop.call(this); - } - this.close(); - } - return this; - } - - /** - * Trigger internal completion callbacks. - */ - close() { - // scroll|transformMatrix need this - Object.keys(onComplete).forEach((component) => { - Object.keys(onComplete[component]).forEach((toClose) => { - onComplete[component][toClose].call(this, toClose); - }); - }); - // when all animations are finished, stop ticking after ~3 frames - this._startFired = false; - stop.call(this); - } - - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - chain(args) { - this._chain = []; - this._chain = args.length ? args : this._chain.concat(args); - return this; - } - - /** - * Stop tweening the chained tween instances. - */ - stopChainedTweens() { - if (this._chain && this._chain.length) this._chain.forEach((tw) => tw.stop()); - } - - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - update(time) { - const T = time !== undefined ? time : KEC.Time(); - - let elapsed; - - if (T < this._startTime && this.playing) { return true; } - - elapsed = (T - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - // calculate progress - const progress = this._easing(elapsed); - - // render the update - Object.keys(this.valuesEnd).forEach((tweenProp) => { - KEC[tweenProp](this.element, - this.valuesStart[tweenProp], - this.valuesEnd[tweenProp], - progress); - }); - - // fire the updateCallback - if (this._onUpdate) { - this._onUpdate.call(this); - } - - if (elapsed === 1) { - // fire the complete callback - if (this._onComplete) { - this._onComplete.call(this); - } - - // now we're sure no animation is running - this.playing = false; - - // stop ticking when finished - this.close(); - - // start animating chained tweens - if (this._chain !== undefined && this._chain.length) { - this._chain.map((tw) => tw.start()); - } - - return false; - } - - return true; - } -} - -// Update Tween Interface -connect.tween = TweenBase; diff --git a/src/tween/tweenCollection.js b/src/tween/tweenCollection.js deleted file mode 100644 index 88f94b3..0000000 --- a/src/tween/tweenCollection.js +++ /dev/null @@ -1,128 +0,0 @@ -import KEC from '../objects/kute'; -import defaultOptions from '../objects/defaultOptions'; -import connect from '../objects/connect'; - -/** - * The static method creates a new `Tween` object for each `HTMLElement` - * from and `Array`, `HTMLCollection` or `NodeList`. - */ -export default class TweenCollection { - /** - * - * @param {Element[] | HTMLCollection | NodeList} els target elements - * @param {KUTE.tweenProps} vS the start values - * @param {KUTE.tweenProps} vE the end values - * @param {KUTE.tweenOptions} Options tween options - * @returns {TweenCollection} the Tween object collection - */ - constructor(els, vS, vE, Options) { - const TweenConstructor = connect.tween; - /** @type {KUTE.twCollection[]} */ - this.tweens = []; - - const Ops = Options || {}; - /** @type {number?} */ - Ops.delay = Ops.delay || defaultOptions.delay; - - // set all options - const options = []; - - Array.from(els).forEach((el, i) => { - options[i] = Ops || {}; - options[i].delay = i > 0 ? Ops.delay + (Ops.offset || defaultOptions.offset) : Ops.delay; - if (el instanceof Element) { - this.tweens.push(new TweenConstructor(el, vS, vE, options[i])); - } else { - throw Error(`KUTE - ${el} is not instanceof Element`); - } - }); - - /** @type {number?} */ - this.length = this.tweens.length; - return this; - } - - /** - * Starts tweening, all targets - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - start(time) { - const T = time === undefined ? KEC.Time() : time; - this.tweens.map((tween) => tween.start(T)); - return this; - } - - /** - * Stops tweening, all targets and their chains - * @returns {TweenCollection} this instance - */ - stop() { - this.tweens.map((tween) => tween.stop()); - return this; - } - - /** - * Pause tweening, all targets - * @returns {TweenCollection} this instance - */ - pause() { - this.tweens.map((tween) => tween.pause()); - return this; - } - - /** - * Resume tweening, all targets - * @returns {TweenCollection} this instance - */ - resume() { - this.tweens.map((tween) => tween.resume()); - return this; - } - - /** - * Schedule another tween or collection to start after - * this one is complete. - * @param {number?} args the tween start time - * @returns {TweenCollection} this instance - */ - chain(args) { - const lastTween = this.tweens[this.length - 1]; - if (args instanceof TweenCollection) { - lastTween.chain(args.tweens); - } else if (args instanceof connect.tween) { - lastTween.chain(args); - } else { - throw new TypeError('KUTE.js - invalid chain value'); - } - return this; - } - - /** - * Check if any tween instance is playing - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - playing() { - return this.tweens.some((tw) => tw.playing); - } - - /** - * Remove all tweens in the collection - */ - removeTweens() { - this.tweens = []; - } - - /** - * Returns the maximum animation duration - * @returns {number} this instance - */ - getMaxDuration() { - const durations = []; - this.tweens.forEach((tw) => { - durations.push(tw._duration + tw._delay + tw._repeat * tw._repeatDelay); - }); - return Math.max(durations); - } -} diff --git a/src/tween/tweenExtra.js b/src/tween/tweenExtra.js deleted file mode 100644 index 7bd71f4..0000000 --- a/src/tween/tweenExtra.js +++ /dev/null @@ -1,73 +0,0 @@ -import connect from '../objects/connect'; -import Tween from './tween'; - -// to do -// * per property easing -// * per property duration -// * per property callback -// * per property delay/offset -// * new update method to work with the above -// * other cool ideas - -/** - * The `KUTE.TweenExtra()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor is intended for experiments or testing of new features. - */ -export default class TweenExtra extends Tween { - /** - * @param {KUTE.tweenParams} args (*target*, *startValues*, *endValues*, *options*) - * @returns {TweenExtra} the resulting Tween object - */ - constructor(...args) { - super(...args); // import constructor of TweenBase -> Tween - - return this; - } - - // additional methods - // set/override property - // to(property, value) { - // TO DO - // this.valuesEnd[property] = value // well that's not all - // } - - // fromTo(property, value) { - // TO DO - // this.valuesEnd[property] = value // well that's not all - // } - - // getTotalDuration() { - // to do - // } - - /** - * Method to add callbacks on the fly. - * @param {string} name callback name - * @param {Function} fn callback function - * @returns {TweenExtra} - */ - on(name, fn) { - if (['start', 'stop', 'update', 'complete', 'pause', 'resume'].indexOf(name) > -1) { - this[`_on${name.charAt(0).toUpperCase() + name.slice(1)}`] = fn; - } - return this; - } - - /** - * Method to set options on the fly. - * * accepting [repeat,yoyo,delay,repeatDelay,easing] - * - * @param {string} option the tick time - * @param {string | number | number[]} value the tick time - * @returns {TweenExtra} - */ - option(option, value) { - this[`_${option}`] = value; - return this; - } -} - -// Tween Interface -connect.tween = TweenExtra; diff --git a/src/util/degToRad.js b/src/util/degToRad.js deleted file mode 100644 index 263b0c3..0000000 --- a/src/util/degToRad.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * degToRad - * - * Returns the value of a degree angle in radian. - * - * @param {number} a the degree angle - * @returns {number} the radian angle - */ -const degToRad = (a) => (a * Math.PI) / 180; -export default degToRad; diff --git a/src/util/fromJSON.js b/src/util/fromJSON.js deleted file mode 100644 index c91bce2..0000000 --- a/src/util/fromJSON.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * fromJSON - * - * Returns the {valuesStart, valuesEnd} objects - * from a Tween instance. - * - * @param {string} str the JSON string - * @returns {JSON} the JSON object - */ -const fromJSON = (str) => { - const obj = JSON.parse(str); - return { - valuesStart: obj.valuesStart, - valuesEnd: obj.valuesEnd, - }; -}; -export default fromJSON; diff --git a/src/util/getPrefix.js b/src/util/getPrefix.js deleted file mode 100644 index cca35d3..0000000 --- a/src/util/getPrefix.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * getPrefix - * - * Returns browser CSS3 prefix. Keep `for()` - * for wider browser support. - * - * @returns {?string} the browser prefix - */ -const getPrefix = () => { - let thePrefix = null; - const prefixes = ['Moz', 'moz', 'Webkit', 'webkit', 'O', 'o', 'Ms', 'ms']; - for (let i = 0, pfl = prefixes.length; i < pfl; i += 1) { - if (`${prefixes[i]}Transform` in document.body.style) { - thePrefix = prefixes[i]; break; // !! BREAK - } - } - return thePrefix; -}; -export default getPrefix; diff --git a/src/util/hexToRGB.js b/src/util/hexToRGB.js deleted file mode 100644 index 8ce596c..0000000 --- a/src/util/hexToRGB.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * hexToRGB - * - * Converts a #HEX color format into RGB - * and returns a color object {r,g,b}. - * - * @param {string} hex the degree angle - * @returns {KUTE.colorObject | null} the radian angle - */ -const hexToRGB = (hex) => { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - const hexShorthand = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - const HEX = hex.replace(hexShorthand, (_, r, g, b) => r + r + g + g + b + b); - const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(HEX); - - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), - } : null; -}; -export default hexToRGB; diff --git a/src/util/now.js b/src/util/now.js deleted file mode 100644 index 27759c0..0000000 --- a/src/util/now.js +++ /dev/null @@ -1,32 +0,0 @@ -// Include a performance.now polyfill. -// source https://github.com/tweenjs/tween.js/blob/master/src/Now.ts -let performanceNow; - -// In node.js, use process.hrtime. -// eslint-disable-next-line -// @ts-ignore -if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { - performanceNow = () => { - // eslint-disable-next-line - // @ts-ignore - const time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; -} else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { - // In a browser, use self.performance.now if it is available. - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - performanceNow = self.performance.now.bind(self.performance); -} else if (typeof Date !== 'undefined' && Date.now) { - // Use Date.now if it is available. - performanceNow = Date.now; -} else { - // Otherwise, use 'new Date().getTime()'. - performanceNow = () => new Date().getTime(); -} - -const now = performanceNow; - -export default now; diff --git a/src/util/polyfill-legacy.js b/src/util/polyfill-legacy.js deleted file mode 100644 index 7833696..0000000 --- a/src/util/polyfill-legacy.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * build this polyfill for IE9+ browser support - */ -// import 'minifill/src/this.Window' -// import 'minifill/src/this.Document' -// import 'minifill/src/window.HTMLElement' - -// import 'minifill/src/Object.defineProperty' -// import 'minifill/src/Object.create' -import 'minifill/src/Function.prototype.bind'; - -import 'minifill/src/Array.from'; -import 'minifill/src/Array.prototype.map'; -import 'minifill/src/Array.prototype.some'; -import 'minifill/src/Array.prototype.every'; -import 'minifill/src/Array.prototype.includes'; -import 'minifill/src/Array.prototype.flat'; -import 'minifill/src/String.prototype.includes'; - -// IE9+ -import 'minifill/src/Date.now'; -import 'minifill/src/window.performance.now'; -import 'minifill/src/window.requestAnimationFrame'; diff --git a/src/util/polyfill.js b/src/util/polyfill.js deleted file mode 100644 index 2e2514a..0000000 --- a/src/util/polyfill.js +++ /dev/null @@ -1,8 +0,0 @@ -// IE10+ -import 'minifill/src/Array.from'; -import 'minifill/src/Array.prototype.flat'; -import 'minifill/src/Array.prototype.includes'; -import 'minifill/src/String.prototype.includes'; -import 'minifill/src/Number.isFinite'; -import 'minifill/src/Number.isInteger'; -import 'minifill/src/Number.isNaN'; diff --git a/src/util/progressBar.js b/src/util/progressBar.js deleted file mode 100644 index 65fa8d0..0000000 --- a/src/util/progressBar.js +++ /dev/null @@ -1,109 +0,0 @@ -import KEC from '../objects/kute'; -import connect from '../objects/connect'; -import selector from './selector'; - -/** - * ProgressBar - * - * @class - * A progress bar utility for KUTE.js that will connect - * a target ``. with a Tween instance - * allowing it to control the progress of the Tween. - */ -export default class ProgressBar { - /** - * @constructor - * @param {HTMLElement} el target or string selector - * @param {KUTE.Tween} multi when true returns an array of elements - */ - constructor(element, tween) { - this.element = selector(element); - this.element.tween = tween; - this.element.tween.toolbar = this.element; - this.element.toolbar = this; - [this.element.output] = this.element.parentNode.getElementsByTagName('OUTPUT'); - - // invalidate - if (!(this.element instanceof HTMLInputElement)) throw TypeError('Target element is not [HTMLInputElement]'); - if (this.element.type !== 'range') throw TypeError('Target element is not a range input'); - if (!(tween instanceof connect.tween)) throw TypeError(`tween parameter is not [${connect.tween}]`); - - this.element.setAttribute('value', 0); - this.element.setAttribute('min', 0); - this.element.setAttribute('max', 1); - this.element.setAttribute('step', 0.0001); - - this.element.tween._onUpdate = this.updateBar; - - this.element.addEventListener('mousedown', this.downAction, false); - } - - updateBar() { - const tick = 0.0001; - const { output } = this.toolbar; - - // let progress = this.paused ? this.toolbar.value - // : (KEC.Time() - this._startTime) / this._duration; - // progress = progress > 1 - tick ? 1 : progress < 0.01 ? 0 : progress; - - let progress; - if (this.paused) { - progress = this.toolbar.value; - } else { - progress = (KEC.Time() - this._startTime) / this._duration; - } - - // progress = progress > 1 - tick ? 1 : progress < 0.01 ? 0 : progress; - if (progress > 1 - tick) progress = 1; - if (progress < 0.01) progress = 0; - - const value = !this._reversed ? progress : 1 - progress; - this.toolbar.value = value; - // eslint-disable-next-line no-bitwise - if (output) output.value = `${(value * 10000 >> 0) / 100}%`; - } - - toggleEvents(action) { - // add passive handler ? - this.element[`${action}EventListener`]('mousemove', this.moveAction, false); - this.element[`${action}EventListener`]('mouseup', this.upAction, false); - } - - updateTween() { - // make sure we never complete the tween - const progress = (!this.tween._reversed ? this.value : 1 - this.value) - * this.tween._duration - 0.0001; - - this.tween._startTime = 0; - this.tween.update(progress); - } - - moveAction() { - this.toolbar.updateTween.call(this); - } - - downAction() { - if (!this.tween.playing) { - this.tween.start(); - } - - if (!this.tween.paused) { - this.tween.pause(); - this.toolbar.toggleEvents('add'); - - KEC.Tick = cancelAnimationFrame(KEC.Ticker); - } - } - - upAction() { - if (this.tween.paused) { - if (this.tween.paused) this.tween.resume(); - - this.tween._startTime = KEC.Time() - - (!this.tween._reversed ? this.value : 1 - this.value) * this.tween._duration; - - this.toolbar.toggleEvents('remove'); - KEC.Tick = requestAnimationFrame(KEC.Ticker); - } - } -} diff --git a/src/util/radToDeg.js b/src/util/radToDeg.js deleted file mode 100644 index d5de40c..0000000 --- a/src/util/radToDeg.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * radToDeg - * - * Returns the value of a radian in degrees. - * - * @param {number} a the value in radian - * @returns {number} the value in degrees - */ -const radToDeg = (a) => (a * 180) / Math.PI; -export default radToDeg; diff --git a/src/util/rgbToHex.js b/src/util/rgbToHex.js deleted file mode 100644 index 66333e0..0000000 --- a/src/util/rgbToHex.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * rgbToHex - * - * Converts an {r,g,b} color `Object` into #HEX string color format. - * Webkit browsers ignore HEX, always use RGB/RGBA. - * - * @param {number} r the red value - * @param {number} g the green value - * @param {number} b the blue value - * @returns {string} the #HEX string - */ -// eslint-disable-next-line no-bitwise -const rgbToHex = (r, g, b) => `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`; -export default rgbToHex; diff --git a/src/util/selector.js b/src/util/selector.js deleted file mode 100644 index 8c4d917..0000000 --- a/src/util/selector.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ -export default function selector(el, multi) { - try { - let requestedElem; - let itemsArray; - if (multi) { - itemsArray = el instanceof Array && el.every((x) => x instanceof Element); - requestedElem = el instanceof HTMLCollection || el instanceof NodeList || itemsArray - ? el : document.querySelectorAll(el); - } else { - requestedElem = el instanceof Element || el === window // scroll - ? el : document.querySelector(el); - } - return requestedElem; - } catch (e) { - throw TypeError(`KUTE.js - Element(s) not found: ${el}.`); - } -} diff --git a/src/util/supportLegacyTransform.js b/src/util/supportLegacyTransform.js deleted file mode 100644 index f9a0c56..0000000 --- a/src/util/supportLegacyTransform.js +++ /dev/null @@ -1,5 +0,0 @@ -import transformProperty from './transformProperty'; - -/** check if transform is supported via prefixed property */ -const supportTransform = transformProperty in document.head.style; -export default supportTransform; diff --git a/src/util/toJSON.js b/src/util/toJSON.js deleted file mode 100644 index f350234..0000000 --- a/src/util/toJSON.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * toJSON - * - * Returns the {valuesStart, valuesEnd} objects - * from a Tween instance in JSON string format. - * - * @param {KUTE.Tween} tween the Tween instance - * @returns {string} the JSON string - */ -const toJSON = (tween) => { - const obj = { - valuesStart: tween.valuesStart, - valuesEnd: tween.valuesEnd, - }; - return JSON.stringify(obj); -}; -export default toJSON; diff --git a/src/util/transformProperty.js b/src/util/transformProperty.js deleted file mode 100644 index ccf07e2..0000000 --- a/src/util/transformProperty.js +++ /dev/null @@ -1,5 +0,0 @@ -import trueProperty from './trueProperty'; - -/** the `transform` string for legacy browsers */ -const transformProperty = trueProperty('transform'); -export default transformProperty; diff --git a/src/util/trueColor.js b/src/util/trueColor.js deleted file mode 100644 index 03c2887..0000000 --- a/src/util/trueColor.js +++ /dev/null @@ -1,49 +0,0 @@ -import hexToRGB from './hexToRGB'; - -/** - * trueColor - * - * Transform any color to rgba()/rgb() and return a nice RGB(a) object. - * - * @param {string} colorString the color input - * @returns {KUTE.colorObject} the {r,g,b,a} color object - */ -const trueColor = (colorString) => { - let result; - if (/rgb|rgba/.test(colorString)) { // first check if it's a rgb string - const vrgb = colorString.replace(/\s|\)/, '').split('(')[1].split(','); - const colorAlpha = vrgb[3] ? vrgb[3] : null; - if (!colorAlpha) { - result = { r: parseInt(vrgb[0], 10), g: parseInt(vrgb[1], 10), b: parseInt(vrgb[2], 10) }; - } - result = { - r: parseInt(vrgb[0], 10), - g: parseInt(vrgb[1], 10), - b: parseInt(vrgb[2], 10), - a: parseFloat(colorAlpha), - }; - } if (/^#/.test(colorString)) { - const fromHex = hexToRGB(colorString); - result = { r: fromHex.r, g: fromHex.g, b: fromHex.b }; - } if (/transparent|none|initial|inherit/.test(colorString)) { - result = { - r: 0, g: 0, b: 0, a: 0, - }; - } - // maybe we can check for web safe colors - // only works in a browser - if (!/^#|^rgb/.test(colorString)) { - const siteHead = document.getElementsByTagName('head')[0]; - siteHead.style.color = colorString; - let webColor = getComputedStyle(siteHead, null).color; - webColor = /rgb/.test(webColor) ? webColor.replace(/[^\d,]/g, '').split(',') : [0, 0, 0]; - siteHead.style.color = ''; - result = { - r: parseInt(webColor[0], 10), - g: parseInt(webColor[1], 10), - b: parseInt(webColor[2], 10), - }; - } - return result; -}; -export default trueColor; diff --git a/src/util/trueDimension.js b/src/util/trueDimension.js deleted file mode 100644 index 4301b08..0000000 --- a/src/util/trueDimension.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * trueDimension - * - * Returns the string value of a specific CSS property converted into a nice - * { v = value, u = unit } object. - * - * @param {string} dimValue the property string value - * @param {boolean | number} isAngle sets the utility to investigate angles - * @returns {{v: number, u: string}} the true {value, unit} tuple - */ -const trueDimension = (dimValue, isAngle) => { - const intValue = parseInt(dimValue, 10) || 0; - const mUnits = ['px', '%', 'deg', 'rad', 'em', 'rem', 'vh', 'vw']; - let theUnit; - - for (let mIndex = 0; mIndex < mUnits.length; mIndex += 1) { - if (typeof dimValue === 'string' && dimValue.includes(mUnits[mIndex])) { - theUnit = mUnits[mIndex]; break; - } - } - if (theUnit === undefined) { - theUnit = isAngle ? 'deg' : 'px'; - } - - return { v: intValue, u: theUnit }; -}; -export default trueDimension; diff --git a/src/util/trueProperty.js b/src/util/trueProperty.js deleted file mode 100644 index 7bff726..0000000 --- a/src/util/trueProperty.js +++ /dev/null @@ -1,19 +0,0 @@ -import getPrefix from './getPrefix'; - -/** - * trueProperty - * - * Returns prefixed property name in a legacy browser - * or the regular name in modern browsers. - * - * @param {string} property the property name - * @returns {string} the right property name for every browser - */ -const trueProperty = (property) => { - const prop = !(property in document.head.style) - ? getPrefix() + (property.charAt(0).toUpperCase() + property.slice(1)) - : property; - return prop; -}; - -export default trueProperty; diff --git a/src/util/version.js b/src/util/version.js deleted file mode 100644 index 369fd70..0000000 --- a/src/util/version.js +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-ignore -import { version } from '../../package.json'; - -/** - * A global namespace for library version. - * @type {string} - */ -const Version = version; -export default Version; diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index fdc8e92..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "target": "ESNext", - "moduleResolution": "Node", - "declaration": true, - "resolveJsonModule": true, - "emitDeclarationOnly": true, - "maxNodeModuleJsDepth": 3, // allows to incorporate dependency utils - "strict": true, - "allowJs": true, - "rootDir": "../", - "outFile": "types/kute.d.ts", // UN-comment to generate - "outDir": "types", - }, - "files": [ - "types/index.d.ts", - // "types/kute.d.ts", // comment to re-generate, delete file - "types/more/kute.ts", - "types/more/types.d.ts", - ], -} diff --git a/types/index.d.ts b/types/index.d.ts deleted file mode 100644 index 1b28421..0000000 --- a/types/index.d.ts +++ /dev/null @@ -1,155 +0,0 @@ -export as namespace KUTE; - -// dependencies -export * as SVGPathCommander from "svg-path-commander"; - -import './kute'; -export { default as Animation } from "kute.js/src/animation/animation"; -export { default as AnimationBase } from "kute.js/src/animation/animationBase"; -export { default as AnimationDevelopment } from "kute.js/src/animation/animationDevelopment"; -export { default as backgroundPosition } from "kute.js/src/components/backgroundPosition"; -export { default as backgroundPositionBase } from "kute.js/src/components/backgroundPositionBase"; -export { default as borderRadius } from "kute.js/src/components/borderRadius"; -export { default as borderRadiusBase } from "kute.js/src/components/borderRadiusBase"; -export { default as boxModel } from "kute.js/src/components/boxModel"; -export { default as boxModelBase } from "kute.js/src/components/boxModelBase"; -export { default as boxModelEssential } from "kute.js/src/components/boxModelEssential"; -export { default as clipProperty } from "kute.js/src/components/clipProperty"; -export { default as clipPropertyBase } from "kute.js/src/components/clipPropertyBase"; -export { default as colorProperties } from "kute.js/src/components/colorProperties"; -export { default as colorPropertiesBase } from "kute.js/src/components/colorPropertiesBase"; -export { default as crossBrowserMove } from "kute.js/src/components/crossBrowserMove"; -export { default as filterEffects } from "kute.js/src/components/filterEffects"; -export { default as filterEffectsBase } from "kute.js/src/components/filterEffectsBase"; -export { default as htmlAttributes } from "kute.js/src/components/htmlAttributes"; -export { default as htmlAttributesBase } from "kute.js/src/components/htmlAttributesBase"; -export { default as opacityProperty } from "kute.js/src/components/opacityProperty"; -export { default as opacityPropertyBase } from "kute.js/src/components/opacityPropertyBase"; -export { default as scrollProperty } from "kute.js/src/components/scrollProperty"; -export { default as scrollPropertyBase } from "kute.js/src/components/scrollPropertyBase"; -export { default as shadowProperties } from "kute.js/src/components/shadowProperties"; -export { default as shadowPropertiesBase } from "kute.js/src/components/shadowPropertiesBase"; -export { default as svgCubicMorph } from "kute.js/src/components/svgCubicMorph"; -export { default as svgCubicMorphBase } from "kute.js/src/components/svgCubicMorphBase"; -export { default as svgDraw } from "kute.js/src/components/svgDraw"; -export { default as svgDrawBase } from "kute.js/src/components/svgDrawBase"; -export { default as svgMorph } from "kute.js/src/components/svgMorph"; -export { default as svgMorphBase } from "kute.js/src/components/svgMorphBase"; -export { default as svgTransform } from "kute.js/src/components/svgTransform"; -export { default as svgTransformBase } from "kute.js/src/components/svgTransformBase"; -export { default as textProperties } from "kute.js/src/components/textProperties"; -export { default as textPropertiesBase } from "kute.js/src/components/textPropertiesBase"; -export { default as textWrite } from "kute.js/src/components/textWrite"; -export { default as textWriteBase } from "kute.js/src/components/textWriteBase"; -export { default as transformFunctions } from "kute.js/src/components/transformFunctions"; -export { default as transformFunctionsBase } from "kute.js/src/components/transformFunctionsBase"; -export { default as transformLegacy } from "kute.js/src/components/transformLegacy"; -export { default as transformLegacyBase } from "kute.js/src/components/transformLegacyBase"; -export { default as transformMatrix } from "kute.js/src/components/transformMatrix"; -export { default as transformMatrixBase } from "kute.js/src/components/transformMatrixBase"; -export { default as add } from "kute.js/src/core/add"; -export { default as getAll } from "kute.js/src/core/getAll"; -export { default as Internals } from "kute.js/src/core/internals"; -export { default as linkInterpolation } from "kute.js/src/core/linkInterpolation"; -export { default as queueStart } from "kute.js/src/core/queueStart"; -export { default as remove } from "kute.js/src/core/remove"; -export { default as removeAll } from "kute.js/src/core/removeAll"; -export { default as Render } from "kute.js/src/core/render"; -export { default as EasingBase } from "kute.js/src/easing/easing-base"; -export { default as EasingBezier } from "kute.js/src/easing/easing-bezier"; -export { default as Easing } from "kute.js/src/easing/easing"; -export { default as allFromTo } from "kute.js/src/interface/allFromTo"; -export { default as allTo } from "kute.js/src/interface/allTo"; -export { default as fromTo } from "kute.js/src/interface/fromTo"; -export { default as to } from "kute.js/src/interface/to"; -export { default as arrays } from "kute.js/src/interpolation/arrays"; -export { default as colors } from "kute.js/src/interpolation/colors"; -export { default as coords } from "kute.js/src/interpolation/coords"; -export { default as numbers } from "kute.js/src/interpolation/numbers"; -export { default as perspective } from "kute.js/src/interpolation/perspective"; -export { default as rotate } from "kute.js/src/interpolation/rotate"; -export { default as rotate3d } from "kute.js/src/interpolation/rotate3d"; -export { default as scale } from "kute.js/src/interpolation/scale"; -export { default as skew } from "kute.js/src/interpolation/skew"; -export { default as skewX } from "kute.js/src/interpolation/skewX"; -export { default as skewY } from "kute.js/src/interpolation/skewY"; -export { default as translate } from "kute.js/src/interpolation/translate"; -export { default as translate3d } from "kute.js/src/interpolation/translate3d"; -export { default as units } from "kute.js/src/interpolation/units"; -export { default as ComponentsBase } from "kute.js/src/objects/componentsBase"; -export { default as ComponentsDefault } from "kute.js/src/objects/componentsDefault"; -export { default as ComponentsExtra } from "kute.js/src/objects/componentsExtra"; -export { default as connect } from "kute.js/src/objects/connect"; -export { default as crossCheck } from "kute.js/src/objects/crossCheck"; -export { default as defaultOptions } from "kute.js/src/objects/defaultOptions"; -export { default as defaultValues } from "kute.js/src/objects/defaultValues"; -export { default as globalObject } from "kute.js/src/objects/globalObject"; -export { default as Interpolate } from "kute.js/src/objects/interpolate"; -export { default as KEC } from "kute.js/src/objects/kute"; -export { default as linkProperty } from "kute.js/src/objects/linkProperty"; -export { default as Objects } from "kute.js/src/objects/objects"; -export { default as ObjectsBase } from "kute.js/src/objects/objectsBase"; -export { default as onComplete } from "kute.js/src/objects/onComplete"; -export { default as onStart } from "kute.js/src/objects/onStart"; -export { default as prepareProperty } from "kute.js/src/objects/prepareProperty"; -export { default as prepareStart } from "kute.js/src/objects/prepareStart"; -export { default as supportedProperties } from "kute.js/src/objects/supportedProperties"; -export { default as Tweens } from "kute.js/src/objects/tweens"; -export { default as Util } from "kute.js/src/objects/util"; -export { default as getInlineStyle } from "kute.js/src/process/getInlineStyle"; -export { default as getInlineStyleLegacy } from "kute.js/src/process/getInlineStyleLegacy"; -export { default as getStartValues } from "kute.js/src/process/getStartValues"; -export { default as getStyleForProperty } from "kute.js/src/process/getStyleForProperty"; -export { default as prepareObject } from "kute.js/src/process/prepareObject"; -export { default as Process } from "kute.js/src/process/process"; -export { default as Tween } from "kute.js/src/tween/tween"; -export { default as TweenBase } from "kute.js/src/tween/tweenBase"; -export { default as TweenCollection } from "kute.js/src/tween/tweenCollection"; -export { default as TweenExtra } from "kute.js/src/tween/tweenExtra"; -export { default as degToRad } from "kute.js/src/util/degToRad"; -export { default as fromJSON } from "kute.js/src/util/fromJSON"; -export { default as getPrefix } from "kute.js/src/util/getPrefix"; -export { default as hexToRGB } from "kute.js/src/util/hexToRGB"; -export { default as now } from "kute.js/src/util/now"; -export { default as ProgressBar } from "kute.js/src/util/progressBar"; -export { default as radToDeg } from "kute.js/src/util/radToDeg"; -export { default as rgbToHex } from "kute.js/src/util/rgbToHex"; -export { default as selector } from "kute.js/src/util/selector"; -export { default as supportLegacyTransform } from "kute.js/src/util/supportLegacyTransform"; -export { default as toJSON } from "kute.js/src/util/toJSON"; -export { default as transformProperty } from "kute.js/src/util/transformProperty"; -export { default as trueColor } from "kute.js/src/util/trueColor"; -export { default as trueDimension } from "kute.js/src/util/trueDimension"; -export { default as trueProperty } from "kute.js/src/util/trueProperty"; -export { default as Version } from "kute.js/src/util/version"; - -export { - easingFunction, - easingOption, - tweenOptions, - tweenProps, - tweenParams, - twCollection, - chainOption, - propValue, - rawValue, - interpolationFn, - preparePropFn, - prepareStartFn, - fullComponent, - baseComponent, - curveObject, - polygonMorph, - polygonObject, - transformMObject, - transformFObject, - transformSVGObject, - exactPolygon, - drawObject, - curveSpecs, - colorObject, - shadowObject, - filterList, - selectorType, -} from './more/types'; - diff --git a/types/kute.d.ts b/types/kute.d.ts deleted file mode 100644 index acf3cc8..0000000 --- a/types/kute.d.ts +++ /dev/null @@ -1,3054 +0,0 @@ -declare module "kute.js/src/objects/supportedProperties" { - export default supportedProperties; - const supportedProperties: {}; -} -declare module "kute.js/src/objects/defaultValues" { - export default defaultValues; - const defaultValues: {}; -} -declare module "kute.js/src/objects/defaultOptions" { - export default defaultOptions; - namespace defaultOptions { - const duration: number; - const delay: number; - const easing: string; - const repeat: number; - const repeatDelay: number; - const yoyo: boolean; - const resetStart: boolean; - const offset: number; - } -} -declare module "kute.js/src/objects/prepareProperty" { - export default prepareProperty; - const prepareProperty: {}; -} -declare module "kute.js/src/objects/prepareStart" { - export default prepareStart; - const prepareStart: {}; -} -declare module "kute.js/src/objects/onStart" { - export default onStart; - const onStart: {}; -} -declare module "kute.js/src/objects/onComplete" { - export default onComplete; - const onComplete: {}; -} -declare module "kute.js/src/objects/crossCheck" { - export default crossCheck; - const crossCheck: {}; -} -declare module "kute.js/src/objects/linkProperty" { - export default linkProperty; - const linkProperty: {}; -} -declare module "kute.js/src/objects/util" { - export default Util; - const Util: {}; -} -declare module "kute.js/src/objects/interpolate" { - export default interpolate; - const interpolate: {}; -} -declare module "kute.js/src/animation/animation" { - /** - * Animation Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - */ - export default class Animation { - /** - * @constructor - * @param {KUTE.fullComponent} Component - */ - constructor(Component: KUTE.fullComponent); - } -} -declare module "kute.js/src/animation/animationBase" { - /** - * Animation Base Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * This class only registers the minimal amount of component information - * required to enable components animation, which means value processing - * as well as `to()` and `allTo()` methods are not supported. - */ - export default class AnimationBase { - /** - * @class - * @param {KUTE.baseComponent} Component - */ - constructor(Component: KUTE.baseComponent); - _: number; - } -} -declare module "kute.js/src/animation/animationDevelopment" { - /** - * Animation Development Class - * - * Registers components by populating KUTE.js objects and makes sure - * no duplicate component / property is allowed. - * - * In addition to the default class, this one provides more component - * information to help you with custom component development. - */ - export default class AnimationDevelopment extends Animation { - /** - * - * @param {KUTE.fullComponent} args - */ - constructor(Component: any); - } - import Animation from "kute.js/src/animation/animation"; -} -declare module "kute.js/src/process/getStyleForProperty" { - /** - * getStyleForProperty - * - * Returns the computed style property for element for .to() method. - * Used by for the `.to()` static method. - * - * @param {Element} elem - * @param {string} propertyName - * @returns {string} - */ - export default function getStyleForProperty(elem: Element, propertyName: string): string; -} -declare module "kute.js/src/interpolation/numbers" { - /** - * Numbers Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {number} v progress - * @returns {number} the interpolated number - */ - export default function numbers(a: number, b: number, v: number): number; -} -declare module "kute.js/src/util/trueDimension" { - export default trueDimension; - /** - * trueDimension - * - * Returns the string value of a specific CSS property converted into a nice - * { v = value, u = unit } object. - * - * @param {string} dimValue the property string value - * @param {boolean | number} isAngle sets the utility to investigate angles - * @returns {{v: number, u: string}} the true {value, unit} tuple - */ - function trueDimension(dimValue: string, isAngle: boolean | number): { - v: number; - u: string; - }; -} -declare module "kute.js/src/objects/kute" { - export default KEC; - /** - * The KUTE.js Execution Context - */ - const KEC: {}; -} -declare module "kute.js/src/components/backgroundPositionBase" { - /** - * Sets the property update function. - * @param {string} prop the property name - */ - export function onStartBgPos(prop: string): void; - export default BackgroundPositionBase; - namespace BackgroundPositionBase { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartBgPos as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/backgroundPosition" { - export default BackgroundPosition; - namespace BackgroundPosition { - export const component: string; - export const property: string; - export const defaultValue: number[]; - export namespace Interpolate { - export { numbers }; - } - export { bgPositionFunctions as functions }; - export namespace Util { - export { trueDimension }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace bgPositionFunctions { - export { getBgPos as prepareStart }; - export { prepareBgPos as prepareProperty }; - export { onStartBgPos as onStart }; - } - import trueDimension from "kute.js/src/util/trueDimension"; - /** - * Returns the property computed style. - * @param {string} prop the property - * @returns {string} the property computed style - */ - function getBgPos(prop: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ - function prepareBgPos(_: string, value: string): number[]; - import { onStartBgPos } from "kute.js/src/components/backgroundPositionBase"; -} -declare module "kute.js/src/interpolation/units" { - /** - * Units Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the interpolated value + unit string - */ - export default function units(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/components/borderRadiusBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function radiusOnStartFn(tweenProp: string): void; - export default BorderRadiusBase; - namespace BorderRadiusBase { - const component: string; - const category: string; - namespace Interpolate { - export { units }; - } - namespace functions { - export { radiusOnStart as onStart }; - } - } - import units from "kute.js/src/interpolation/units"; - const radiusOnStart: {}; -} -declare module "kute.js/src/components/borderRadius" { - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} the property computed style - */ - export function getRadius(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} value the property value - * @returns {{v: number, u: string}} the property tween object - */ - export function prepareRadius(_: any, value: string): { - v: number; - u: string; - }; - export namespace radiusFunctions { - export { getRadius as prepareStart }; - export { prepareRadius as prepareProperty }; - export { radiusOnStart as onStart }; - } - export default BorderRadius; - const radiusOnStart: {}; - namespace BorderRadius { - export const component: string; - export const category: string; - export { radiusProps as properties }; - export { radiusValues as defaultValues }; - export namespace Interpolate { - export { units }; - } - export { radiusFunctions as functions }; - export namespace Util { - export { trueDimension }; - } - } - const radiusProps: string[]; - const radiusValues: {}; - import units from "kute.js/src/interpolation/units"; - import trueDimension from "kute.js/src/util/trueDimension"; -} -declare module "kute.js/src/components/boxModelBase" { - /** - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - export function boxModelOnStart(tweenProp: string): void; - export default BoxModelBase; - namespace BoxModelBase { - export const component: string; - export const category: string; - export { baseBoxProps as properties }; - export namespace Interpolate { - export { numbers }; - } - export namespace functions { - export { baseBoxOnStart as onStart }; - } - } - const baseBoxProps: string[]; - import numbers from "kute.js/src/interpolation/numbers"; - const baseBoxOnStart: {}; -} -declare module "kute.js/src/components/boxModel" { - export default BoxModel; - namespace BoxModel { - export const component: string; - export const category: string; - export { boxModelProperties as properties }; - export { boxModelValues as defaultValues }; - export namespace Interpolate { - export { numbers }; - } - export { boxModelFunctions as functions }; - } - const boxModelProperties: string[]; - const boxModelValues: {}; - import numbers from "kute.js/src/interpolation/numbers"; - namespace boxModelFunctions { - export { getBoxModel as prepareStart }; - export { prepareBoxModel as prepareProperty }; - export { boxPropsOnStart as onStart }; - } - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getBoxModel(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareBoxModel(tweenProp: string, value: string): number; - const boxPropsOnStart: {}; -} -declare module "kute.js/src/components/boxModelEssential" { - export default BoxModelEssential; - namespace BoxModelEssential { - export const component: string; - export const category: string; - export { essentialBoxProps as properties }; - export { essentialBoxPropsValues as defaultValues }; - export namespace Interpolate { - export { numbers }; - } - export { essentialBoxModelFunctions as functions }; - export namespace Util { - export { trueDimension }; - } - } - const essentialBoxProps: string[]; - namespace essentialBoxPropsValues { - const top: number; - const left: number; - const width: number; - const height: number; - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace essentialBoxModelFunctions { - export { getBoxModel as prepareStart }; - export { prepareBoxModel as prepareProperty }; - export { essentialBoxOnStart as onStart }; - } - import trueDimension from "kute.js/src/util/trueDimension"; - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getBoxModel(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property name - * @returns {number} the property tween object - */ - function prepareBoxModel(tweenProp: string, value: string): number; - const essentialBoxOnStart: {}; -} -declare module "kute.js/src/components/clipPropertyBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartClip(tweenProp: string): void; - export default ClipPropertyBase; - namespace ClipPropertyBase { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartClip as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/clipProperty" { - export default ClipProperty; - namespace ClipProperty { - export const component: string; - export const property: string; - export const defaultValue: number[]; - export namespace Interpolate { - export { numbers }; - } - export { clipFunctions as functions }; - export namespace Util { - export { trueDimension }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace clipFunctions { - export { getClip as prepareStart }; - export { prepareClip as prepareProperty }; - export { onStartClip as onStart }; - } - import trueDimension from "kute.js/src/util/trueDimension"; - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string | number[]} computed style for property - */ - function getClip(tweenProp: string): string | number[]; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number[]} the property tween object - */ - function prepareClip(_: string, value: string): number[]; - import { onStartClip } from "kute.js/src/components/clipPropertyBase"; -} -declare module "kute.js/src/util/hexToRGB" { - export default hexToRGB; - /** - * hexToRGB - * - * Converts a #HEX color format into RGB - * and returns a color object {r,g,b}. - * - * @param {string} hex the degree angle - * @returns {KUTE.colorObject | null} the radian angle - */ - function hexToRGB(hex: string): KUTE.colorObject | null; -} -declare module "kute.js/src/util/trueColor" { - export default trueColor; - /** - * trueColor - * - * Transform any color to rgba()/rgb() and return a nice RGB(a) object. - * - * @param {string} colorString the color input - * @returns {KUTE.colorObject} the {r,g,b,a} color object - */ - function trueColor(colorString: string): KUTE.colorObject; -} -declare module "kute.js/src/interpolation/colors" { - /** - * Color Interpolation Function. - * - * @param {KUTE.colorObject} a start color - * @param {KUTE.colorObject} b end color - * @param {number} v progress - * @returns {string} the resulting color - */ - export default function colors(a: KUTE.colorObject, b: KUTE.colorObject, v: number): string; -} -declare module "kute.js/src/components/colorPropertiesBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartColors(tweenProp: string): void; - export namespace baseColors { - const component: string; - const category: string; - namespace Interpolate { - export { numbers }; - export { colors }; - } - namespace functions { - export { colorsOnStart as onStart }; - } - } - export default baseColors; - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - const colorsOnStart: {}; -} -declare module "kute.js/src/components/colorProperties" { - export default colorProperties; - namespace colorProperties { - export const component: string; - export const category: string; - export { supportedColors as properties }; - export { defaultColors as defaultValues }; - export namespace Interpolate { - export { numbers }; - export { colors }; - } - export { colorFunctions as functions }; - export namespace Util { - export { trueColor }; - } - } - const supportedColors: string[]; - const defaultColors: {}; - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - namespace colorFunctions { - export { getColor as prepareStart }; - export { prepareColor as prepareProperty }; - export { colorsOnStart as onStart }; - } - import trueColor from "kute.js/src/util/trueColor"; - /** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} property computed style - */ - function getColor(prop: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.colorObject} the property tween object - */ - function prepareColor(_: string, value: string): KUTE.colorObject; - const colorsOnStart: {}; -} -declare module "kute.js/src/process/getInlineStyle" { - /** - * getInlineStyle - * Returns the transform style for element from - * cssText. Used by for the `.to()` static method. - * - * @param {Element} el target element - * @returns {object} - */ - export default function getInlineStyle(el: Element): object; -} -declare module "kute.js/src/util/getPrefix" { - export default getPrefix; - /** - * getPrefix - * - * Returns browser CSS3 prefix. Keep `for()` - * for wider browser support. - * - * @returns {?string} the browser prefix - */ - function getPrefix(): string | null; -} -declare module "kute.js/src/util/trueProperty" { - export default trueProperty; - /** - * trueProperty - * - * Returns prefixed property name in a legacy browser - * or the regular name in modern browsers. - * - * @param {string} property the property name - * @returns {string} the right property name for every browser - */ - function trueProperty(property: string): string; -} -declare module "kute.js/src/components/crossBrowserMove" { - /** - * Sets the property update function. - * @param {string} tweenProp the `path` property - */ - export function onStartComponent(tweenProp: string): void; - export namespace baseCrossBrowserMove { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartComponent as onStart }; - } - } - export default crossBrowserMove; - import numbers from "kute.js/src/interpolation/numbers"; - namespace crossBrowserMove { - const component_1: string; - export { component_1 as component }; - const property_1: string; - export { property_1 as property }; - export const defaultValue: number[]; - export namespace Interpolate_1 { - export { numbers }; - } - export { Interpolate_1 as Interpolate }; - export { componentFunctions as functions }; - export namespace Util { - export { trueProperty }; - } - } - namespace componentFunctions { - export { getComponentCurrentValue as prepareStart }; - export { prepareComponentValue as prepareProperty }; - export { onStartComponent as onStart }; - } - import trueProperty from "kute.js/src/util/trueProperty"; - /** - * Returns the property current style. - */ - function getComponentCurrentValue(): number[]; - /** - * Returns the property tween object. - * @param {string} _ property name - * @param {string} value property value - * @returns {number[]} the property tween object - */ - function prepareComponentValue(_: string, value: string): number[]; -} -declare module "kute.js/src/components/filterEffectsBase" { - /** - * Sets the `drop-shadow` sub-property update function. - * * disimbiguation `dropshadow` interpolation function and `dropShadow` property - * @param {string} tweenProp the property name - */ - export function dropshadow(a: any, b: any, v: any): string; - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartFilter(tweenProp: string): void; - export default baseFilter; - namespace baseFilter { - const component: string; - const property: string; - namespace Interpolate { - export { numbers as opacity }; - export { numbers as blur }; - export { numbers as saturate }; - export { numbers as grayscale }; - export { numbers as brightness }; - export { numbers as contrast }; - export { numbers as sepia }; - export { numbers as invert }; - export { numbers as hueRotate }; - export namespace dropShadow { - export { numbers }; - export { colors }; - export { dropshadow }; - } - } - namespace functions { - export { onStartFilter as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; -} -declare module "kute.js/src/components/filterEffects" { - export default filterEffects; - namespace filterEffects { - export const component: string; - export const property: string; - export namespace defaultValue { - const opacity: number; - const blur: number; - const saturate: number; - const grayscale: number; - const brightness: number; - const contrast: number; - const sepia: number; - const invert: number; - const hueRotate: number; - const dropShadow: (number | { - r: number; - g: number; - b: number; - })[]; - const url: string; - } - export namespace Interpolate { - export { numbers as opacity }; - export { numbers as blur }; - export { numbers as saturate }; - export { numbers as grayscale }; - export { numbers as brightness }; - export { numbers as contrast }; - export { numbers as sepia }; - export { numbers as invert }; - export { numbers as hueRotate }; - export namespace dropShadow_1 { - export { numbers }; - export { colors }; - export { dropshadow }; - } - export { dropShadow_1 as dropShadow }; - } - export { filterFunctions as functions }; - export namespace Util { - export { parseDropShadow }; - export { parseFilterString }; - export { replaceDashNamespace }; - export { trueColor }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - import { dropshadow } from "kute.js/src/components/filterEffectsBase"; - namespace filterFunctions { - export { getFilter as prepareStart }; - export { prepareFilter as prepareProperty }; - export { onStartFilter as onStart }; - export { crossCheckFilter as crossCheck }; - } - /** - * Returns `drop-shadow` sub-property object. - * @param {(string | number)[]} shadow and `Array` with `drop-shadow` parameters - * @returns {KUTE.filterList['dropShadow']} the expected `drop-shadow` values - */ - function parseDropShadow(shadow: (string | number)[]): KUTE.filterList['dropShadow']; - /** - * Returns an array with current filter sub-properties values. - * @param {string} currentStyle the current filter computed style - * @returns {{[x: string]: number}} the filter tuple - */ - function parseFilterString(currentStyle: string): { - [x: string]: number; - }; - /** - * Returns camelCase filter sub-property. - * @param {string} str source string - * @returns {string} camelCase property name - */ - function replaceDashNamespace(str: string): string; - import trueColor from "kute.js/src/util/trueColor"; - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {string} computed style for property - */ - function getFilter(tweenProp: string, value: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property name - * @returns {KUTE.filterList} the property tween object - */ - function prepareFilter(_: string, value: string): KUTE.filterList; - import { onStartFilter } from "kute.js/src/components/filterEffectsBase"; - /** - * Adds missing sub-properties in `valuesEnd` from `valuesStart`. - * @param {string} tweenProp the property name - */ - function crossCheckFilter(tweenProp: string): void; -} -declare module "kute.js/src/components/htmlAttributesBase" { - export namespace onStartAttr { - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - function attr(tweenProp: string): void; - /** - * onStartAttr.attr - * - * Sets the sub-property update function. - * @param {string} tweenProp the property name - */ - function attr(tweenProp: string): void; - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - function attributes(tweenProp: string): void; - /** - * onStartAttr.attributes - * - * Sets the update function for the property. - * @param {string} tweenProp the property name - */ - function attributes(tweenProp: string): void; - } - export default baseAttributes; - export const attributes: {}; - namespace baseAttributes { - export { ComponentName as component }; - export const property: string; - export namespace Interpolate { - export { numbers }; - export { colors }; - } - export namespace functions { - export { onStartAttr as onStart }; - } - } - const ComponentName: "baseHTMLAttributes"; - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; -} -declare module "kute.js/src/components/htmlAttributes" { - /** - * Returns the current attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {{[x:string]: string}} attribute value - */ - export function getAttr(_: string, value: string): { - [x: string]: string; - }; - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} attrObj the property value - * @returns {number} the property tween object - */ - export function prepareAttr(tweenProp: string, attrObj: string): number; - export default htmlAttributes; - namespace htmlAttributes { - export { ComponentName as component }; - export const property: string; - export const subProperties: string[]; - export const defaultValue: { - fill: string; - stroke: string; - 'stop-color': string; - opacity: number; - 'stroke-opacity': number; - 'fill-opacity': number; - }; - export namespace Interpolate { - export { numbers }; - export { colors }; - } - export { attrFunctions as functions }; - export namespace Util { - export { replaceUppercase }; - export { trueColor }; - export { trueDimension }; - } - } - const ComponentName: "htmlAttributes"; - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - namespace attrFunctions { - export { getAttr as prepareStart }; - export { prepareAttr as prepareProperty }; - export { onStartAttr as onStart }; - } - /** - * Returns non-camelcase property name. - * @param {string} a the camelcase property name - * @returns {string} the non-camelcase property name - */ - function replaceUppercase(a: string): string; - import trueColor from "kute.js/src/util/trueColor"; - import trueDimension from "kute.js/src/util/trueDimension"; - import { onStartAttr } from "kute.js/src/components/htmlAttributesBase"; -} -declare module "kute.js/src/components/opacityPropertyBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartOpacity(tweenProp: string): void; - export default OpacityPropertyBase; - namespace OpacityPropertyBase { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartOpacity as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/opacityProperty" { - export default OpacityProperty; - namespace OpacityProperty { - export const component: string; - export const property: string; - export const defaultValue: number; - export namespace Interpolate { - export { numbers }; - } - export { opacityFunctions as functions }; - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace opacityFunctions { - export { getOpacity as prepareStart }; - export { prepareOpacity as prepareProperty }; - export { onStartOpacity as onStart }; - } - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - function getOpacity(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareOpacity(_: string, value: string): number; - import { onStartOpacity } from "kute.js/src/components/opacityPropertyBase"; -} -declare module "kute.js/src/components/scrollPropertyBase" { - /** - * Prevent further scroll events until scroll animation is over. - * @param {Event} e event object - */ - export function preventScroll(e: Event): void; - /** - * Returns the scroll element / target. - * @returns {{el: Element, st: Element}} - */ - export function getScrollTargets(): { - el: Element; - st: Element; - }; - /** - * Toggles scroll prevention callback on scroll events. - * @param {string} action addEventListener / removeEventListener - * @param {Element} element target - */ - export function toggleScrollEvents(action: string, element: Element): void; - /** - * Action performed before scroll animation start. - */ - export function scrollIn(): void; - /** - * Action performed when scroll animation ends. - */ - export function scrollOut(): void; - /** - * * Sets the scroll target. - * * Adds the scroll prevention event listener. - * * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartScroll(tweenProp: string): void; - export class onStartScroll { - /** - * * Sets the scroll target. - * * Adds the scroll prevention event listener. - * * Sets the property update function. - * @param {string} tweenProp the property name - */ - constructor(tweenProp: string); - element: HTMLElement | undefined; - } - /** - * Removes the scroll prevention event listener. - */ - export function onCompleteScroll(): void; - export const scrollContainer: HTMLElement; - export default ScrollPropertyBase; - namespace ScrollPropertyBase { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartScroll as onStart }; - export { onCompleteScroll as onComplete }; - } - namespace Util { - export { preventScroll }; - export { scrollIn }; - export { scrollOut }; - export { getScrollTargets }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/scrollProperty" { - export default ScrollProperty; - namespace ScrollProperty { - export const component: string; - export const property: string; - export const defaultValue: number; - export namespace Interpolate { - export { numbers }; - } - export { scrollFunctions as functions }; - export namespace Util { - export { preventScroll }; - export { scrollIn }; - export { scrollOut }; - export { getScrollTargets }; - export { toggleScrollEvents }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace scrollFunctions { - export { getScroll as prepareStart }; - export { prepareScroll as prepareProperty }; - export { onStartScroll as onStart }; - export { onCompleteScroll as onComplete }; - } - import { preventScroll } from "kute.js/src/components/scrollPropertyBase"; - import { scrollIn } from "kute.js/src/components/scrollPropertyBase"; - import { scrollOut } from "kute.js/src/components/scrollPropertyBase"; - import { getScrollTargets } from "kute.js/src/components/scrollPropertyBase"; - import { toggleScrollEvents } from "kute.js/src/components/scrollPropertyBase"; - /** - * Returns the current property computed style. - * @returns {number} computed style for property - */ - function getScroll(): number; - class getScroll { - element: HTMLElement | undefined; - } - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - function prepareScroll(_: string, value: string): number; - import { onStartScroll } from "kute.js/src/components/scrollPropertyBase"; - import { onCompleteScroll } from "kute.js/src/components/scrollPropertyBase"; -} -declare module "kute.js/src/components/shadowPropertiesBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartShadow(tweenProp: string): void; - export default ShadowPropertiesBase; - namespace ShadowPropertiesBase { - const component: string; - namespace Interpolate { - export { numbers }; - export { colors }; - } - namespace functions { - export { shadowPropOnStart as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - const shadowPropOnStart: {}; -} -declare module "kute.js/src/components/shadowProperties" { - /** - * Returns the current property computed style. - * @param {string} tweenProp the property name - * @returns {string} computed style for property - */ - export function getShadow(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} propValue the property value - * @returns {KUTE.shadowObject} the property tween object - */ - export function prepareShadow(tweenProp: string, propValue: string): KUTE.shadowObject; - export default ShadowProperties; - namespace ShadowProperties { - export const component: string; - export { shadowProps as properties }; - export namespace defaultValues { - const boxShadow: string; - const textShadow: string; - } - export namespace Interpolate { - export { numbers }; - export { colors }; - } - export { shadowFunctions as functions }; - export namespace Util { - export { processShadowArray }; - export { trueColor }; - } - } - const shadowProps: string[]; - import numbers from "kute.js/src/interpolation/numbers"; - import colors from "kute.js/src/interpolation/colors"; - namespace shadowFunctions { - export { getShadow as prepareStart }; - export { prepareShadow as prepareProperty }; - export { shadowPropOnStart as onStart }; - } - /** - * Return the box-shadow / text-shadow tween object. - * * box-shadow: none | h-shadow v-shadow blur spread color inset|initial|inherit - * * text-shadow: none | offset-x offset-y blur-radius color |initial|inherit - * * numbers must be floats and color must be rgb object - * - * @param {(number | string)[]} shadow an `Array` with shadow parameters - * @param {string} tweenProp the property name - * @returns {KUTE.shadowObject} the property tween object - */ - function processShadowArray(shadow: (number | string)[], tweenProp: string): KUTE.shadowObject; - import trueColor from "kute.js/src/util/trueColor"; - const shadowPropOnStart: {}; -} -declare module "kute.js/src/components/svgCubicMorphBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the `path` property - */ - export function onStartCubicMorph(tweenProp: string): void; - export default baseSvgCubicMorph; - namespace baseSvgCubicMorph { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - export { pathToString }; - } - namespace functions { - export { onStartCubicMorph as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - import pathToString from "svg-path-commander/src/convert/pathToString"; -} -declare module "kute.js/src/util/selector" { - /** - * selector - * - * A selector utility for KUTE.js. - * - * @param {KUTE.selectorType} el target(s) or string selector - * @param {boolean | number} multi when true returns an array/collection of elements - * @returns {Element | Element[] | null} - */ - export default function selector(el: KUTE.selectorType, multi: boolean | number): Element | Element[] | null; -} -declare module "kute.js/src/components/svgCubicMorph" { - export default svgCubicMorph; - namespace svgCubicMorph { - export const component: string; - export const property: string; - export const defaultValue: never[]; - export namespace Interpolate { - export { numbers }; - export { pathToString }; - } - export { svgCubicMorphFunctions as functions }; - export namespace Util { - export { pathToCurve }; - export { pathToAbsolute }; - export { pathToString }; - export { parsePathString }; - export { getRotatedCurve }; - export { getRotations }; - export { equalizeSegments }; - export { reverseCurve }; - export { clonePath }; - export { getDrawDirection }; - export { segmentCubicFactory }; - export { splitCubic }; - export { splitPath }; - export { fixPath }; - export { getCurveArray }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - import pathToString from "svg-path-commander/src/convert/pathToString"; - namespace svgCubicMorphFunctions { - export { getCubicMorph as prepareStart }; - export { prepareCubicMorph as prepareProperty }; - export { onStartCubicMorph as onStart }; - export { crossCheckCubicMorph as crossCheck }; - } - import pathToCurve from "svg-path-commander/src/convert/pathToCurve"; - import pathToAbsolute from "svg-path-commander/src/convert/pathToAbsolute"; - import parsePathString from "svg-path-commander/src/parser/parsePathString"; - /** - * Returns the `curveArray` rotation for the best morphing animation. - * @param {SVGPathCommander.curveArray} a the target `curveArray` - * @param {SVGPathCommander.curveArray} b the reference `curveArray` - * @returns {SVGPathCommander.curveArray} the best `a` rotation - */ - function getRotatedCurve(a: import("svg-path-commander").curveArray, b: import("svg-path-commander").curveArray): import("svg-path-commander").curveArray; - /** - * Returns all possible path rotations for `curveArray`. - * @param {SVGPathCommander.curveArray} a the source `curveArray` - * @returns {SVGPathCommander.curveArray[]} all rotations for source - */ - function getRotations(a: import("svg-path-commander").curveArray): import("svg-path-commander").curveArray[]; - /** - * Returns two `curveArray` with same amount of segments. - * @param {SVGPathCommander.curveArray} path1 the first `curveArray` - * @param {SVGPathCommander.curveArray} path2 the second `curveArray` - * @param {number} TL the maximum `curveArray` length - * @returns {SVGPathCommander.curveArray[]} equalized segments - */ - function equalizeSegments(path1: import("svg-path-commander").curveArray, path2: import("svg-path-commander").curveArray, TL: number): import("svg-path-commander").curveArray[]; - import reverseCurve from "svg-path-commander/src/process/reverseCurve"; - import clonePath from "svg-path-commander/src/process/clonePath"; - import getDrawDirection from "svg-path-commander/src/util/getDrawDirection"; - import segmentCubicFactory from "svg-path-commander/src/util/segmentCubicFactory"; - import splitCubic from "svg-path-commander/src/process/splitCubic"; - import splitPath from "svg-path-commander/src/process/splitPath"; - import fixPath from "svg-path-commander/src/process/fixPath"; - /** - * Returns first `pathArray` from multi-paths path. - * @param {SVGPathCommander.pathArray | string} source the source `pathArray` or string - * @returns {KUTE.curveSpecs[]} an `Array` with a custom tuple for `equalizeSegments` - */ - function getCurveArray(source: import("svg-path-commander").pathArray | string): KUTE.curveSpecs[]; - /** - * Returns the current `d` attribute value. - * @returns {string} - */ - function getCubicMorph(): string; - /** - * Returns the property tween object. - * @see KUTE.curveObject - * - * @param {string} _ is the `path` property name, not needed - * @param {string | KUTE.curveObject} value the `path` property value - * @returns {KUTE.curveObject} - */ - function prepareCubicMorph(_: string, value: string | KUTE.curveObject): KUTE.curveObject; - import { onStartCubicMorph } from "kute.js/src/components/svgCubicMorphBase"; - /** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} tweenProp is `path` tween property, but it's not needed - */ - function crossCheckCubicMorph(tweenProp: string): void; -} -declare module "kute.js/src/components/svgDrawBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartDraw(tweenProp: string): void; - export default SvgDrawBase; - namespace SvgDrawBase { - const component: string; - const property: string; - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartDraw as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/svgDraw" { - export default SvgDrawProperty; - namespace SvgDrawProperty { - export const component: string; - export const property: string; - export const defaultValue: string; - export namespace Interpolate { - export { numbers }; - } - export { svgDrawFunctions as functions }; - export namespace Util { - export { getRectLength }; - export { getPolyLength }; - export { getLineLength }; - export { getCircleLength }; - export { getEllipseLength }; - export { getTotalLength }; - export { resetDraw }; - export { getDraw }; - export { percent }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; - namespace svgDrawFunctions { - export { getDrawValue as prepareStart }; - export { prepareDraw as prepareProperty }; - export { onStartDraw as onStart }; - } - /** - * Returns the `` length. - * It doesn't compute `rx` and / or `ry` of the element. - * @see http://stackoverflow.com/a/30376660 - * @param {SVGRectElement} el target element - * @returns {number} the `` length - */ - function getRectLength(el: SVGRectElement): number; - /** - * Returns the `` / `` length. - * @param {SVGPolylineElement | SVGPolygonElement} el target element - * @returns {number} the element length - */ - function getPolyLength(el: SVGPolylineElement | SVGPolygonElement): number; - /** - * Returns the `` length. - * @param {SVGLineElement} el target element - * @returns {number} the element length - */ - function getLineLength(el: SVGLineElement): number; - /** - * Returns the `` length. - * @param {SVGCircleElement} el target element - * @returns {number} the element length - */ - function getCircleLength(el: SVGCircleElement): number; - /** - * Returns the `` length. - * @param {SVGEllipseElement} el target element - * @returns {number} the element length - */ - function getEllipseLength(el: SVGEllipseElement): number; - /** - * Returns the shape length. - * @param {SVGPathCommander.shapeTypes} el target element - * @returns {number} the element length - */ - function getTotalLength(el: SVGPathCommander.shapeTypes): number; - /** - * Reset CSS properties associated with the `draw` property. - * @param {SVGPathCommander.shapeTypes} element target - */ - function resetDraw(elem: any): void; - /** - * Returns the property tween object. - * @param {SVGPathCommander.shapeTypes} element the target element - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function getDraw(element: SVGPathCommander.shapeTypes, value: string | KUTE.drawObject): KUTE.drawObject; - /** - * Convert a `` length percent value to absolute. - * @param {string} v raw value - * @param {number} l length value - * @returns {number} the absolute value - */ - function percent(v: string, l: number): number; - /** - * Returns the property tween object. - * @returns {KUTE.drawObject} the property tween object - */ - function getDrawValue(): KUTE.drawObject; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.drawObject} value the property value - * @returns {KUTE.drawObject} the property tween object - */ - function prepareDraw(_: string, value: string | KUTE.drawObject): KUTE.drawObject; - import { onStartDraw } from "kute.js/src/components/svgDrawBase"; -} -declare module "kute.js/src/interpolation/coords" { - /** - * Coordinates Interpolation Function. - * - * @param {number[][]} a start coordinates - * @param {number[][]} b end coordinates - * @param {string} l amount of coordinates - * @param {number} v progress - * @returns {number[][]} the interpolated coordinates - */ - export default function coords(a: number[][], b: number[][], l: string, v: number): number[][]; -} -declare module "kute.js/src/components/svgMorphBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartSVGMorph(tweenProp: string): void; - export default SVGMorphBase; - namespace SVGMorphBase { - export const component: string; - export const property: string; - export { coords as Interpolate }; - export namespace functions { - export { onStartSVGMorph as onStart }; - } - } - import coords from "kute.js/src/interpolation/coords"; -} -declare module "kute.js/src/components/svgMorph" { - export default SVGMorph; - namespace SVGMorph { - export const component: string; - export const property: string; - export const defaultValue: never[]; - export { coords as Interpolate }; - export namespace defaultOptions { - const morphPrecision: number; - } - export { svgMorphFunctions as functions }; - export namespace Util { - export { addPoints }; - export { bisect }; - export { getPolygon }; - export { validPolygon }; - export { getInterpolationPoints }; - export { pathStringToPolygon }; - export { distanceSquareRoot }; - export { midPoint }; - export { approximatePolygon }; - export { rotatePolygon }; - export { pathToString }; - export { pathToCurve }; - export { getTotalLength }; - export { getPointAtLength }; - export { polygonArea }; - export { roundPath }; - } - } - import coords from "kute.js/src/interpolation/coords"; - namespace svgMorphFunctions { - export { getSVGMorph as prepareStart }; - export { prepareSVGMorph as prepareProperty }; - export { onStartSVGMorph as onStart }; - export { crossCheckSVGMorph as crossCheck }; - } - /** - * Sample additional points for a polygon to better match its pair. - * @param {KUTE.polygonObject} polygon the target polygon - * @param {number} numPoints the amount of points needed - */ - function addPoints(polygon: KUTE.polygonObject, numPoints: number): void; - /** - * Split segments of a polygon until it reaches a certain - * amount of points. - * @param {number[][]} polygon the target polygon - * @param {number} maxSegmentLength the maximum amount of points - */ - function bisect(polygon: number[][], maxSegmentLength?: number): void; - /** - * Returns a new polygon and its length from string or another `Array`. - * @param {KUTE.polygonMorph | string} input the target polygon - * @param {number} maxSegmentLength the maximum amount of points - * @returns {KUTE.polygonMorph} normalized polygon - */ - function getPolygon(input: import("kute.js/types").polygonMorph | string, maxSegmentLength: number): import("kute.js/types").polygonMorph; - /** - * Checks the validity of a polygon. - * @param {KUTE.polygonMorph} polygon the target polygon - * @returns {boolean} the result of the check - */ - function validPolygon(polygon: import("kute.js/types").polygonMorph): boolean; - /** - * Returns two new polygons ready to tween. - * @param {string} path1 the first path string - * @param {string} path2 the second path string - * @param {number} precision the morphPrecision option value - * @returns {KUTE.polygonMorph[]} the two polygons - */ - function getInterpolationPoints(path1: string, path2: string, precision: number): import("kute.js/types").polygonMorph[]; - /** - * Parses a path string and returns a polygon array. - * @param {string} str path string - * @param {number} maxLength maximum amount of points - * @returns {KUTE.exactPolygon} the polygon array we need - */ - function pathStringToPolygon(str: string, maxLength: number): KUTE.exactPolygon; - import distanceSquareRoot from "svg-path-commander/src/math/distanceSquareRoot"; - import midPoint from "svg-path-commander/src/math/midPoint"; - /** - * Returns a new polygon polygon. - * @param {SVGPathCommander.pathArray} parsed target `pathArray` - * @param {number} maxLength the maximum segment length - * @returns {KUTE.exactPolygon} the resulted polygon - */ - function approximatePolygon(parsed: import("svg-path-commander").pathArray, maxLength: number): KUTE.exactPolygon; - /** - * Rotates a polygon to better match its pair. - * @param {KUTE.polygonMorph} polygon the target polygon - * @param {KUTE.polygonMorph} vs the reference polygon - */ - function rotatePolygon(polygon: import("kute.js/types").polygonMorph, vs: import("kute.js/types").polygonMorph): void; - import pathToString from "svg-path-commander/src/convert/pathToString"; - import pathToCurve from "svg-path-commander/src/convert/pathToCurve"; - import getTotalLength from "svg-path-commander/src/util/getTotalLength"; - import getPointAtLength from "svg-path-commander/src/util/getPointAtLength"; - import polygonArea from "svg-path-commander/src/math/polygonArea"; - import roundPath from "svg-path-commander/src/process/roundPath"; - /** - * Returns the current `d` attribute value. - * @returns {string} the `d` attribute value - */ - function getSVGMorph(): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string | KUTE.polygonObject} value the property value - * @returns {KUTE.polygonObject} the property tween object - */ - function prepareSVGMorph(_: string, value: string | KUTE.polygonObject): KUTE.polygonObject; - import { onStartSVGMorph } from "kute.js/src/components/svgMorphBase"; - /** - * Enables the `to()` method by preparing the tween object in advance. - * @param {string} prop the `path` property name - */ - function crossCheckSVGMorph(prop: string): void; - /** - * Returns an existing polygon or false if it's not a polygon. - * @param {SVGPathCommander.pathArray} pathArray target `pathArray` - * @returns {KUTE.exactPolygon | false} the resulted polygon - */ - function exactPolygon(pathArray: import("svg-path-commander").pathArray): KUTE.exactPolygon | false; -} -declare module "kute.js/src/components/svgTransformBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function svgTransformOnStart(tweenProp: string): void; - export default baseSVGTransform; - namespace baseSVGTransform { - const component: string; - const property: string; - namespace defaultOptions { - const transformOrigin: string; - } - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { svgTransformOnStart as onStart }; - } - } - import numbers from "kute.js/src/interpolation/numbers"; -} -declare module "kute.js/src/components/svgTransform" { - export namespace svgTransformFunctions { - export { getStartSvgTransform as prepareStart }; - export { prepareSvgTransform as prepareProperty }; - export { svgTransformOnStart as onStart }; - export { svgTransformCrossCheck as crossCheck }; - } - export namespace svgTransform { - export const component: string; - export const property: string; - export namespace defaultOptions { - const transformOrigin: string; - } - export namespace defaultValue { - const translate: number; - const rotate: number; - const skewX: number; - const skewY: number; - const scale: number; - } - export namespace Interpolate { - export { numbers }; - } - export { svgTransformFunctions as functions }; - export namespace Util { - export { parseStringOrigin }; - export { parseTransformString }; - export { parseTransformSVG }; - } - } - export default svgTransform; - /** - * Returns an object with the current transform attribute value. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {string} current transform object - */ - function getStartSvgTransform(_: string, value: string): string; - /** - * Returns the property tween object. - * @param {string} prop the property name - * @param {string} value the property value - * @returns {KUTE.transformSVGObject} the property tween object - */ - function prepareSvgTransform(prop: string, value: string): KUTE.transformSVGObject; - import { svgTransformOnStart } from "kute.js/src/components/svgTransformBase"; - function svgTransformCrossCheck(prop: any): void; - import numbers from "kute.js/src/interpolation/numbers"; - /** - * Returns a correct transform origin consistent with the shape bounding box. - * @param {string} origin transform origin string - * @param {SVGPathCommander.pathBBox} bbox path bounding box - * @returns {number} - */ - function parseStringOrigin(origin: string, bbox: SVGPathCommander.pathBBox): number; - /** - * Parse SVG transform string and return an object. - * @param {string} a transform string - * @returns {Object} - */ - function parseTransformString(a: string): { - [x: string]: (string | number); - }; - /** - * Returns the SVG transform tween object. - * @param {string} _ property name - * @param {Object} v property value object - * @returns {KUTE.transformSVGObject} the SVG transform tween object - */ - function parseTransformSVG(_: string, v: { - [x: string]: (string | number); - }): KUTE.transformSVGObject; -} -declare module "kute.js/src/components/textPropertiesBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function textPropOnStart(tweenProp: string): void; - export default TextPropertiesBase; - namespace TextPropertiesBase { - const component: string; - const category: string; - namespace Interpolate { - export { units }; - } - namespace functions { - export { textOnStart as onStart }; - } - } - import units from "kute.js/src/interpolation/units"; - const textOnStart: {}; -} -declare module "kute.js/src/components/textProperties" { - /** - * Returns the current property computed style. - * @param {string} prop the property name - * @returns {string} computed style for property - */ - export function getTextProp(prop: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {number} the property tween object - */ - export function prepareTextProp(_: string, value: string): number; - export default TextProperties; - namespace TextProperties { - export const component: string; - export const category: string; - export { textProps as properties }; - export namespace defaultValues { - const fontSize: number; - const lineHeight: number; - const letterSpacing: number; - const wordSpacing: number; - } - export namespace Interpolate { - export { units }; - } - export { textPropFunctions as functions }; - export namespace Util { - export { trueDimension }; - } - } - const textProps: string[]; - import units from "kute.js/src/interpolation/units"; - namespace textPropFunctions { - export { getTextProp as prepareStart }; - export { prepareTextProp as prepareProperty }; - export { textOnStart as onStart }; - } - import trueDimension from "kute.js/src/util/trueDimension"; - const textOnStart: {}; -} -declare module "kute.js/src/objects/connect" { - export default connect; - namespace connect { - const tween: KUTE.TweenBase | KUTE.Tween | KUTE.TweenExtra; - const processEasing: any; - } -} -declare module "kute.js/src/components/textWriteBase" { - export namespace onStartWrite { - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function text(tweenProp: string): void; - /** - * onStartWrite.text - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function text(tweenProp: string): void; - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function number(tweenProp: string): void; - /** - * onStartWrite.number - * - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function number(tweenProp: string): void; - } - export namespace TextWriteBase { - const component: string; - const category: string; - namespace defaultOptions { - const textChars: string; - } - namespace Interpolate { - export { numbers }; - } - namespace functions { - export { onStartWrite as onStart }; - } - namespace Util { - export { charSet }; - } - } - export default TextWriteBase; - export namespace charSet { - export { lowerCaseAlpha as alpha }; - export { upperCaseAlpha as upper }; - export { nonAlpha as symbols }; - export { numeric }; - export { alphaNumeric as alphanumeric }; - export { allTypes as all }; - } - import numbers from "kute.js/src/interpolation/numbers"; - const lowerCaseAlpha: string[]; - const upperCaseAlpha: string[]; - const nonAlpha: string[]; - const numeric: string[]; - const alphaNumeric: string[]; - const allTypes: string[]; -} -declare module "kute.js/src/components/textWrite" { - export function createTextTweens(target: any, newText: any, ops: any): false | any[]; - export namespace textWriteFunctions { - export { getWrite as prepareStart }; - export { prepareText as prepareProperty }; - export { onStartWrite as onStart }; - } - export namespace TextWrite { - export const component: string; - export const category: string; - export const properties: string[]; - export namespace defaultValues { - const text: string; - const number: string; - } - export namespace defaultOptions { - const textChars: string; - } - export namespace Interpolate { - export { numbers }; - } - export { textWriteFunctions as functions }; - export namespace Util { - export { charSet }; - export { createTextTweens }; - } - } - export default TextWrite; - /** - * Returns the current element `innerHTML`. - * @returns {string} computed style for property - */ - function getWrite(): string; - /** - * Returns the property tween object. - * @param {string} tweenProp the property name - * @param {string} value the property value - * @returns {number | string} the property tween object - */ - function prepareText(tweenProp: string, value: string): number | string; - import { onStartWrite } from "kute.js/src/components/textWriteBase"; - import numbers from "kute.js/src/interpolation/numbers"; - import { charSet } from "kute.js/src/components/textWriteBase"; -} -declare module "kute.js/src/interpolation/perspective" { - /** - * Perspective Interpolation Function. - * - * @param {number} a start value - * @param {number} b end value - * @param {string} u unit - * @param {number} v progress - * @returns {string} the perspective function in string format - */ - export default function perspective(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/interpolation/translate3d" { - /** - * Translate 3D Interpolation Function. - * - * @param {number[]} a start [x,y,z] position - * @param {number[]} b end [x,y,z] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D translation string - */ - export default function translate3d(a: number[], b: number[], u: string, v: number): string; -} -declare module "kute.js/src/interpolation/rotate3d" { - /** - * 3D Rotation Interpolation Function. - * - * @param {number} a start [x,y,z] angles - * @param {number} b end [x,y,z] angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated 3D rotation string - */ - export default function rotate3d(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/interpolation/translate" { - /** - * Translate 2D Interpolation Function. - * - * @param {number[]} a start [x,y] position - * @param {number[]} b end [x,y] position - * @param {string} u unit, usually `px` degrees - * @param {number} v progress - * @returns {string} the interpolated 2D translation string - */ - export default function translate(a: number[], b: number[], u: string, v: number): string; -} -declare module "kute.js/src/interpolation/rotate" { - /** - * 2D Rotation Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated rotation - */ - export default function rotate(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/interpolation/scale" { - /** - * Scale Interpolation Function. - * - * @param {number} a start scale - * @param {number} b end scale - * @param {number} v progress - * @returns {string} the interpolated scale - */ - export default function scale(a: number, b: number, v: number): string; -} -declare module "kute.js/src/interpolation/skew" { - /** - * Skew Interpolation Function. - * - * @param {number} a start {x,y} angles - * @param {number} b end {x,y} angles - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated string value of skew(s) - */ - export default function skew(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/components/transformFunctionsBase" { - /** - * Sets the property update function. - * * same to svgTransform, htmlAttributes - * @param {string} tweenProp the property name - */ - export function onStartTransform(tweenProp: string): void; - export default TransformFunctionsBase; - namespace TransformFunctionsBase { - const component: string; - const property: string; - namespace functions { - export { onStartTransform as onStart }; - } - namespace Interpolate { - export { perspective }; - export { translate3d }; - export { rotate3d }; - export { translate }; - export { rotate }; - export { scale }; - export { skew }; - } - } - import perspective from "kute.js/src/interpolation/perspective"; - import translate3d from "kute.js/src/interpolation/translate3d"; - import rotate3d from "kute.js/src/interpolation/rotate3d"; - import translate from "kute.js/src/interpolation/translate"; - import rotate from "kute.js/src/interpolation/rotate"; - import scale from "kute.js/src/interpolation/scale"; - import skew from "kute.js/src/interpolation/skew"; -} -declare module "kute.js/src/components/transformFunctions" { - export default TransformFunctions; - namespace TransformFunctions { - export const component: string; - export const property: string; - export { supportedTransformProperties as subProperties }; - export { defaultTransformValues as defaultValues }; - export { transformFunctions as functions }; - export namespace Interpolate { - export { perspective }; - export { translate3d }; - export { rotate3d }; - export { translate }; - export { rotate }; - export { scale }; - export { skew }; - } - } - const supportedTransformProperties: string[]; - namespace defaultTransformValues { - const perspective_1: number; - export { perspective_1 as perspective }; - const translate3d_1: number[]; - export { translate3d_1 as translate3d }; - export const translateX: number; - export const translateY: number; - export const translateZ: number; - const translate_1: number[]; - export { translate_1 as translate }; - const rotate3d_1: number[]; - export { rotate3d_1 as rotate3d }; - export const rotateX: number; - export const rotateY: number; - export const rotateZ: number; - const rotate_1: number; - export { rotate_1 as rotate }; - export const skewX: number; - export const skewY: number; - const skew_1: number[]; - export { skew_1 as skew }; - const scale_1: number; - export { scale_1 as scale }; - } - namespace transformFunctions { - export { getTransform as prepareStart }; - export { prepareTransform as prepareProperty }; - export { onStartTransform as onStart }; - export { crossCheckTransform as crossCheck }; - } - import perspective from "kute.js/src/interpolation/perspective"; - import translate3d from "kute.js/src/interpolation/translate3d"; - import rotate3d from "kute.js/src/interpolation/rotate3d"; - import translate from "kute.js/src/interpolation/translate"; - import rotate from "kute.js/src/interpolation/rotate"; - import scale from "kute.js/src/interpolation/scale"; - import skew from "kute.js/src/interpolation/skew"; - /** - * Returns the current property inline style. - * @param {string} tweenProp the property name - * @returns {string} inline style for property - */ - function getTransform(tweenProp: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ - function prepareTransform(_: string, obj: { - [x: string]: string | number | (string | number)[]; - }): KUTE.transformFObject; - import { onStartTransform } from "kute.js/src/components/transformFunctionsBase"; - /** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ - function crossCheckTransform(tweenProp: string): void; -} -declare module "kute.js/src/util/transformProperty" { - export default transformProperty; - /** the `transform` string for legacy browsers */ - const transformProperty: string; -} -declare module "kute.js/src/process/getInlineStyleLegacy" { - /** - * getInlineStyle - * - * Returns the transform style for element from cssText. - * Used by for the `.to()` static method on legacy browsers. - * - * @param {Element} el target element - * @returns {object} a transform object - */ - export default function getInlineStyleLegacy(el: Element): object; -} -declare module "kute.js/src/util/supportLegacyTransform" { - export default supportTransform; - /** check if transform is supported via prefixed property */ - const supportTransform: boolean; -} -declare module "kute.js/src/components/transformLegacyBase" { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - export function onStartLegacyTransform(tweenProp: string): void; - export default BaseLegacyTransform; - namespace BaseLegacyTransform { - const component: string; - const property: string; - namespace functions { - export { onStartLegacyTransform as onStart }; - } - namespace Interpolate { - export { perspective }; - export { translate3d }; - export { rotate3d }; - export { translate }; - export { rotate }; - export { scale }; - export { skew }; - } - namespace Util { - export { transformProperty }; - } - } - import perspective from "kute.js/src/interpolation/perspective"; - import translate3d from "kute.js/src/interpolation/translate3d"; - import rotate3d from "kute.js/src/interpolation/rotate3d"; - import translate from "kute.js/src/interpolation/translate"; - import rotate from "kute.js/src/interpolation/rotate"; - import scale from "kute.js/src/interpolation/scale"; - import skew from "kute.js/src/interpolation/skew"; - import transformProperty from "kute.js/src/util/transformProperty"; -} -declare module "kute.js/src/components/transformLegacy" { - export default transformLegacyComponent; - namespace transformLegacyComponent { - export const component: string; - export const property: string; - export { legacyTransformProperties as subProperties }; - export { legacyTransformValues as defaultValues }; - export { transformLegacyFunctions as functions }; - export namespace Interpolate { - export { perspective }; - export { translate3d }; - export { rotate3d }; - export { translate }; - export { rotate }; - export { scale }; - export { skew }; - } - export const Util: string[]; - } - const legacyTransformProperties: string[]; - namespace legacyTransformValues { - const perspective_1: number; - export { perspective_1 as perspective }; - const translate3d_1: number[]; - export { translate3d_1 as translate3d }; - export const translateX: number; - export const translateY: number; - export const translateZ: number; - const translate_1: number[]; - export { translate_1 as translate }; - const rotate3d_1: number[]; - export { rotate3d_1 as rotate3d }; - export const rotateX: number; - export const rotateY: number; - export const rotateZ: number; - const rotate_1: number; - export { rotate_1 as rotate }; - export const skewX: number; - export const skewY: number; - const skew_1: number[]; - export { skew_1 as skew }; - const scale_1: number; - export { scale_1 as scale }; - } - namespace transformLegacyFunctions { - export { getLegacyTransform as prepareStart }; - export { prepareLegacyTransform as prepareProperty }; - export { onStartLegacyTransform as onStart }; - export { crossCheckLegacyTransform as crossCheck }; - } - import perspective from "kute.js/src/interpolation/perspective"; - import translate3d from "kute.js/src/interpolation/translate3d"; - import rotate3d from "kute.js/src/interpolation/rotate3d"; - import translate from "kute.js/src/interpolation/translate"; - import rotate from "kute.js/src/interpolation/rotate"; - import scale from "kute.js/src/interpolation/scale"; - import skew from "kute.js/src/interpolation/skew"; - /** - * Returns the current property inline style. - * @param {string} tweenProperty the property name - * @returns {string} inline style for property - */ - function getLegacyTransform(tweenProperty: string): string; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformFObject} the property tween object - */ - function prepareLegacyTransform(_: string, obj: { - [x: string]: string | number | (string | number)[]; - }): KUTE.transformFObject; - import { onStartLegacyTransform } from "kute.js/src/components/transformLegacyBase"; - /** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ - function crossCheckLegacyTransform(tweenProp: string): void; -} -declare module "kute.js/src/interpolation/arrays" { - /** - * Array Interpolation Function. - * - * @param {number[]} a start array - * @param {number[]} b end array - * @param {number} v progress - * @returns {number[]} the resulting array - */ - export default function arrays(a: number[], b: number[], v: number): number[]; -} -declare module "kute.js/src/components/transformMatrixBase" { - export namespace onStartTransform { - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function transform(tweenProp: string): void; - /** - * Sets the property update function. - * @param {string} tweenProp the property name - */ - function transform(tweenProp: string): void; - /** - * onStartTransform.CSS3Matrix - * - * Sets the update function for the property. - * @param {string} prop the property name - */ - function CSS3Matrix(prop: string): void; - /** - * onStartTransform.CSS3Matrix - * - * Sets the update function for the property. - * @param {string} prop the property name - */ - function CSS3Matrix(prop: string): void; - } - export namespace TransformMatrixBase { - export { matrixComponent as component }; - export const property: string; - export namespace functions { - export { onStartTransform as onStart }; - } - export namespace Interpolate { - export { numbers as perspective }; - export { arrays as translate3d }; - export { arrays as rotate3d }; - export { arrays as skew }; - export { arrays as scale3d }; - } - } - export default TransformMatrixBase; - const matrixComponent: "transformMatrixBase"; - import numbers from "kute.js/src/interpolation/numbers"; - import arrays from "kute.js/src/interpolation/arrays"; -} -declare module "kute.js/src/components/transformMatrix" { - export default matrixTransform; - namespace matrixTransform { - export { matrixComponent as component }; - export const property: string; - export namespace defaultValue { - const perspective: number; - const translate3d: number[]; - const translateX: number; - const translateY: number; - const translateZ: number; - const rotate3d: number[]; - const rotateX: number; - const rotateY: number; - const rotateZ: number; - const skew: number[]; - const skewX: number; - const skewY: number; - const scale3d: number[]; - const scaleX: number; - const scaleY: number; - const scaleZ: number; - } - export { matrixFunctions as functions }; - export namespace Interpolate { - export { numbers as perspective }; - export { arrays as translate3d }; - export { arrays as rotate3d }; - export { arrays as skew }; - export { arrays as scale3d }; - } - } - const matrixComponent: "transformMatrix"; - namespace matrixFunctions { - export { getTransform as prepareStart }; - export { prepareTransform as prepareProperty }; - export { onStartTransform as onStart }; - export { onCompleteTransform as onComplete }; - export { crossCheckTransform as crossCheck }; - } - import numbers from "kute.js/src/interpolation/numbers"; - import arrays from "kute.js/src/interpolation/arrays"; - /** - * Returns the current transform object. - * @param {string} _ the property name - * @param {string} value the property value - * @returns {KUTE.transformMObject} transform object - */ - function getTransform(_: string, value: string): KUTE.transformMObject; - /** - * Returns the property tween object. - * @param {string} _ the property name - * @param {Object} obj the property value - * @returns {KUTE.transformMObject} the property tween object - */ - function prepareTransform(_: string, value: any): KUTE.transformMObject; - import { onStartTransform } from "kute.js/src/components/transformMatrixBase"; - /** - * Sets the end values for the next `to()` method call. - * @param {string} tweenProp the property name - */ - function onCompleteTransform(tweenProp: string): void; - /** - * Prepare tween object in advance for `to()` method. - * @param {string} tweenProp the property name - */ - function crossCheckTransform(tweenProp: string): void; -} -declare module "kute.js/src/objects/tweens" { - export default Tweens; - const Tweens: any[]; -} -declare module "kute.js/src/core/add" { - export default add; - /** - * KUTE.add(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - function add(tw: KUTE.Tween): number; -} -declare module "kute.js/src/core/getAll" { - export default getAll; - /** - * KUTE.add(Tween) - * - * @return {KUTE.Tween[]} tw a new tween to add - */ - function getAll(): KUTE.Tween[]; -} -declare module "kute.js/src/core/remove" { - export default remove; - /** - * KUTE.remove(Tween) - * - * @param {KUTE.Tween} tw a new tween to add - */ - function remove(tw: KUTE.Tween): void; -} -declare module "kute.js/src/core/removeAll" { - export default removeAll; - /** - * KUTE.removeAll() - */ - function removeAll(): void; -} -declare module "kute.js/src/objects/globalObject" { - export default globalObject; - const globalObject: {}; -} -declare module "kute.js/src/util/now" { - export default now; - function now(): number; -} -declare module "kute.js/src/core/render" { - export function stop(): void; - export default Render; - export let Tick: number; - /** - * - * @param {number | Date} time - */ - export function Ticker(time: number | Date): void; - namespace Render { - export { Tick }; - export { Ticker }; - export { Tweens }; - export { Time }; - } - import Tweens from "kute.js/src/objects/tweens"; - namespace Time { - export { now }; - } - import now from "kute.js/src/util/now"; -} -declare module "kute.js/src/core/linkInterpolation" { - /** - * linkInterpolation - * @this {KUTE.Tween} - */ - export default function linkInterpolation(): void; -} -declare module "kute.js/src/core/internals" { - export default internals; - namespace internals { - export { add }; - export { remove }; - export { getAll }; - export { removeAll }; - export { stop }; - export { linkInterpolation }; - } - import add from "kute.js/src/core/add"; - import remove from "kute.js/src/core/remove"; - import getAll from "kute.js/src/core/getAll"; - import removeAll from "kute.js/src/core/removeAll"; - import { stop } from "kute.js/src/core/render"; - import linkInterpolation from "kute.js/src/core/linkInterpolation"; -} -declare module "kute.js/src/core/queueStart" { - export default function queueStart(): void; -} -declare module "kute.js/src/easing/easing-base" { - export default Easing; - namespace Easing { - const linear: KUTE.easingFunction; - const easingQuadraticIn: KUTE.easingFunction; - const easingQuadraticOut: KUTE.easingFunction; - const easingQuadraticInOut: KUTE.easingFunction; - const easingCubicIn: KUTE.easingFunction; - const easingCubicOut: KUTE.easingFunction; - const easingCubicInOut: KUTE.easingFunction; - const easingCircularIn: KUTE.easingFunction; - const easingCircularOut: KUTE.easingFunction; - const easingCircularInOut: KUTE.easingFunction; - const easingBackIn: KUTE.easingFunction; - const easingBackOut: KUTE.easingFunction; - const easingBackInOut: KUTE.easingFunction; - } -} -declare module "kute.js/src/easing/easing-bezier" { - export default Easing; - namespace Easing { - const linear: CubicBezier; - const easingSinusoidalIn: CubicBezier; - const easingSinusoidalOut: CubicBezier; - const easingSinusoidalInOut: CubicBezier; - const easingQuadraticIn: CubicBezier; - const easingQuadraticOut: CubicBezier; - const easingQuadraticInOut: CubicBezier; - const easingCubicIn: CubicBezier; - const easingCubicOut: CubicBezier; - const easingCubicInOut: CubicBezier; - const easingQuarticIn: CubicBezier; - const easingQuarticOut: CubicBezier; - const easingQuarticInOut: CubicBezier; - const easingQuinticIn: CubicBezier; - const easingQuinticOut: CubicBezier; - const easingQuinticInOut: CubicBezier; - const easingExponentialIn: CubicBezier; - const easingExponentialOut: CubicBezier; - const easingExponentialInOut: CubicBezier; - const easingCircularIn: CubicBezier; - const easingCircularOut: CubicBezier; - const easingCircularInOut: CubicBezier; - const easingBackIn: CubicBezier; - const easingBackOut: CubicBezier; - const easingBackInOut: CubicBezier; - } - import CubicBezier from "cubic-bezier-easing"; -} -declare module "kute.js/src/easing/easing" { - export default Easing; - namespace Easing { - const linear: KUTE.easingFunction; - const easingSinusoidalIn: KUTE.easingFunction; - const easingSinusoidalOut: KUTE.easingFunction; - const easingSinusoidalInOut: KUTE.easingFunction; - const easingQuadraticIn: KUTE.easingFunction; - const easingQuadraticOut: KUTE.easingFunction; - const easingQuadraticInOut: KUTE.easingFunction; - const easingCubicIn: KUTE.easingFunction; - const easingCubicOut: KUTE.easingFunction; - const easingCubicInOut: KUTE.easingFunction; - const easingQuarticIn: KUTE.easingFunction; - const easingQuarticOut: KUTE.easingFunction; - const easingQuarticInOut: KUTE.easingFunction; - const easingQuinticIn: KUTE.easingFunction; - const easingQuinticOut: KUTE.easingFunction; - const easingQuinticInOut: KUTE.easingFunction; - const easingCircularIn: KUTE.easingFunction; - const easingCircularOut: KUTE.easingFunction; - const easingCircularInOut: KUTE.easingFunction; - const easingExponentialIn: KUTE.easingFunction; - const easingExponentialOut: KUTE.easingFunction; - const easingExponentialInOut: KUTE.easingFunction; - const easingBackIn: KUTE.easingFunction; - const easingBackOut: KUTE.easingFunction; - const easingBackInOut: KUTE.easingFunction; - const easingElasticIn: KUTE.easingFunction; - const easingElasticOut: KUTE.easingFunction; - const easingElasticInOut: KUTE.easingFunction; - const easingBounceIn: KUTE.easingFunction; - const easingBounceOut: KUTE.easingFunction; - const easingBounceInOut: KUTE.easingFunction; - } -} -declare module "kute.js/src/tween/tweenCollection" { - /** - * The static method creates a new `Tween` object for each `HTMLElement` - * from and `Array`, `HTMLCollection` or `NodeList`. - */ - export default class TweenCollection { - /** - * - * @param {Element[] | HTMLCollection | NodeList} els target elements - * @param {KUTE.tweenProps} vS the start values - * @param {KUTE.tweenProps} vE the end values - * @param {KUTE.tweenOptions} Options tween options - * @returns {TweenCollection} the Tween object collection - */ - constructor(els: Element[] | HTMLCollection | NodeList, vS: import("kute.js/types").tweenProps, vE: import("kute.js/types").tweenProps, Options: KUTE.tweenOptions); - /** @type {KUTE.twCollection[]} */ - tweens: import("kute.js/types").twCollection[]; - /** @type {number?} */ - length: number | null; - /** - * Starts tweening, all targets - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - start(time: number | null): TweenCollection; - /** - * Stops tweening, all targets and their chains - * @returns {TweenCollection} this instance - */ - stop(): TweenCollection; - /** - * Pause tweening, all targets - * @returns {TweenCollection} this instance - */ - pause(): TweenCollection; - /** - * Resume tweening, all targets - * @returns {TweenCollection} this instance - */ - resume(): TweenCollection; - /** - * Schedule another tween or collection to start after - * this one is complete. - * @param {number?} args the tween start time - * @returns {TweenCollection} this instance - */ - chain(args: number | null): TweenCollection; - /** - * Check if any tween instance is playing - * @param {number?} time the tween start time - * @returns {TweenCollection} this instance - */ - playing(): TweenCollection; - /** - * Remove all tweens in the collection - */ - removeTweens(): void; - /** - * Returns the maximum animation duration - * @returns {number} this instance - */ - getMaxDuration(): number; - } -} -declare module "kute.js/src/interface/allFromTo" { - /** - * The `KUTE.allFromTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at a given state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {TweenCollection} the Tween object collection - */ - export default function allFromTo(elements: Element[] | HTMLCollection | NodeList, startObject: import("kute.js/types").tweenProps, endObject: import("kute.js/types").tweenProps, optionsObj: KUTE.tweenOptions): TweenCollection; - import TweenCollection from "kute.js/src/tween/tweenCollection"; -} -declare module "kute.js/src/interface/allTo" { - /** - * The `KUTE.allTo()` static method creates a new Tween object - * for multiple `HTMLElement`s, `HTMLCollection` or `NodeListat` - * at their current state. - * - * @param {Element[] | HTMLCollection | NodeList} elements target elements - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenProps} optionsObj progress - * @returns {TweenCollection} the Tween object collection - */ - export default function allTo(elements: Element[] | HTMLCollection | NodeList, endObject: import("kute.js/types").tweenProps, optionsObj: import("kute.js/types").tweenProps): TweenCollection; - import TweenCollection from "kute.js/src/tween/tweenCollection"; -} -declare module "kute.js/src/interface/fromTo" { - /** - * The `KUTE.fromTo()` static method returns a new Tween object - * for a single `HTMLElement` at a given state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} startObject - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - export default function fromTo(element: Element, startObject: import("kute.js/types").tweenProps, endObject: import("kute.js/types").tweenProps, optionsObj: KUTE.tweenOptions): KUTE.Tween; -} -declare module "kute.js/src/interface/to" { - /** - * The `KUTE.to()` static method returns a new Tween object - * for a single `HTMLElement` at its current state. - * - * @param {Element} element target element - * @param {KUTE.tweenProps} endObject - * @param {KUTE.tweenOptions} optionsObj tween options - * @returns {KUTE.Tween} the resulting Tween object - */ - export default function to(element: Element, endObject: import("kute.js/types").tweenProps, optionsObj: KUTE.tweenOptions): KUTE.Tween; -} -declare module "kute.js/src/interpolation/skewX" { - /** - * SkewX Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated skewX - */ - export default function skewX(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/interpolation/skewY" { - /** - * SkewY Interpolation Function. - * - * @param {number} a start angle - * @param {number} b end angle - * @param {string} u unit, usually `deg` degrees - * @param {number} v progress - * @returns {string} the interpolated skewY - */ - export default function skewY(a: number, b: number, u: string, v: number): string; -} -declare module "kute.js/src/objects/componentsBase" { - export default Components; - namespace Components { - const Transform: Animation; - const BoxModel: Animation; - const Opacity: Animation; - } - import Animation from "kute.js/src/animation/animationBase"; -} -declare module "kute.js/src/objects/componentsDefault" { - export default Components; - namespace Components { - export { EssentialBoxModel }; - export { ColorsProperties }; - export { HTMLAttributes }; - export { OpacityProperty }; - export { TextWriteProp }; - export { TransformFunctions }; - export { SVGDraw }; - export { SVGMorph }; - } - import EssentialBoxModel from "kute.js/src/components/boxModelEssential"; - import ColorsProperties from "kute.js/src/components/colorProperties"; - import HTMLAttributes from "kute.js/src/components/htmlAttributes"; - import OpacityProperty from "kute.js/src/components/opacityProperty"; - import TextWriteProp from "kute.js/src/components/textWrite"; - import TransformFunctions from "kute.js/src/components/transformFunctions"; - import SVGDraw from "kute.js/src/components/svgDraw"; - import SVGMorph from "kute.js/src/components/svgMorph"; -} -declare module "kute.js/src/objects/componentsExtra" { - export default Components; - namespace Components { - export { BackgroundPosition }; - export { BorderRadius }; - export { BoxModel }; - export { ClipProperty }; - export { ColorProperties }; - export { FilterEffects }; - export { HTMLAttributes }; - export { OpacityProperty }; - export { SVGDraw }; - export { SVGCubicMorph }; - export { SVGTransform }; - export { ScrollProperty }; - export { ShadowProperties }; - export { TextProperties }; - export { TextWriteProperties }; - export { MatrixTransform }; - } - import BackgroundPosition from "kute.js/src/components/backgroundPosition"; - import BorderRadius from "kute.js/src/components/borderRadius"; - import BoxModel from "kute.js/src/components/boxModel"; - import ClipProperty from "kute.js/src/components/clipProperty"; - import ColorProperties from "kute.js/src/components/colorProperties"; - import FilterEffects from "kute.js/src/components/filterEffects"; - import HTMLAttributes from "kute.js/src/components/htmlAttributes"; - import OpacityProperty from "kute.js/src/components/opacityProperty"; - import SVGDraw from "kute.js/src/components/svgDraw"; - import SVGCubicMorph from "kute.js/src/components/svgCubicMorph"; - import SVGTransform from "kute.js/src/components/svgTransform"; - import ScrollProperty from "kute.js/src/components/scrollProperty"; - import ShadowProperties from "kute.js/src/components/shadowProperties"; - import TextProperties from "kute.js/src/components/textProperties"; - import TextWriteProperties from "kute.js/src/components/textWrite"; - import MatrixTransform from "kute.js/src/components/transformMatrix"; -} -declare module "kute.js/src/objects/objects" { - export default Objects; - namespace Objects { - export { supportedProperties }; - export { defaultValues }; - export { defaultOptions }; - export { prepareProperty }; - export { prepareStart }; - export { crossCheck }; - export { onStart }; - export { onComplete }; - export { linkProperty }; - } - import supportedProperties from "kute.js/src/objects/supportedProperties"; - import defaultValues from "kute.js/src/objects/defaultValues"; - import defaultOptions from "kute.js/src/objects/defaultOptions"; - import prepareProperty from "kute.js/src/objects/prepareProperty"; - import prepareStart from "kute.js/src/objects/prepareStart"; - import crossCheck from "kute.js/src/objects/crossCheck"; - import onStart from "kute.js/src/objects/onStart"; - import onComplete from "kute.js/src/objects/onComplete"; - import linkProperty from "kute.js/src/objects/linkProperty"; -} -declare module "kute.js/src/objects/objectsBase" { - export default Objects; - namespace Objects { - export { defaultOptions }; - export { linkProperty }; - export { onStart }; - export { onComplete }; - } - import defaultOptions from "kute.js/src/objects/defaultOptions"; - import linkProperty from "kute.js/src/objects/linkProperty"; - import onStart from "kute.js/src/objects/onStart"; - import onComplete from "kute.js/src/objects/onComplete"; -} -declare module "kute.js/src/process/prepareObject" { - /** - * prepareObject - * - * Returns all processed valuesStart / valuesEnd. - * - * @param {Element} obj the values start/end object - * @param {string} fn toggles between the two - */ - export default function prepareObject(obj: Element, fn: string): void; -} -declare module "kute.js/src/process/getStartValues" { - /** - * getStartValues - * - * Returns the start values for to() method. - * Used by for the `.to()` static method. - * - * @this {KUTE.Tween} the tween instance - */ - export default function getStartValues(): void; - export default class getStartValues { - valuesStart: {}; - } -} -declare module "kute.js/src/process/process" { - namespace _default { - export { getInlineStyle }; - export { getStyleForProperty }; - export { getStartValues }; - export { prepareObject }; - } - export default _default; - import getInlineStyle from "kute.js/src/process/getInlineStyle"; - import getStyleForProperty from "kute.js/src/process/getStyleForProperty"; - import getStartValues from "kute.js/src/process/getStartValues"; - import prepareObject from "kute.js/src/process/prepareObject"; -} -declare module "kute.js/src/tween/tweenBase" { - /** - * The `TweenBase` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * `TweenBase` is meant to be used with pre-processed values. - */ - export default class TweenBase { - /** - * @param {Element} targetElement the target element - * @param {KUTE.tweenProps} startObject the start values - * @param {KUTE.tweenProps} endObject the end values - * @param {KUTE.tweenOptions} opsObject the end values - * @returns {TweenBase} the resulting Tween object - */ - constructor(targetElement: Element, startObject: import("kute.js/types").tweenProps, endObject: import("kute.js/types").tweenProps, opsObject: KUTE.tweenOptions); - element: Element; - /** @type {boolean} */ - playing: boolean; - /** @type {number?} */ - _startTime: number | null; - /** @type {boolean} */ - _startFired: boolean; - valuesEnd: import("kute.js/types").tweenProps; - valuesStart: import("kute.js/types").tweenProps; - _resetStart: any; - /** @type {KUTE.easingOption} */ - _easing: KUTE.easingOption; - /** @type {number} */ - _duration: number; - /** @type {number} */ - _delay: number; - /** - * Starts tweening - * @param {number?} time the tween start time - * @returns {TweenBase} this instance - */ - start(time: number | null): TweenBase; - /** - * Stops tweening - * @returns {TweenBase} this instance - */ - stop(): TweenBase; - /** - * Trigger internal completion callbacks. - */ - close(): void; - /** - * Schedule another tween instance to start once this one completes. - * @param {KUTE.chainOption} args the tween animation start time - * @returns {TweenBase} this instance - */ - chain(args: KUTE.chainOption): TweenBase; - _chain: any; - /** - * Stop tweening the chained tween instances. - */ - stopChainedTweens(): void; - /** - * Update the tween on each tick. - * @param {number} time the tick time - * @returns {boolean} this instance - */ - update(time: number): boolean; - } -} -declare module "kute.js/src/tween/tween" { - /** - * The `KUTE.Tween()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor adds additional functionality and is the default - * Tween object constructor in KUTE.js. - */ - export default class Tween extends TweenBase { - /** @type {boolean} */ - paused: boolean; - /** @type {number?} */ - _pauseTime: number | null; - /** @type {number?} */ - _repeat: number | null; - /** @type {number?} */ - _repeatDelay: number | null; - /** @type {number?} */ - _repeatOption: number | null; - /** @type {KUTE.tweenProps} */ - valuesRepeat: import("kute.js/types").tweenProps; - /** @type {boolean} */ - _yoyo: boolean; - /** @type {boolean} */ - _reversed: boolean; - /** - * Resume tweening - * @returns {Tween} this instance - */ - resume(): Tween; - /** - * Pause tweening - * @returns {Tween} this instance - */ - pause(): Tween; - /** - * Reverses start values with end values - */ - reverse(): void; - } - import TweenBase from "kute.js/src/tween/tweenBase"; -} -declare module "kute.js/src/tween/tweenExtra" { - /** - * The `KUTE.TweenExtra()` constructor creates a new `Tween` object - * for a single `HTMLElement` and returns it. - * - * This constructor is intended for experiments or testing of new features. - */ - export default class TweenExtra extends Tween { - /** - * Method to add callbacks on the fly. - * @param {string} name callback name - * @param {Function} fn callback function - * @returns {TweenExtra} - */ - on(name: string, fn: Function): TweenExtra; - /** - * Method to set options on the fly. - * * accepting [repeat,yoyo,delay,repeatDelay,easing] - * - * @param {string} option the tick time - * @param {string | number | number[]} value the tick time - * @returns {TweenExtra} - */ - option(option: string, value: string | number | number[]): TweenExtra; - } - import Tween from "kute.js/src/tween/tween"; -} -declare module "kute.js/src/util/degToRad" { - export default degToRad; - /** - * degToRad - * - * Returns the value of a degree angle in radian. - * - * @param {number} a the degree angle - * @returns {number} the radian angle - */ - function degToRad(a: number): number; -} -declare module "kute.js/src/util/fromJSON" { - export default fromJSON; - /** - * fromJSON - * - * Returns the {valuesStart, valuesEnd} objects - * from a Tween instance. - * - * @param {string} str the JSON string - * @returns {JSON} the JSON object - */ - function fromJSON(str: string): JSON; -} -declare module "kute.js/src/util/progressBar" { - /** - * ProgressBar - * - * @class - * A progress bar utility for KUTE.js that will connect - * a target ``. with a Tween instance - * allowing it to control the progress of the Tween. - */ - export default class ProgressBar { - /** - * @constructor - * @param {HTMLElement} el target or string selector - * @param {KUTE.Tween} multi when true returns an array of elements - */ - constructor(element: any, tween: any); - element: HTMLInputElement; - updateBar(): void; - toggleEvents(action: any): void; - updateTween(): void; - moveAction(): void; - downAction(): void; - upAction(): void; - } -} -declare module "kute.js/src/util/radToDeg" { - export default radToDeg; - /** - * radToDeg - * - * Returns the value of a radian in degrees. - * - * @param {number} a the value in radian - * @returns {number} the value in degrees - */ - function radToDeg(a: number): number; -} -declare module "kute.js/src/util/rgbToHex" { - export default rgbToHex; - /** - * rgbToHex - * - * Converts an {r,g,b} color `Object` into #HEX string color format. - * Webkit browsers ignore HEX, always use RGB/RGBA. - * - * @param {number} r the red value - * @param {number} g the green value - * @param {number} b the blue value - * @returns {string} the #HEX string - */ - function rgbToHex(r: number, g: number, b: number): string; -} -declare module "kute.js/src/util/toJSON" { - export default toJSON; - /** - * toJSON - * - * Returns the {valuesStart, valuesEnd} objects - * from a Tween instance in JSON string format. - * - * @param {KUTE.Tween} tween the Tween instance - * @returns {string} the JSON string - */ - function toJSON(tween: KUTE.Tween): string; -} -declare module "kute.js/src/util/version" { - export default Version; - /** - * A global namespace for library version. - * @type {string} - */ - const Version: string; -} -declare module "kute.js/types/more/kute" { - export { default as Animation } from "kute.js/src/animation/animation"; - export { default as AnimationBase } from "kute.js/src/animation/animationBase"; - export { default as AnimationDevelopment } from "kute.js/src/animation/animationDevelopment"; - export { default as backgroundPosition } from "kute.js/src/components/backgroundPosition"; - export { default as backgroundPositionBase } from "kute.js/src/components/backgroundPositionBase"; - export { default as borderRadius } from "kute.js/src/components/borderRadius"; - export { default as borderRadiusBase } from "kute.js/src/components/borderRadiusBase"; - export { default as boxModel } from "kute.js/src/components/boxModel"; - export { default as boxModelBase } from "kute.js/src/components/boxModelBase"; - export { default as boxModelEssential } from "kute.js/src/components/boxModelEssential"; - export { default as clipProperty } from "kute.js/src/components/clipProperty"; - export { default as clipPropertyBase } from "kute.js/src/components/clipPropertyBase"; - export { default as colorProperties } from "kute.js/src/components/colorProperties"; - export { default as colorPropertiesBase } from "kute.js/src/components/colorPropertiesBase"; - export { default as crossBrowserMove } from "kute.js/src/components/crossBrowserMove"; - export { default as filterEffects } from "kute.js/src/components/filterEffects"; - export { default as filterEffectsBase } from "kute.js/src/components/filterEffectsBase"; - export { default as htmlAttributes } from "kute.js/src/components/htmlAttributes"; - export { default as htmlAttributesBase } from "kute.js/src/components/htmlAttributesBase"; - export { default as opacityProperty } from "kute.js/src/components/opacityProperty"; - export { default as opacityPropertyBase } from "kute.js/src/components/opacityPropertyBase"; - export { default as scrollProperty } from "kute.js/src/components/scrollProperty"; - export { default as scrollPropertyBase } from "kute.js/src/components/scrollPropertyBase"; - export { default as shadowProperties } from "kute.js/src/components/shadowProperties"; - export { default as shadowPropertiesBase } from "kute.js/src/components/shadowPropertiesBase"; - export { default as svgCubicMorph } from "kute.js/src/components/svgCubicMorph"; - export { default as svgCubicMorphBase } from "kute.js/src/components/svgCubicMorphBase"; - export { default as svgDraw } from "kute.js/src/components/svgDraw"; - export { default as svgDrawBase } from "kute.js/src/components/svgDrawBase"; - export { default as svgMorph } from "kute.js/src/components/svgMorph"; - export { default as svgMorphBase } from "kute.js/src/components/svgMorphBase"; - export { default as svgTransform } from "kute.js/src/components/svgTransform"; - export { default as svgTransformBase } from "kute.js/src/components/svgTransformBase"; - export { default as textProperties } from "kute.js/src/components/textProperties"; - export { default as textPropertiesBase } from "kute.js/src/components/textPropertiesBase"; - export { default as textWrite } from "kute.js/src/components/textWrite"; - export { default as textWriteBase } from "kute.js/src/components/textWriteBase"; - export { default as transformFunctions } from "kute.js/src/components/transformFunctions"; - export { default as transformFunctionsBase } from "kute.js/src/components/transformFunctionsBase"; - export { default as transformLegacy } from "kute.js/src/components/transformLegacy"; - export { default as transformLegacyBase } from "kute.js/src/components/transformLegacyBase"; - export { default as transformMatrix } from "kute.js/src/components/transformMatrix"; - export { default as transformMatrixBase } from "kute.js/src/components/transformMatrixBase"; - export { default as add } from "kute.js/src/core/add"; - export { default as getAll } from "kute.js/src/core/getAll"; - export { default as Internals } from "kute.js/src/core/internals"; - export { default as linkInterpolation } from "kute.js/src/core/linkInterpolation"; - export { default as queueStart } from "kute.js/src/core/queueStart"; - export { default as remove } from "kute.js/src/core/remove"; - export { default as removeAll } from "kute.js/src/core/removeAll"; - export { default as Render } from "kute.js/src/core/render"; - export { default as EasingBase } from "kute.js/src/easing/easing-base"; - export { default as EasingBezier } from "kute.js/src/easing/easing-bezier"; - export { default as Easing } from "kute.js/src/easing/easing"; - export { default as allFromTo } from "kute.js/src/interface/allFromTo"; - export { default as allTo } from "kute.js/src/interface/allTo"; - export { default as fromTo } from "kute.js/src/interface/fromTo"; - export { default as to } from "kute.js/src/interface/to"; - export { default as arrays } from "kute.js/src/interpolation/arrays"; - export { default as colors } from "kute.js/src/interpolation/colors"; - export { default as coords } from "kute.js/src/interpolation/coords"; - export { default as numbers } from "kute.js/src/interpolation/numbers"; - export { default as perspective } from "kute.js/src/interpolation/perspective"; - export { default as rotate } from "kute.js/src/interpolation/rotate"; - export { default as rotate3d } from "kute.js/src/interpolation/rotate3d"; - export { default as scale } from "kute.js/src/interpolation/scale"; - export { default as skew } from "kute.js/src/interpolation/skew"; - export { default as skewX } from "kute.js/src/interpolation/skewX"; - export { default as skewY } from "kute.js/src/interpolation/skewY"; - export { default as translate } from "kute.js/src/interpolation/translate"; - export { default as translate3d } from "kute.js/src/interpolation/translate3d"; - export { default as units } from "kute.js/src/interpolation/units"; - export { default as ComponentsBase } from "kute.js/src/objects/componentsBase"; - export { default as ComponentsDefault } from "kute.js/src/objects/componentsDefault"; - export { default as ComponentsExtra } from "kute.js/src/objects/componentsExtra"; - export { default as connect } from "kute.js/src/objects/connect"; - export { default as crossCheck } from "kute.js/src/objects/crossCheck"; - export { default as defaultOptions } from "kute.js/src/objects/defaultOptions"; - export { default as defaultValues } from "kute.js/src/objects/defaultValues"; - export { default as globalObject } from "kute.js/src/objects/globalObject"; - export { default as Interpolate } from "kute.js/src/objects/interpolate"; - export { default as KEC } from "kute.js/src/objects/kute"; - export { default as linkProperty } from "kute.js/src/objects/linkProperty"; - export { default as Objects } from "kute.js/src/objects/objects"; - export { default as ObjectsBase } from "kute.js/src/objects/objectsBase"; - export { default as onComplete } from "kute.js/src/objects/onComplete"; - export { default as onStart } from "kute.js/src/objects/onStart"; - export { default as prepareProperty } from "kute.js/src/objects/prepareProperty"; - export { default as prepareStart } from "kute.js/src/objects/prepareStart"; - export { default as supportedProperties } from "kute.js/src/objects/supportedProperties"; - export { default as Tweens } from "kute.js/src/objects/tweens"; - export { default as Util } from "kute.js/src/objects/util"; - export { default as getInlineStyle } from "kute.js/src/process/getInlineStyle"; - export { default as getInlineStyleLegacy } from "kute.js/src/process/getInlineStyleLegacy"; - export { default as getStartValues } from "kute.js/src/process/getStartValues"; - export { default as getStyleForProperty } from "kute.js/src/process/getStyleForProperty"; - export { default as prepareObject } from "kute.js/src/process/prepareObject"; - export { default as Process } from "kute.js/src/process/process"; - export { default as Tween } from "kute.js/src/tween/tween"; - export { default as TweenBase } from "kute.js/src/tween/tweenBase"; - export { default as TweenCollection } from "kute.js/src/tween/tweenCollection"; - export { default as TweenExtra } from "kute.js/src/tween/tweenExtra"; - export { default as degToRad } from "kute.js/src/util/degToRad"; - export { default as fromJSON } from "kute.js/src/util/fromJSON"; - export { default as getPrefix } from "kute.js/src/util/getPrefix"; - export { default as hexToRGB } from "kute.js/src/util/hexToRGB"; - export { default as now } from "kute.js/src/util/now"; - export { default as ProgressBar } from "kute.js/src/util/progressBar"; - export { default as radToDeg } from "kute.js/src/util/radToDeg"; - export { default as rgbToHex } from "kute.js/src/util/rgbToHex"; - export { default as selector } from "kute.js/src/util/selector"; - export { default as supportLegacyTransform } from "kute.js/src/util/supportLegacyTransform"; - export { default as toJSON } from "kute.js/src/util/toJSON"; - export { default as transformProperty } from "kute.js/src/util/transformProperty"; - export { default as trueColor } from "kute.js/src/util/trueColor"; - export { default as trueDimension } from "kute.js/src/util/trueDimension"; - export { default as trueProperty } from "kute.js/src/util/trueProperty"; - export { default as Version } from "kute.js/src/util/version"; -} diff --git a/types/more/kute.ts b/types/more/kute.ts deleted file mode 100644 index 185d333..0000000 --- a/types/more/kute.ts +++ /dev/null @@ -1,127 +0,0 @@ -export {default as Animation} from '../../src/animation/animation'; -export {default as AnimationBase} from '../../src/animation/animationBase'; -export {default as AnimationDevelopment} from '../../src/animation/animationDevelopment'; - -export {default as backgroundPosition} from '../../src/components/backgroundPosition'; -export {default as backgroundPositionBase} from '../../src/components/backgroundPositionBase'; -export {default as borderRadius} from '../../src/components/borderRadius'; -export {default as borderRadiusBase} from '../../src/components/borderRadiusBase'; -export {default as boxModel} from '../../src/components/boxModel'; -export {default as boxModelBase} from '../../src/components/boxModelBase'; -export {default as boxModelEssential} from '../../src/components/boxModelEssential'; -export {default as clipProperty} from '../../src/components/clipProperty'; -export {default as clipPropertyBase} from '../../src/components/clipPropertyBase'; -export {default as colorProperties} from '../../src/components/colorProperties'; -export {default as colorPropertiesBase} from '../../src/components/colorPropertiesBase'; -export {default as crossBrowserMove} from '../../src/components/crossBrowserMove'; -export {default as filterEffects} from '../../src/components/filterEffects'; -export {default as filterEffectsBase} from '../../src/components/filterEffectsBase'; -export {default as htmlAttributes} from '../../src/components/htmlAttributes'; -export {default as htmlAttributesBase} from '../../src/components/htmlAttributesBase'; -export {default as opacityProperty} from '../../src/components/opacityProperty'; -export {default as opacityPropertyBase} from '../../src/components/opacityPropertyBase'; -export {default as scrollProperty} from '../../src/components/scrollProperty'; -export {default as scrollPropertyBase} from '../../src/components/scrollPropertyBase'; -export {default as shadowProperties} from '../../src/components/shadowProperties'; -export {default as shadowPropertiesBase} from '../../src/components/shadowPropertiesBase'; -export {default as svgCubicMorph} from '../../src/components/svgCubicMorph'; -export {default as svgCubicMorphBase} from '../../src/components/svgCubicMorphBase'; -export {default as svgDraw} from '../../src/components/svgDraw'; -export {default as svgDrawBase} from '../../src/components/svgDrawBase'; -export {default as svgMorph} from '../../src/components/svgMorph'; -export {default as svgMorphBase} from '../../src/components/svgMorphBase'; -export {default as svgTransform} from '../../src/components/svgTransform'; -export {default as svgTransformBase} from '../../src/components/svgTransformBase'; -export {default as textProperties} from '../../src/components/textProperties'; -export {default as textPropertiesBase} from '../../src/components/textPropertiesBase'; -export {default as textWrite} from '../../src/components/textWrite'; -export {default as textWriteBase} from '../../src/components/textWriteBase'; -export {default as transformFunctions} from '../../src/components/transformFunctions'; -export {default as transformFunctionsBase} from '../../src/components/transformFunctionsBase'; -export {default as transformLegacy} from '../../src/components/transformLegacy'; -export {default as transformLegacyBase} from '../../src/components/transformLegacyBase'; -export {default as transformMatrix} from '../../src/components/transformMatrix'; -export {default as transformMatrixBase} from '../../src/components/transformMatrixBase'; - -export {default as add} from '../../src/core/add'; -export {default as getAll} from '../../src/core/getAll'; -export {default as Internals} from '../../src/core/internals'; -export {default as linkInterpolation} from '../../src/core/linkInterpolation'; -export {default as queueStart} from '../../src/core/queueStart'; -export {default as remove} from '../../src/core/remove'; -export {default as removeAll} from '../../src/core/removeAll'; -export {default as Render} from '../../src/core/render'; - -export {default as EasingBase} from '../../src/easing/easing-base'; -export {default as EasingBezier} from '../../src/easing/easing-bezier'; -export {default as Easing} from '../../src/easing/easing'; - -export {default as allFromTo} from '../../src/interface/allFromTo'; -export {default as allTo} from '../../src/interface/allTo'; -export {default as fromTo} from '../../src/interface/fromTo'; -export {default as to} from '../../src/interface/to'; - -export {default as arrays} from '../../src/interpolation/arrays'; -export {default as colors} from '../../src/interpolation/colors'; -export {default as coords} from '../../src/interpolation/coords'; -export {default as numbers} from '../../src/interpolation/numbers'; -export {default as perspective} from '../../src/interpolation/perspective'; -export {default as rotate} from '../../src/interpolation/rotate'; -export {default as rotate3d} from '../../src/interpolation/rotate3d'; -export {default as scale} from '../../src/interpolation/scale'; -export {default as skew} from '../../src/interpolation/skew'; -export {default as skewX} from '../../src/interpolation/skewX'; -export {default as skewY} from '../../src/interpolation/skewY'; -export {default as translate} from '../../src/interpolation/translate'; -export {default as translate3d} from '../../src/interpolation/translate3d'; -export {default as units} from '../../src/interpolation/units'; - -export {default as ComponentsBase} from '../../src/objects/componentsBase'; -export {default as ComponentsDefault} from '../../src/objects/componentsDefault'; -export {default as ComponentsExtra} from '../../src/objects/componentsExtra'; -export {default as connect} from '../../src/objects/connect'; -export {default as crossCheck} from '../../src/objects/crossCheck'; -export {default as defaultOptions} from '../../src/objects/defaultOptions'; -export {default as defaultValues} from '../../src/objects/defaultValues'; -export {default as globalObject} from '../../src/objects/globalObject'; -export {default as Interpolate} from '../../src/objects/interpolate'; -export {default as KEC} from '../../src/objects/kute'; -export {default as linkProperty} from '../../src/objects/linkProperty'; -export {default as Objects} from '../../src/objects/objects'; -export {default as ObjectsBase} from '../../src/objects/objectsBase'; -export {default as onComplete} from '../../src/objects/onComplete'; -export {default as onStart} from '../../src/objects/onStart'; -export {default as prepareProperty} from '../../src/objects/prepareProperty'; -export {default as prepareStart} from '../../src/objects/prepareStart'; -export {default as supportedProperties} from '../../src/objects/supportedProperties'; -export {default as Tweens} from '../../src/objects/tweens'; -export {default as Util} from '../../src/objects/util'; - -export {default as getInlineStyle} from '../../src/process/getInlineStyle'; -export {default as getInlineStyleLegacy} from '../../src/process/getInlineStyleLegacy'; -export {default as getStartValues} from '../../src/process/getStartValues'; -export {default as getStyleForProperty} from '../../src/process/getStyleForProperty'; -export {default as prepareObject} from '../../src/process/prepareObject'; -export {default as Process} from '../../src/process/process'; - -export {default as Tween} from '../../src/tween/tween'; -export {default as TweenBase} from '../../src/tween/tweenBase'; -export {default as TweenCollection} from '../../src/tween/tweenCollection'; -export {default as TweenExtra} from '../../src/tween/tweenExtra'; - -export {default as degToRad} from '../../src/util/degToRad'; -export {default as fromJSON} from '../../src/util/fromJSON'; -export {default as getPrefix} from '../../src/util/getPrefix'; -export {default as hexToRGB} from '../../src/util/hexToRGB'; -export {default as now} from '../../src/util/now'; -export {default as ProgressBar} from '../../src/util/progressBar'; -export {default as radToDeg} from '../../src/util/radToDeg'; -export {default as rgbToHex} from '../../src/util/rgbToHex'; -export {default as selector} from '../../src/util/selector'; -export {default as supportLegacyTransform} from '../../src/util/supportLegacyTransform'; -export {default as toJSON} from '../../src/util/toJSON'; -export {default as transformProperty} from '../../src/util/transformProperty'; -export {default as trueColor} from '../../src/util/trueColor'; -export {default as trueDimension} from '../../src/util/trueDimension'; -export {default as trueProperty} from '../../src/util/trueProperty'; -export {default as Version} from '../../src/util/version'; diff --git a/types/more/types.d.ts b/types/more/types.d.ts deleted file mode 100644 index 00258f9..0000000 --- a/types/more/types.d.ts +++ /dev/null @@ -1,208 +0,0 @@ -import CubicBezier from "cubic-bezier-easing"; -import Tween from "kute.js/src/tween/tween"; -import TweenBase from "kute.js/src/tween/tweenBase"; -import TweenExtra from "kute.js/src/tween/tweenExtra"; - -// custom types -export type selectorType = Element | Element[] | HTMLCollection | string; - -export type easingFunction = (fn: number) => number; -export type easingOption = string | easingFunction | CubicBezier; - -export declare interface tweenOptions { - /** @default 700 */ - duration?: number; - /** @default 0 */ - delay?: number; - /** @default 0 */ - offset?: number; - /** @default "linear" */ - easing?: easingOption; - /** @default 0 */ - repeat?: number; - /** @default 0 */ - repeatDelay?: number; - /** @default false */ - yoyo?: boolean; - /** @default null */ - resetStart?: any; -} - -export type tweenProps = [string, (string | number | number[])][]; -export type tweenParams = [Element, tweenProps, tweenProps, tweenOptions]; -export type twCollection = (Tween | TweenBase | TweenExtra)[]; -export type chainOption = Tween | TweenBase | twCollection; -export type propValue = number | number[] | [string, number] | [string, number][]; -export type rawValue = string | propValue; -export type interpolationFn = (a: propValue, b: propValue, t: number) => void; -export type prepareStartFn = (a?: string, b?: rawValue) => rawValue; -export type preparePropFn = (a?: string, b?: rawValue) => propValue; -export type onStartPropFn = (tweenProp?: string) => void; - -export interface fullComponent { - component: string; - category?: string; - property?: string; - properties?: string[]; - subProperties?: string[]; - defaultValues?: propValue[]; - defaultValue?: propValue; - defaultOptions?: [string, string | number | number[]][]; - Interpolate?: [string, interpolationFn][]; - functions: { - prepareStart: prepareStartFn; - prepareProperty: preparePropFn; - onStart: () => onStartPropFn; - onComplete?: () => void; - crossCheck?: () => void; - } -} -export interface baseComponent { - component: string; - category?: string; - property?: string; - properties?: string[]; - subProperties?: string[]; - defaultOptions?: [string, string | number | number[]][]; - Interpolate?: [string, interpolationFn][]; - functions: { - onStart: onStartPropFn; - } -} -export interface curveSpecs { - s: SVGPathCommander.CSegment | SVGPathCommander.MSegment, - ss: SVGPathCommander.curveArray, - l: number -} - -export interface curveObject { - curve: SVGPathCommander.curveArray, - original: string -} - -export type polygonMorph = [number, number][]; - -export type exactPolygon = { polygon: polygonMorph, skipBisect?: boolean } | false; - -export interface polygonObject { - polygon: polygonMorph, - original: string -} - -export declare interface transformFObject { - perspective?: number; - translate3d?: number[]; - rotate3d?: number[]; - skew?: number[]; - scale?: number; - } - -export declare interface transformMObject { - perspective?: number; - translate3d?: number[]; - rotate3d?: number[]; - scale3d?: number[]; - skew?: number[]; - } - - -export interface colorObject { - /** @default 0 */ - r: number, - /** @default 0 */ - g: number, - /** @default 0 */ - b: number, - /** @default 1 */ - a: number | null -} - -export interface drawObject { - s: number, - e: number, - l: number -} - -export interface transformSVGObject { - translate?: number | [number, number], - rotate?: number, - skewX?: number, - skewY?: number, - scale?: number -} - -// boxShadow: '0px 0px 0px 0px rgb(0,0,0)', -// h-shadow, v-shadow, blur, spread, color -export type boxShadowObject = [number, number, number, number, colorObject]; -// textShadow: '0px 0px 0px rgb(0,0,0)', -// h-shadow, v-shadow, blur, color -export type textShadowObject = [number, number, number, colorObject] -export type shadowObject = boxShadowObject | textShadowObject; - -// property: range | default -export interface filterList { - /** - * opacity range [0-100%] - * opacity unit % - * @default 100 - */ - opacity: number, - /** - * blur range [0-N] - * blur unit [em, px, rem] - * @default 0 - */ - blur: number, - /** - * saturate range [0-N] - * saturate unit % - * @default 100 - */ - saturate: number, - /** - * invert range [0-100] - * invert unit % - * @default 0 - */ - invert: number, - /** - * grayscale range [0-100] - * grayscale unit % - * @default 0 - */ - grayscale: number, - /** - * brightness range [0-100] - * brightness unit % - * @default 100 - */ - brightness: number, - /** - * contrast range [0-N] - * contrast unit % - * @default 100 - */ - contrast: number, - /** - * sepia range [0-N] - * sepia unit % - * @default 0 - */ - sepia: number, - /** - * hue-rotate range [0-N] - * hue-rotate unit deg - * @default 0 - */ - hueRotate: number, - /** - * drop-shadow [x,y,spread,color] - * @default [0,0,0,{r:0,g:0,b:0}] - */ - dropShadow: [number, number, number, colorObject], - /** - * "url(_URL_)" - * @default null - */ - url: string -} \ No newline at end of file