diff --git a/README.md b/README.md index 3504a4d..d3582d7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # KUTE.js -A modern JavaScript animation engine built on ES6/ES7 standards with most essential features for web developers, designers and animators, delivering easy to use methods to set up high performance, cross-browser animations. The focus is code quality, flexibility, performance and size. + +[![KUTE.js](demo/assets/img/apple-touch-icon.png)](https://thednp.github.io/kute.js/) + +A modern JavaScript animation engine built on ES6+ standards with most essential features for the web, delivering 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) diff --git a/demo/assets/img/rectangle.svg b/demo/assets/img/rectangle.svg index 5c14c43..9efd23e 100644 --- a/demo/assets/img/rectangle.svg +++ b/demo/assets/img/rectangle.svg @@ -1,9 +1,14 @@ - - - + + + + + diff --git a/demo/assets/img/social.svg b/demo/assets/img/social.svg index bbc017e..b9b079b 100644 --- a/demo/assets/img/social.svg +++ b/demo/assets/img/social.svg @@ -1,29 +1,34 @@ - - - - - - - - - - + + + + + + + + + + + diff --git a/demo/assets/js/svgCubicMorph.js b/demo/assets/js/svgCubicMorph.js index 223577e..bbc9c05 100644 --- a/demo/assets/js/svgCubicMorph.js +++ b/demo/assets/js/svgCubicMorph.js @@ -1,41 +1,53 @@ +// general tween options +var morphOps = { + duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut' +} + // basic morph -var morphTween = KUTE.to('#rectangle', { path: '#star' }, { - duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut' -}); -var morphTween1 = KUTE.to('#rectangle1', { path: '#star1' }, { - duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut' -}); +var morphTween = KUTE.to('#rectangle', { path: '#star' }, morphOps); +var morphTween1 = KUTE.to('#rectangle1', { path: '#star1' }, morphOps); +var morphTween2 = KUTE.to('#rectangle2', { path: '#star2' }, morphOps); var morphBtn = document.getElementById('morphBtn'); morphBtn.addEventListener('click', function(){ - !morphTween.playing && morphTween.start() && morphTween1.start() + !morphTween.playing && morphTween.start(); + !morphTween1.playing && morphTween1.start(); + !morphTween2.playing && morphTween2.start(); }, false); // line to circle -var lineMorph = KUTE.to('#line',{path:'#circle'},{ yoyo:true, repeat:1, duration:2000, easing: 'easingCubicOut'}), - lineMorph1 = KUTE.to('#line1',{path:'#circle1'},{ yoyo:true, repeat:1, duration:2000, easing: 'easingCubicOut'}), - morphBtnClosed = document.getElementById('morphBtnClosed'); +var lineMorph = KUTE.to('#line' ,{path:'#circle' }, morphOps); +var lineMorph1 = KUTE.to('#line1',{path:'#circle1'}, morphOps); +var lineMorph2 = KUTE.to('#line2',{path:'#circle2'}, morphOps); +var lineMorph3 = KUTE.to('#line3',{path:'#circle3'}, morphOps); +var morphBtnClosed = document.getElementById('morphBtnClosed') + morphBtnClosed.addEventListener('click', function(){ - !lineMorph.playing && lineMorph.start() - !lineMorph1.playing && lineMorph1.start() + !lineMorph.playing && lineMorph.start(); + !lineMorph1.playing && lineMorph1.start(); + !lineMorph2.playing && lineMorph2.start(); + !lineMorph3.playing && lineMorph3.start(); }, false); +var morphOps1 = { + duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut' +} // multishape morph var multiMorphBtn = document.getElementById('multiMorphBtn'); -var multiMorph1 = KUTE.fromTo('#w11', { path: '#w11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w21', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph2 = KUTE.fromTo('#w12', { path: '#w12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w22', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph3 = KUTE.fromTo('#w13', { path: '#w13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w23', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph4 = KUTE.fromTo('#w14', { path: '#w14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w24', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var multiMorph1 = KUTE.fromTo('#w11', { path: '#w11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w21', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph2 = KUTE.fromTo('#w12', { path: '#w12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w22', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph3 = KUTE.fromTo('#w13', { path: '#w13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w23', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph4 = KUTE.fromTo('#w14', { path: '#w14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w24', attr:{ fill: "#56C5FF" } }, morphOps1); -var multiMorph11 = KUTE.fromTo('#w111', { path: '#w111', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w211', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph21 = KUTE.fromTo('#w121', { path: '#w121', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w221', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph31 = KUTE.fromTo('#w131', { path: '#w131', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w231', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph41 = KUTE.fromTo('#w141', { path: '#w141', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w241', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var multiMorph11 = KUTE.fromTo('#w111', { path: '#w111', attr:{ fill: "rgb(233,27,31)" } }, { path: '#w211', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph21 = KUTE.fromTo('#w121', { path: '#w121', attr:{ fill: "rgb(255,87,34)" } }, { path: '#w221', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph31 = KUTE.fromTo('#w131', { path: '#w131', attr:{ fill: "rgb(76,175,80)" } }, { path: '#w231', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph41 = KUTE.fromTo('#w141', { path: '#w141', attr:{ fill: "rgb(33,150,243)" } }, { path: '#w241', attr:{ fill: "#56C5FF" } }, morphOps1); -var multiMorph1s = KUTE.fromTo('#s11', { path: '#s11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#s23', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph2s = KUTE.fromTo('#s12', { path: '#s12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#s21', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph3s = KUTE.fromTo('#s13', { path: '#s13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#s24', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var multiMorph4s = KUTE.fromTo('#s14', { path: '#s14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#s22', attr:{ fill: "#56C5FF" } }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var multiMorph1s = KUTE.fromTo('#s11', { path: '#s11', attr:{ fill: "rgb(233,27,31)" } }, { path: '#s23', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph2s = KUTE.fromTo('#s12', { path: '#s12', attr:{ fill: "rgb(255,87,34)" } }, { path: '#s21', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph3s = KUTE.fromTo('#s13', { path: '#s13', attr:{ fill: "rgb(76,175,80)" } }, { path: '#s24', attr:{ fill: "#56C5FF" } }, morphOps1); +var multiMorph4s = KUTE.fromTo('#s14', { path: '#s14', attr:{ fill: "rgb(33,150,243)" } }, { path: '#s22', attr:{ fill: "#56C5FF" } }, morphOps1); multiMorphBtn.addEventListener('click', function(){ !multiMorph1.playing && multiMorph1.start() && multiMorph11.start() && multiMorph1s.start(); @@ -46,20 +58,20 @@ multiMorphBtn.addEventListener('click', function(){ // complex multi morph var compliMorphBtn = document.getElementById('compliMorphBtn'); -var compliMorph1 = KUTE.fromTo('#rectangle-container', {path: '#rectangle-container', attr:{ fill: "#2196F3"} }, { path: '#circle-container', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph2 = KUTE.fromTo('#symbol-left', {path: '#symbol-left'}, { path: '#eye-left' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph3 = KUTE.fromTo('#symbol-left-clone', {path: '#symbol-left-clone'}, { path: '#mouth' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph4 = KUTE.fromTo('#symbol-right', {path: '#symbol-right'}, { path: '#eye-right' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var compliMorph1 = KUTE.fromTo('#rectangle-container', {path: '#rectangle-container', attr:{ fill: "#2196F3"} }, { path: '#circle-container', attr:{ fill: "#FF5722"} }, morphOps1); +var compliMorph2 = KUTE.fromTo('#symbol-left', {path: '#symbol-left'}, { path: '#eye-left' }, morphOps1); +var compliMorph3 = KUTE.fromTo('#symbol-left-clone', {path: '#symbol-left-clone'}, { path: '#mouth' }, morphOps1); +var compliMorph4 = KUTE.fromTo('#symbol-right', {path: '#symbol-right'}, { path: '#eye-right' }, morphOps1); -var compliMorph11 = KUTE.fromTo('#rectangle-container1', {path: '#rectangle-container1', attr:{ fill: "#9C27B0"} }, { path: '#circle-container1', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph21 = KUTE.fromTo('#symbol-left1', {path: '#symbol-left1'}, { path: '#eye-left1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph31 = KUTE.fromTo('#symbol-left-clone1', {path: '#symbol-left-clone1'}, { path: '#mouth1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph41 = KUTE.fromTo('#symbol-right1', {path: '#symbol-right1'}, { path: '#eye-right1' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var compliMorph11 = KUTE.fromTo('#rectangle-container1', {path: '#rectangle-container1', attr:{ fill: "#9C27B0"} }, { path: '#circle-container1', attr:{ fill: "#FF5722"} }, morphOps1); +var compliMorph21 = KUTE.fromTo('#symbol-left1', {path: '#symbol-left1'}, { path: '#eye-left1' }, morphOps1); +var compliMorph31 = KUTE.fromTo('#symbol-left-clone1', {path: '#symbol-left-clone1'}, { path: '#mouth1' }, morphOps1); +var compliMorph41 = KUTE.fromTo('#symbol-right1', {path: '#symbol-right1'}, { path: '#eye-right1' }, morphOps1); -var compliMorph12 = KUTE.fromTo('#rectangle-container2', {path: '#rectangle-container2', attr:{ fill: "#e91b1f"} }, { path: '#circle-container2', attr:{ fill: "#FF5722"} }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph22 = KUTE.fromTo('#symbol-left2', {path: '#symbol-left2'}, { path: '#eye-left2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph32 = KUTE.fromTo('#sample-shape2', {path: '#sample-shape2'}, { path: '#mouth2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); -var compliMorph42 = KUTE.fromTo('#symbol-right2', {path: '#symbol-right2'}, { path: '#eye-right2' }, { duration: 2000, repeat: 1, yoyo: true, easing: 'easingCubicOut'}); +var compliMorph12 = KUTE.fromTo('#rectangle-container2', {path: '#rectangle-container2', attr:{ fill: "#e91b1f"} }, { path: '#circle-container2', attr:{ fill: "#FF5722"} }, morphOps1); +var compliMorph22 = KUTE.fromTo('#symbol-left2', {path: '#symbol-left2'}, { path: '#eye-left2' }, morphOps1); +var compliMorph32 = KUTE.fromTo('#sample-shape2', {path: '#sample-shape2'}, { path: '#mouth2' }, morphOps1); +var compliMorph42 = KUTE.fromTo('#symbol-right2', {path: '#symbol-right2'}, { path: '#eye-right2' }, morphOps1); compliMorphBtn.addEventListener('click', function(){ !compliMorph1.playing && compliMorph1.start() && compliMorph11.start() && compliMorph12.start(); diff --git a/demo/assets/js/transformMatrix.js b/demo/assets/js/transformMatrix.js index 00f4440..77afc5b 100644 --- a/demo/assets/js/transformMatrix.js +++ b/demo/assets/js/transformMatrix.js @@ -35,10 +35,10 @@ var tween13 = KUTE.fromTo(el1, { transform: {perspective:400,translate3d:[150,20 // chain tweens try { - tween11.chain(tween12); - tween12.chain(tween13); + tween11.chain(tween12); + tween12.chain(tween13); } catch(e) { - console.warn(e+". TweenBase doesn\'t support chain method") + console.warn(e+". TweenBase doesn\'t support chain method") } // built the tween objects for element2 @@ -48,10 +48,10 @@ var tween23 = KUTE.fromTo(el2, { transform: {perspective:400,translate3d:[150,20 // chain tweens try{ - tween21.chain(tween22); - tween22.chain(tween23); + tween21.chain(tween22); + tween22.chain(tween23); }catch(e){ - console.warn(e+". TweenBase doesn\'t support chain method") + console.warn(e+". TweenBase doesn\'t support chain method") } // built the tween objects for element3 diff --git a/demo/backgroundPosition.html b/demo/backgroundPosition.html index 18643ce..4975d0b 100644 --- a/demo/backgroundPosition.html +++ b/demo/backgroundPosition.html @@ -1,108 +1,107 @@ - - - - - - - - - - + + + + + + + + + - KUTE.js Background Position + KUTE.js Background Position - - + + - - + + - - + + - + -
+
- +
+

Background Position

+

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

+
+ +
-

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.

-
+
+
+

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

+

Example

-

Here a couple of possible tween objects:

+

Here a couple of possible tween objects:

// provide the exact values for interpolation
 let bgPosTween = KUTE.to('selector1',{backgroundPosition:[0,50]}).start();
@@ -114,45 +113,45 @@ let bgPosTween = KUTE.to('selector1',{backgroundPosition:"0% 50%"}).start();
 let bgPosTween = KUTE.to('selector1',{backgroundPosition:"left center"}).start();
 
-
-
+
+
-
- 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.
  • - -
-
- - - +

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 index 299be5e..4b454dd 100644 --- a/demo/borderRadius.html +++ b/demo/borderRadius.html @@ -2,117 +2,117 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Border Radius + KUTE.js Border Radius - - + + - - + + - - + + -
+
- +
+

Border Radius

+

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

+
+ +
-

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:

-
+
+
+

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.
  • -
+

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:

- + +

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();
@@ -120,52 +120,52 @@ KUTE.to('selector4',{borderBottomLeftRadius:50}).start();
 KUTE.to('selector5',{borderBottomRightRadius:'20px'}).start();
 
-
-
ALL
-
TL
-
TR
-
BL
-
BR
+
+
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.
  • - -
-
- - - - +
+ 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 index 8c1941f..e8e682c 100644 --- a/demo/boxModel.html +++ b/demo/boxModel.html @@ -2,125 +2,125 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Box Model + KUTE.js Box Model - - + + - - + + - - + + -
+
- +
+

Box Model

+

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

+
+ +
-

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.

-
+
+
+

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.

+

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:

+

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})
@@ -132,47 +132,47 @@ 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 
+

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

+
+
BOX
 MODEL 
-
- Start -
-
+
+ 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.
  • -
- -
- - - + +

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 index 6a51cd5..19c8664 100644 --- a/demo/clipProperty.html +++ b/demo/clipProperty.html @@ -1,153 +1,153 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Clip Property + KUTE.js Clip Property - - + + - - + + - - + + -
+
- +
+

Clip Property

+

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

+
+ +
-

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.

-
+
+
+

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:

+

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:

+

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.
  • -
+
+
+
+ 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 index 8e5f89c..4c999e7 100644 --- a/demo/colorProperties.html +++ b/demo/colorProperties.html @@ -2,168 +2,168 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Color Properties + KUTE.js Color Properties - - + + - - + + - - + + -
+
- +
+

Color Properties

+

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

+
+ +
-

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:

-
-
+
+
+

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)'.
  • -
+
+ +

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:

+

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
+
+
Colors
-
- Start -
+
+ 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.
  • - -
-
- - +

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 index 09e2bf8..31a6739 100644 --- a/demo/filterEffects.html +++ b/demo/filterEffects.html @@ -1,125 +1,125 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Filter Effects + KUTE.js Filter Effects - - + + - - + + - - + + - + -
+
- +
+

Filter Effects

+

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

+
+ +
-

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.

-
+
+
+

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:

+
+

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 }})
@@ -127,64 +127,64 @@ 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.
  • -
-
- - - +
+ + + + + + + + + + + + + + +
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 index 555b25c..c510ba0 100644 --- a/demo/htmlAttributes.html +++ b/demo/htmlAttributes.html @@ -1,106 +1,106 @@ - - - - - - - - - + + + + + + + + + - KUTE.js HTML Attributes + 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.

+
+ +
-

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.

-
+
+
+

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

+
+

General Usage

// basic notation for unitless attributes
 var myAttrTween = KUTE.to('selector', {attr: {attributeName: 75}});
@@ -109,9 +109,9 @@ var myAttrTween = KUTE.to('selector', {attr: {attributeName: 75}});
 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:

+

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}});
@@ -120,13 +120,13 @@ var myDashedAttrStringTween = KUTE.to('selector', {attr: {'stroke-width': 75}});
 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.

+

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.

+

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' }});
@@ -135,23 +135,23 @@ var fillTween = KUTE.to('#element-to-fill', {attr: { fill: 'red' }});
 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.

+
+ 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.

+

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}});
@@ -160,21 +160,21 @@ var radiusTween = KUTE.to('#circle', {attr: {r: 75}});
 var coordinatesTween = KUTE.to('#circle', {attr:{cx:0,cy:0}});
 
-

A quick demo with the above:

+

A quick demo with the above:

-
- - - +
+ + + -
- Start -
-
+
+ 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:

+

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%'}});
@@ -183,50 +183,50 @@ var closingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'49%', y1:'49%',
 var rotatingGradient = KUTE.to('#gradient', {attr: {x1:'49%', x2:'51%', y1:'51%', y2:'51%'}});
 
-
- - - - - - - - - +
+ + + + + + + + + -
- Start -
+
+ 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.
  • -
- - -
+

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 index d3cd128..e070332 100644 --- a/demo/index.html +++ b/demo/index.html @@ -141,10 +141,10 @@
-

ECMA Script 2015

+

ES6+ JavaScript

-

Inside the sources you will find fast & modern JavaScript code with solid build tools. Everything and anything can be done with SVGElement, +

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.

@@ -215,11 +215,10 @@

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/ES7 JavaScript Standard, packed with utilities, build tools and a wide range of supported properties, KUTE.js is now a fully featured animation engine +

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 @@ -237,8 +236,8 @@

-

ES6/ES7 JavaScript

-

The entire codebase reworked on the latest standards with flexible rollup based build tools. Most classes are extensible via the ES6 extend +

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.

diff --git a/demo/opacityProperty.html b/demo/opacityProperty.html index b76d527..e05a4f5 100644 --- a/demo/opacityProperty.html +++ b/demo/opacityProperty.html @@ -1,108 +1,108 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Opacity Property + KUTE.js Opacity Property - - + + - - + + - - + + - + -
+
- +
+

Opacity Property

+

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

+
+ +
-

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.

-
+
+
+

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

- +

Example

+
// fade out
 let fadeOutTween = KUTE.to('selector1',{opacity:0}).start()
 
@@ -110,44 +110,44 @@ let fadeOutTween = KUTE.to('selector1',{opacity:0}).start()
 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.
  • -
-
- - - - + +
+ +

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-transform.html b/demo/performance-transform.html index ae26364..0b4b697 100644 --- a/demo/performance-transform.html +++ b/demo/performance-transform.html @@ -2,212 +2,212 @@ - - - - - - - - + + + + + + + + - KUTE.js | Regular Transform Performance Testing Page - + .cube .cube__side { + position: absolute; + height: 100%; + width: 100%; + background-color: rgba(80, 176, 255, 0.1); + box-shadow: inset 0 0 0 2px rgb(13, 165, 64); + } + .cube .cube__side:nth-child(1) {transform: translateZ(50px); } + .cube .cube__side:nth-child(2) {transform: translateZ(-50px); } + .cube .cube__side:nth-child(3) {transform: translateX(-50px) rotateY(90deg); } + .cube .cube__side:nth-child(4) {transform: translateX(50px) rotateY(-90deg); } + .cube .cube__side:nth-child(5) {transform: translateY(50px) rotateX(90deg); } + .cube .cube__side:nth-child(6) {transform: translateY(-50px) rotateX(-90deg); } + .cube .cube__side:nth-child(7), + .cube .cube__side:nth-child(8), + .cube .cube__side:nth-child(9), + .cube .cube__side:nth-child(10), + .cube .cube__side:nth-child(11), + .cube .cube__side:nth-child(12), + .cube .cube__side:nth-child(13), + .cube .cube__side:nth-child(14), + .cube .cube__side:nth-child(15) { + background-color: rgba(129, 11, 109, 0.1) !important; + box-shadow: 0 0 1rem #d7ff6a, inset 0 0 0 2px #6aff8f; + opacity: 0.2; + } + .cube.alive .cube__side:nth-child(7), + .cube.alive .cube__side:nth-child(8), + .cube.alive .cube__side:nth-child(9), + .cube.alive .cube__side:nth-child(10), + .cube.alive .cube__side:nth-child(11), + .cube.alive .cube__side:nth-child(12), + .cube.alive .cube__side:nth-child(13), + .cube.alive .cube__side:nth-child(14), + .cube.alive .cube__side:nth-child(15) {opacity: 0.5; } + .cube .cube__side:nth-child(7) {transform: translateY(-25px) rotateX(-90deg); } + .cube .cube__side:nth-child(8) {transform: rotateX(-90deg); } + .cube .cube__side:nth-child(9) {transform: translateY(25px) rotateX(-90deg); } + .cube .cube__side:nth-child(10) {transform: translateZ(25px); } + .cube .cube__side:nth-child(11) {transform: none; } + .cube .cube__side:nth-child(12) {transform: translateZ(-25px); } + .cube .cube__side:nth-child(13) {transform: translateX(-25px) rotateY(90deg); } + .cube .cube__side:nth-child(14) {transform: rotateY(90deg); } + .cube .cube__side:nth-child(15) {transform: translateX(25px) rotateY(90deg); } + -
+
- -
+ +
-
- -
+
+ +
-

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.

+

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 index f8ddaeb..d91aeb4 100644 --- a/demo/performance.html +++ b/demo/performance.html @@ -2,243 +2,243 @@ - - - - - - - - + + + + + + + + - KUTE.js | Performance Testing Page - - + .list-inline>li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; + } + -
- -
+
+ +
- - - - + + + + - - - - + + + + - - - - + + + + - - - - - -
- -
- -
-

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.

+ + + + +
+
+
+

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 index ecc7935..d9a264d 100644 --- a/demo/progress.html +++ b/demo/progress.html @@ -3,160 +3,160 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Using Update Functions | Javascript Animation Engine + 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:

+

A very basic code sample will look like this:

// the range slider
@@ -170,50 +170,50 @@ var progressBar = new KUTE.ProgressBar(rangeSlider,morphTween)
 
 // also start animation when Element is clicked
 document.getElementById('rectangle').addEventListener('click',function(){
-  !morphTween.playing && morphTween.start()
+!morphTween.playing && morphTween.start()
 })
 
-

And now let's see the code in action:

-
-
- - 0% -
- - - - +

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.

- -
- - - + +

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/shadowProperties.html b/demo/shadowProperties.html index 63c86ef..025d238 100644 --- a/demo/shadowProperties.html +++ b/demo/shadowProperties.html @@ -1,170 +1,170 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Shadow Properties + KUTE.js Shadow Properties - - + + - - + + - - + + - + -
+
- +
+

Shadow Properties

+

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

+
+ +
-

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:

-
+
+
+

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

+

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();
+'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();
+'selector',                                // target
+{boxShadow: [5, 5, 0, '#069', 'inset']},   // from
+{boxShadow: '0px 0px rgb(0,0,0)'})         // to
+.start();
 
-
-
-
- Start -
-
+
+
+
+ Start +
+
-

Text Shadow

+

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();
+'selector',                          // target
+{textShadow: [0, 0, 0, '#069']},     // from
+{textShadow: '5px 5px rgb(0,0,0)'})  // to
+.start();
 
-
-
Sample Text
- -
- 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.
  • -
- +

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.
  • +
+
@@ -176,7 +176,7 @@ var myTSTween2 = KUTE.fromTo(
- + diff --git a/demo/src/kute-base.js b/demo/src/kute-base.js index dd24cc2..96dac3b 100644 --- a/demo/src/kute-base.js +++ b/demo/src/kute-base.js @@ -1,5 +1,5 @@ /*! -* KUTE.js Base v2.0.15 (http://thednp.github.io/kute.js) +* KUTE.js Base v2.0.16 (http://thednp.github.io/kute.js) * Copyright 2015-2020 © thednp * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) */ @@ -9,7 +9,7 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); }(this, (function () { 'use strict'; - var version = "2.0.15"; + var version = "2.0.16"; var KUTE = {}; @@ -452,7 +452,7 @@ BoxModel: BoxModel, Opacity: Opacity, }, - TweenBase: TweenBase, + Tween: TweenBase, fromTo: fromTo, Objects: Objects, Easing: Easing, diff --git a/demo/src/kute-base.min.js b/demo/src/kute-base.min.js index abf6f48..815148b 100644 --- a/demo/src/kute-base.min.js +++ b/demo/src/kute-base.min.js @@ -1,2 +1,2 @@ -// KUTE.js Base v2.0.15 | thednp © 2020 | MIT-License -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=n()}(this,(function(){"use strict";var t={},n=[],e="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},i={},r={},o={};o.now=self.performance.now.bind(self.performance);var a=0,s=function(t){for(var e=0;e>0)/1e3;return i}E.prototype.start=function(n){return g(this),this.playing=!0,this._startTime=void 0!==n?n:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),b.call(this),this._startFired=!0),!a&&s(),this},E.prototype.stop=function(){return this.playing&&(_(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},E.prototype.close=function(){for(var t in h)for(var n in h[t])h[t][n].call(this,n);this._startFired=!1,u.call(this)},E.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},E.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},E.prototype.update=function(n){var e,i;if((n=void 0!==n?n:t.Time())1?1:e,i=this._easing(e),this.valuesEnd)t[r](this.element,this.valuesStart[r],this.valuesEnd[r],i);return this._onUpdate&&this._onUpdate.call(this),1!==e||(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)},y.tween=E;var k="undefined"!=typeof DOMMatrix?DOMMatrix:"undefined"!=typeof WebKitCSSMatrix?WebKitCSSMatrix:"undefined"!=typeof CSSMatrix?CSSMatrix:"undefined"!=typeof MSCSSMatrix?MSCSSMatrix:null,x={component:"transformMatrixBase",property:"transform",functions:{onStart:{transform:function(n){this.valuesEnd[n]&&!t[n]&&(t[n]=function(t,e,i,r){var o=new k,a={};for(var s in i)a[s]="perspective"===s?O(e[s],i[s],r):I(e[s],i[s],r);a.perspective&&(o.m34=-1/a.perspective),o=a.translate3d?o.translate(a.translate3d[0],a.translate3d[1],a.translate3d[2]):o,o=a.rotate3d?o.rotate(a.rotate3d[0],a.rotate3d[1],a.rotate3d[2]):o,a.skew&&(o=a.skew[0]?o.skewX(a.skew[0]):o,o=a.skew[1]?o.skewY(a.skew[1]):o),o=a.scale3d?o.scale(a.scale3d[0],a.scale3d[1],a.scale3d[2]):o,t.style[n]=o.toString()})},CSS3Matrix:function(n){this.valuesEnd.transform&&!t[n]&&(t[n]=k)}}},Interpolate:{perspective:O,translate3d:I,rotate3d:I,skew:I,scale3d:I}};function U(n){n in this.valuesEnd&&!t[n]&&(t[n]=function(t,e,i,r){t.style[n]=(r>.99||r<.01?(10*O(e,i,r)>>0)/10:O(e,i,r)>>0)+"px"})}var q=["top","left","width","height"],A={};q.map((function(t){return A[t]=U}));var B={component:"baseBoxModel",category:"boxModel",properties:q,Interpolate:{numbers:O},functions:{onStart:A}};var F={component:"baseOpacity",property:"opacity",Interpolate:{numbers:O},functions:{onStart:function(n){n in this.valuesEnd&&!t[n]&&(t[n]=function(t,e,i,r){t.style[n]=(1e3*O(e,i,r)>>0)/1e3})}}},j=new M(x),K=new M(B),Q=new M(F);return{Animation:M,Components:{Transform:j,BoxModel:K,Opacity:Q},TweenBase:E,fromTo:function(t,n,e,i){return i=i||{},new y.tween(C(t),n,e,i)},Objects:d,Easing:m,Util:v,Render:f,Interpolate:i,Internals:T,Selector:C,Version:"2.0.15"}})); +// KUTE.js Base v2.0.16 | thednp © 2020 | MIT-License +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).KUTE=n()}(this,(function(){"use strict";var t={},n=[],e="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},i={},r={},o={};o.now=self.performance.now.bind(self.performance);var a=0,s=function(t){for(var e=0;e>0)/1e3;return i}E.prototype.start=function(n){return g(this),this.playing=!0,this._startTime=void 0!==n?n:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),b.call(this),this._startFired=!0),!a&&s(),this},E.prototype.stop=function(){return this.playing&&(_(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},E.prototype.close=function(){for(var t in h)for(var n in h[t])h[t][n].call(this,n);this._startFired=!1,u.call(this)},E.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},E.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},E.prototype.update=function(n){var e,i;if((n=void 0!==n?n:t.Time())1?1:e,i=this._easing(e),this.valuesEnd)t[r](this.element,this.valuesStart[r],this.valuesEnd[r],i);return this._onUpdate&&this._onUpdate.call(this),1!==e||(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)},y.tween=E;var k="undefined"!=typeof DOMMatrix?DOMMatrix:"undefined"!=typeof WebKitCSSMatrix?WebKitCSSMatrix:"undefined"!=typeof CSSMatrix?CSSMatrix:"undefined"!=typeof MSCSSMatrix?MSCSSMatrix:null,x={component:"transformMatrixBase",property:"transform",functions:{onStart:{transform:function(n){this.valuesEnd[n]&&!t[n]&&(t[n]=function(t,e,i,r){var o=new k,a={};for(var s in i)a[s]="perspective"===s?O(e[s],i[s],r):I(e[s],i[s],r);a.perspective&&(o.m34=-1/a.perspective),o=a.translate3d?o.translate(a.translate3d[0],a.translate3d[1],a.translate3d[2]):o,o=a.rotate3d?o.rotate(a.rotate3d[0],a.rotate3d[1],a.rotate3d[2]):o,a.skew&&(o=a.skew[0]?o.skewX(a.skew[0]):o,o=a.skew[1]?o.skewY(a.skew[1]):o),o=a.scale3d?o.scale(a.scale3d[0],a.scale3d[1],a.scale3d[2]):o,t.style[n]=o.toString()})},CSS3Matrix:function(n){this.valuesEnd.transform&&!t[n]&&(t[n]=k)}}},Interpolate:{perspective:O,translate3d:I,rotate3d:I,skew:I,scale3d:I}};function U(n){n in this.valuesEnd&&!t[n]&&(t[n]=function(t,e,i,r){t.style[n]=(r>.99||r<.01?(10*O(e,i,r)>>0)/10:O(e,i,r)>>0)+"px"})}var q=["top","left","width","height"],A={};q.map((function(t){return A[t]=U}));var B={component:"baseBoxModel",category:"boxModel",properties:q,Interpolate:{numbers:O},functions:{onStart:A}};var F={component:"baseOpacity",property:"opacity",Interpolate:{numbers:O},functions:{onStart:function(n){n in this.valuesEnd&&!t[n]&&(t[n]=function(t,e,i,r){t.style[n]=(1e3*O(e,i,r)>>0)/1e3})}}},j=new M(x),K=new M(B),Q=new M(F);return{Animation:M,Components:{Transform:j,BoxModel:K,Opacity:Q},Tween:E,fromTo:function(t,n,e,i){return i=i||{},new y.tween(C(t),n,e,i)},Objects:d,Easing:m,Util:v,Render:f,Interpolate:i,Internals:T,Selector:C,Version:"2.0.16"}})); diff --git a/demo/src/kute-extra.js b/demo/src/kute-extra.js index 573e524..eed22f2 100644 --- a/demo/src/kute-extra.js +++ b/demo/src/kute-extra.js @@ -1,5 +1,5 @@ /*! -* KUTE.js Extra v2.0.15 (http://thednp.github.io/kute.js) +* KUTE.js Extra v2.0.16 (http://thednp.github.io/kute.js) * Copyright 2015-2020 © thednp * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) */ @@ -9,7 +9,7 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); }(this, (function () { 'use strict'; - var version = "2.0.15"; + var version = "2.0.16"; var KUTE = {}; @@ -1187,94 +1187,6 @@ }; Components.ColorProperties = colorProperties; - var attributes = {}; - var onStartAttr = { - attr : function(tweenProp){ - if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { - KUTE[tweenProp] = function (elem, vS, vE, v) { - for ( var oneAttr in vE ){ - KUTE.attributes[oneAttr](elem,oneAttr,vS[oneAttr],vE[oneAttr],v); - } - }; - } - }, - attributes : function(tweenProp){ - if (!KUTE[tweenProp] && this.valuesEnd.attr) { - KUTE[tweenProp] = attributes; - } - } - }; - - var ComponentName = 'htmlAttributes'; - var svgColors = ['fill','stroke','stop-color']; - function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); } - function getAttr(tweenProp,value){ - var attrStartValues = {}; - for (var attr in value){ - var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''); - var 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; - } - function prepareAttr(tweenProp,attrObj){ - var attributesObject = {}; - for ( var p in attrObj ) { - var prop = replaceUppercase(p); - var regex = /(%|[a-z]+)$/; - var currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); - if ( !svgColors.includes(prop)) { - if ( currentValue !== null && regex.test(currentValue) ) { - var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - var suffix = /%/.test(unit) ? '_percent' : ("_" + unit); - onStart[ComponentName][prop+suffix] = function(tp) { - if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { - attributes[tp] = function (elem, p, a, b, v) { - var _p = p.replace(suffix,''); - elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u ); - }; - } - }; - attributesObject[prop+suffix] = trueDimension(attrObj[p]); - } else if ( !regex.test(attrObj[p]) || currentValue === null || currentValue !== null && !regex.test(currentValue) ) { - onStart[ComponentName][prop] = function(tp) { - if ( this.valuesEnd[tweenProp] && this.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 { - onStart[ComponentName][prop] = function(tp) { - if ( this.valuesEnd[tweenProp] && this.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; - } - var attrFunctions = { - prepareStart: getAttr, - prepareProperty: prepareAttr, - onStart: onStartAttr - }; - var htmlAttributes = { - component: ComponentName, - 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: numbers,colors: colors }, - functions: attrFunctions, - Util: { replaceUppercase: replaceUppercase, trueColor: trueColor, trueDimension: trueDimension } - }; - Components.HTMLAttributes = htmlAttributes; - function dropShadow(a,b,v){ var params = [], unit = 'px'; for (var i=0; i<3; i++){ @@ -1399,6 +1311,94 @@ }; Components.FilterEffects = filterEffects; + var attributes = {}; + var onStartAttr = { + attr : function(tweenProp){ + if (!KUTE[tweenProp] && this.valuesEnd[tweenProp]) { + KUTE[tweenProp] = function (elem, vS, vE, v) { + for ( var oneAttr in vE ){ + KUTE.attributes[oneAttr](elem,oneAttr,vS[oneAttr],vE[oneAttr],v); + } + }; + } + }, + attributes : function(tweenProp){ + if (!KUTE[tweenProp] && this.valuesEnd.attr) { + KUTE[tweenProp] = attributes; + } + } + }; + + var ComponentName = 'htmlAttributes'; + var svgColors = ['fill','stroke','stop-color']; + function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); } + function getAttr(tweenProp,value){ + var attrStartValues = {}; + for (var attr in value){ + var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), + 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; + } + function prepareAttr(tweenProp,attrObj){ + var attributesObject = {}; + for ( var p in attrObj ) { + var prop = replaceUppercase(p), + regex = /(%|[a-z]+)$/, + currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); + if ( !svgColors.includes(prop)) { + if ( currentValue !== null && regex.test(currentValue) ) { + var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u, + suffix = /%/.test(unit) ? '_percent' : ("_" + unit); + onStart[ComponentName][prop+suffix] = function(tp) { + if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { + attributes[tp] = function (elem, p, a, b, v) { + var _p = p.replace(suffix,''); + elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u ); + }; + } + }; + attributesObject[prop+suffix] = trueDimension(attrObj[p]); + } else if ( !regex.test(attrObj[p]) || currentValue === null || currentValue !== null && !regex.test(currentValue) ) { + onStart[ComponentName][prop] = function(tp) { + if ( this.valuesEnd[tweenProp] && this.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 { + onStart[ComponentName][prop] = function(tp) { + if ( this.valuesEnd[tweenProp] && this.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; + } + var attrFunctions = { + prepareStart: getAttr, + prepareProperty: prepareAttr, + onStart: onStartAttr + }; + var htmlAttributes = { + component: ComponentName, + 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: numbers,colors: colors }, + functions: attrFunctions, + Util: { replaceUppercase: replaceUppercase, trueColor: trueColor, trueDimension: trueDimension } + }; + Components.HTMLAttributes = htmlAttributes; + function onStartOpacity(tweenProp){ if ( tweenProp in this.valuesEnd && !KUTE[tweenProp]) { KUTE[tweenProp] = function (elem, a, b, v) { @@ -1490,15 +1490,15 @@ return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; } function getTotalLength(el) { - if (/rect/.test(el.tagName)) { + if ('rect'===el.tagName) { return getRectLength(el); - } else if (/circle/.test(el.tagName)) { + } else if ('circle'===el.tagName) { return getCircleLength(el); - } else if (/ellipse/.test(el.tagName)) { + } else if ('ellipse'===el.tagName) { return getEllipseLength(el); - } else if (/polygon|polyline/.test(el.tagName)) { + } else if (['polygon,polyline'].indexOf(el.tagName)>-1) { return getPolyLength(el); - } else if (/line/.test(el.tagName)) { + } else if ('line'===el.tagName) { return getLineLength(el); } } @@ -1574,50 +1574,45 @@ } function clonePath(pathArray){ - return pathArray.map(function (x) { return Array.isArray(x) ? clonePath(x) : !isNaN(+x) ? +x : x; } ) + return pathArray.map(function (x) { return Array.isArray(x) + ? clonePath(x) + : !isNaN(+x) ? +x : x; } ) } - var SVGPathCommanderOptions = { + var options = { + origin:null, decimals:3, round:1 }; - function roundPath(pathArray) { - return pathArray.map( function (seg) { return seg.map(function (c,i) { - var nr = +c, dc = Math.pow(10,SVGPathCommanderOptions.decimals); - return i ? (nr % 1 === 0 ? nr : (nr*dc>>0)/dc) : c - } - ); }) - } - - function SVGPathArray(pathString){ - this.segments = []; - this.pathValue = pathString; - this.max = pathString.length; - this.index = 0; - this.param = 0.0; - this.segmentStart = 0; - this.data = []; - this.err = ''; - return this + function roundPath(pathArray,round) { + var decimalsOption = !isNaN(+round) ? +round : options.decimals; + return decimalsOption ? + pathArray.map( function (seg) { return seg.map(function (c,i) { + var nr = +c, dc = Math.pow(10,decimalsOption); + return nr ? (nr % 1 === 0 ? nr : Math.round(nr*dc)/dc) : c + } + ); }) : clonePath(pathArray) } var paramsCount = { a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0 }; function finalizeSegment(state) { - var cmd = state.pathValue[state.segmentStart], cmdLC = cmd.toLowerCase(), params = state.data; - if (cmdLC === 'm' && params.length > 2) { - state.segments.push([ cmd, params[0], params[1] ]); + var pathCommand = state.pathValue[state.segmentStart], + pathComLK = pathCommand.toLowerCase(), + params = state.data; + if (pathComLK === 'm' && params.length > 2) { + state.segments.push([ pathCommand, params[0], params[1] ]); params = params.slice(2); - cmdLC = 'l'; - cmd = (cmd === 'm') ? 'l' : 'L'; + pathComLK = 'l'; + pathCommand = (pathCommand === 'm') ? 'l' : 'L'; } - if (cmdLC === 'r') { - state.segments.push([ cmd ].concat(params)); + if (pathComLK === 'r') { + state.segments.push([ pathCommand ].concat(params)); } else { - while (params.length >= paramsCount[cmdLC]) { - state.segments.push([ cmd ].concat(params.splice(0, paramsCount[cmdLC]))); - if (!paramsCount[cmdLC]) { + while (params.length >= paramsCount[pathComLK]) { + state.segments.push([ pathCommand ].concat(params.splice(0, paramsCount[pathComLK]))); + if (!paramsCount[pathComLK]) { break; } } @@ -1638,7 +1633,7 @@ state.index++; return; } - state.err = invalidPathValue; + state.err = invalidPathValue + ": invalid Arc flag " + ch; } function isDigit(code) { @@ -1655,7 +1650,7 @@ hasDot = false, ch; if (index >= max) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing param " + (state.pathValue[index]); return; } ch = state.pathValue.charCodeAt(index); @@ -1664,7 +1659,7 @@ ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; } if (!isDigit(ch) && ch !== 0x2E) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " not number"; return; } if (ch !== 0x2E) { @@ -1673,7 +1668,7 @@ ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; if (zeroFirst && index < max) { if (ch && isDigit(ch)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[start]) + " illegal number"; return; } } @@ -1694,7 +1689,7 @@ } if (ch === 0x65 || ch === 0x45) { if (hasDot && !hasCeiling && !hasDecimal) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } index++; @@ -1707,7 +1702,7 @@ index++; } } else { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } } @@ -1715,6 +1710,21 @@ state.param = +state.pathValue.slice(start, index); } + 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) || + (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); + } + + function skipSpaces(state) { + while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { + state.index++; + } + } + function isPathCommand(code) { switch (code | 0x20) { case 0x6D: @@ -1744,27 +1754,12 @@ return (code | 0x20) === 0x61; } - 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) || - (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || - (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); - } - - function skipSpaces(state) { - while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { - state.index++; - } - } - function scanSegment(state) { var max = state.max, cmdCode, comma_found, need_params, i; state.segmentStart = state.index; cmdCode = state.pathValue.charCodeAt(state.index); if (!isPathCommand(cmdCode)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[state.index]) + " not a path command"; return; } need_params = paramsCount[state.pathValue[state.index].toLowerCase()]; @@ -1805,106 +1800,52 @@ finalizeSegment(state); } + function SVGPathArray(pathString){ + this.segments = []; + this.pathValue = pathString; + this.max = pathString.length; + this.index = 0; + this.param = 0.0; + this.segmentStart = 0; + this.data = []; + this.err = ''; + return this + } + function isPathArray(pathArray){ - return Array.isArray(pathArray) && pathArray.every(function (x){ - var pathCommand = x[0].toLowerCase(); - return paramsCount[pathCommand] === x.length - 1 && /[achlmrqstvz]/g.test(pathCommand) + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[achlmrqstvz]/g.test(pathCommand) }) } - function parsePathString(pathString) { + function parsePathString(pathString,round) { if ( isPathArray(pathString) ) { return clonePath(pathString) } - var state = new SVGPathArray(pathString), max = state.max; + var state = new SVGPathArray(pathString); skipSpaces(state); - while (state.index < max && !state.err.length) { + while (state.index < state.max && !state.err.length) { scanSegment(state); } if (state.err.length) { state.segments = []; } else if (state.segments.length) { if ('mM'.indexOf(state.segments[0][0]) < 0) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing M/m"; state.segments = []; } else { state.segments[0][0] = 'M'; } } - return roundPath(state.segments) - } - - function catmullRom2bezier(crp, z) { - var d = []; - for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { - var p = [ - {x: +crp[i - 2], y: +crp[i - 1]}, - {x: +crp[i], y: +crp[i + 1]}, - {x: +crp[i + 2], y: +crp[i + 3]}, - {x: +crp[i + 4], y: +crp[i + 5]} - ]; - if (z) { - if (!i) { - p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; - } else if (iLen - 4 == i) { - p[3] = {x: +crp[0], y: +crp[1]}; - } else if (iLen - 2 == i) { - p[2] = {x: +crp[0], y: +crp[1]}; - p[3] = {x: +crp[2], y: +crp[3]}; - } - } else { - if (iLen - 4 == i) { - p[3] = p[2]; - } else if (!i) { - p[0] = {x: +crp[i], y: +crp[i + 1]}; - } - } - d.push([ - "C", - (-p[0].x + 6 * p[1].x + p[2].x) / 6, - (-p[0].y + 6 * p[1].y + p[2].y) / 6, - (p[1].x + 6 * p[2].x - p[3].x) / 6, - (p[1].y + 6*p[2].y - p[3].y) / 6, - p[2].x, - p[2].y - ]); - } - return d - } - - function ellipseToArc(x, y, rx, ry, a) { - if (a == null && ry == null) { - ry = rx; - } - x = +x; - y = +y; - rx = +rx; - ry = +ry; - var res; - if (a != null) { - var rad = Math.PI / 180, - x1 = x + rx * Math.cos(-ry * rad), - x2 = x + rx * Math.cos(-a * rad), - y1 = y + rx * Math.sin(-ry * rad), - y2 = y + rx * Math.sin(-a * rad); - res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; - } else { - res = [ - ["M", x, y], - ["m", 0, -ry], - ["a", rx, ry, 0, 1, 1, 0, 2 * ry], - ["a", rx, ry, 0, 1, 1, 0, -2 * ry], - ["z"] - ]; - } - return res; + return roundPath(state.segments,round) } function isAbsoluteArray(pathInput){ return isPathArray(pathInput) && pathInput.every(function (x){ return x[0] === x[0].toUpperCase(); }) } - function pathToAbsolute(pathArray) { + function pathToAbsolute(pathArray,round) { if (isAbsoluteArray(pathArray)) { return clonePath(pathArray) } @@ -1912,10 +1853,8 @@ var resultArray = [], x = 0, y = 0, mx = 0, my = 0, start = 0, ii = pathArray.length, - crz = pathArray.length === 3 && - pathArray[0][0] === "M" && - pathArray[1][0].toUpperCase() === "R" && - pathArray[2][0].toUpperCase() === "Z"; + pathCommand = '', segment = [], segLength = 0, + absoluteSegment = []; if (pathArray[0][0] === "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; @@ -1924,96 +1863,54 @@ start++; resultArray[0] = ["M", x, y]; } - var loop = function ( i ) { - var r = [], pa = pathArray[i], pa0 = pa[0], dots = []; - resultArray.push(r = []); - if (pa0 !== pa0.toUpperCase()) { - r[0] = pa0.toUpperCase(); - switch (r[0]) { + for (var i = start; i < ii; i++) { + segment = pathArray[i]; + pathCommand = segment[0]; + resultArray.push(absoluteSegment = []); + if (pathCommand !== pathCommand.toUpperCase()) { + absoluteSegment[0] = pathCommand.toUpperCase(); + switch (absoluteSegment[0]) { case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +pa[6] + x; - r[7] = +pa[7] + y; + segment.slice(1,-2) + .concat([+segment[6] + x, +segment[7] + y]) + .map(function (s){ return absoluteSegment.push(s); }); break; case "V": - r[1] = +pa[1] + y; + absoluteSegment[1] = +segment[1] + y; break; case "H": - r[1] = +pa[1] + x; - break; - case "R": - dots = [x, y].concat(pa.slice(1)); - for (var j = 2, jj = dots.length; j < jj; j++) { - dots[j] = +dots[j] + x; - dots[++j] = +dots[j] + y; - } - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - break; - case "O": - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - break; - case "U": - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, pa[1], pa[2], pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); + absoluteSegment[1] = +segment[1] + x; break; case "M": - mx = +pa[1] + x; - my = +pa[2] + y; + mx = +segment[1] + x; + my = +segment[2] + y; default: - for (var k = 1, kk = pa.length; k < kk; k++) { - r[k] = +pa[k] + ((k % 2) ? x : y); - } + segment.map(function (s,j){ return j && absoluteSegment.push(+s + ((j % 2) ? x : y)); }); } - } else if (pa0 === "R") { - dots = [x, y].concat(pa.slice(1)); - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - r = ["R"].concat(pa.slice(-2)); - } else if (pa0 === "O") { - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - } else if (pa0 === "U") { - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, +pa[1], +pa[2], +pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); } else { - pa.map(function (k){ return r.push(k); }); + segment.map(function (k){ return absoluteSegment.push(k); }); } - pa0 = pa0.toUpperCase(); - if (pa0 !== "O") { - switch (r[0]) { - case "Z": - x = mx; - y = my; - break; - case "H": - x = +r[1]; - break; - case "V": - y = +r[1]; - break; - case "M": - mx = +r[r.length - 2]; - my = +r[r.length - 1]; - default: - x = +r[r.length - 2]; - y = +r[r.length - 1]; - } + segLength = absoluteSegment.length; + switch (absoluteSegment[0]) { + case "Z": + x = mx; + y = my; + break; + case "H": + x = +absoluteSegment[1]; + break; + case "V": + y = +absoluteSegment[1]; + break; + case "M": + mx = +absoluteSegment[segLength - 2]; + my = +absoluteSegment[segLength - 1]; + default: + x = +absoluteSegment[segLength - 2]; + y = +absoluteSegment[segLength - 1]; } - }; - for (var i = start; i < ii; i++) loop( i ); - return roundPath(resultArray) + } + return roundPath(resultArray,round) } function fixArc(pathArray, allPathCommands, i) { @@ -2029,55 +1926,61 @@ } function isCurveArray(pathArray){ - return isPathArray(pathArray) && pathArray.slice(1).every(function (x){ return x[0] === 'C'; }) + return isPathArray(pathArray) && pathArray.slice(1).every(function (seg){ return seg[0] === 'C'; }) } - function shorthandToQuadratic(x1,y1,qx,qy,prevCommand){ + function shorthandToQuad(x1,y1,qx,qy,prevCommand){ return 'QT'.indexOf(prevCommand)>-1 ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy} - : { qx : x1, qy : y1 } + : { qx: x1, qy: y1 } } function shorthandToCubic(x1,y1,x2,y2,prevCommand){ return 'CS'.indexOf(prevCommand)>-1 ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2} - : { x1 : x1, y1 : y1 } + : { x1: x1, y1: y1 } } function normalizeSegment(segment, params, prevCommand) { var nqxy, nxy; + 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); switch (segment[0]) { + case "H": + return ["L", segment[1], params.y1] + case "V": + return ["L", params.x1, segment[1]] case "S": nxy = shorthandToCubic(params.x1,params.y1, params.x2,params.y2, prevCommand); params.x1 = nxy.x1; params.y1 = nxy.y1; - segment = ["C", nxy.x1, nxy.y1].concat(segment.slice(1)); - break + return ["C", nxy.x1, nxy.y1].concat(segment.slice(1)) case "T": - nqxy = shorthandToQuadratic(params.x1,params.y1, params.qx, params.qy, prevCommand); + nqxy = shorthandToQuad(params.x1,params.y1, params.qx, params.qy, prevCommand); params.qx = nqxy.qx; params.qy = nqxy.qy; - segment = ["Q", params.qx, params.qy].concat(segment.slice(1)); - break + return ["Q", params.qx, params.qy].concat(segment.slice(1)) case "Q": params.qx = segment[1]; params.qy = segment[2]; - break - case "H": - segment = ["L", segment[1], params.y1]; - break - case "V": - segment = ["L", params.x1, segment[1]]; - break } return segment } - function normalizePath(pathArray) { + function isNormalizedArray(pathArray){ + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[ACLMQZ]/.test(seg[0]) + }) + } + + function normalizePath(pathArray,round) { + if (isNormalizedArray(pathArray)) { + return clonePath(pathArray) + } pathArray = pathToAbsolute(pathArray); var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, - allPathCommands = [], pathCommand = '', prevCommand = '', ii = pathArray.length, - segment, seglen; + allPathCommands = [], pathCommand = '', prevCommand = '', + ii = pathArray.length, segment, seglen; for (var i = 0; i < ii; i++) { - pathArray[i] && (pathCommand = pathArray[i][0]); + pathCommand = pathArray[i][0]; allPathCommands[i] = pathCommand; i && ( prevCommand = allPathCommands[i - 1]); pathArray[i] = normalizeSegment(pathArray[i], params, prevCommand); @@ -2088,7 +1991,7 @@ params.x2 = +(segment[seglen - 4]) || params.x1; params.y2 = +(segment[seglen - 3]) || params.y1; } - return roundPath(pathArray) + return roundPath(pathArray,round) } function rotateVector(x, y, rad) { @@ -2097,7 +2000,7 @@ return {x: X, y: Y} } - function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + function arcToCubic(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { var _120 = Math.PI * 120 / 180, rad = Math.PI / 180 * (angle || 0), res = [], xy, f1, f2, cx, cy; @@ -2145,7 +2048,7 @@ f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); x2 = cx + rx * Math.cos(f2); y2 = cy + ry * Math.sin(f2); - res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + res = arcToCubic(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = Math.cos(f1), @@ -2169,60 +2072,76 @@ } } - function quadraticToCubicBezier (x1, y1, ax, ay, x2, y2) { + function quadToCubic (x1, y1, qx, qy, x2, y2) { var _13 = 1 / 3, _23 = 2 / 3; return [ - _13 * x1 + _23 * ax, - _13 * y1 + _23 * ay, - _13 * x2 + _23 * ax, - _13 * y2 + _23 * ay, + _13 * x1 + _23 * qx, + _13 * y1 + _23 * qy, + _13 * x2 + _23 * qx, + _13 * y2 + _23 * qy, x2, y2 ] } - function lineToCubicBezier(x1, y1, x2, y2) { - return [x1, y1, x2, y2, x2, y2] + function getPointAtSegLength (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: Math.pow(t1, 3) * p1x + Math.pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + Math.pow(t, 3) * p2x, + y: Math.pow(t1, 3) * p1y + Math.pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + Math.pow(t, 3) * p2y + }; } - function segmentToCubicBezier(segment, params) { + function midPoint(a, b, t) { + var ax = a[0], ay = a[1], bx = b[0], by = b[1]; + return [ ax + (bx - ax) * t, ay + (by - ay) * t]; + } + + function lineToCubic(x1, y1, x2, y2) { + var t = 0.5, + p0 = [x1,y1], + p1 = [x2,y2], + p2 = midPoint(p0, p1, t), + p3 = midPoint(p1, p2, t), + p4 = midPoint(p2, p3, t), + p5 = midPoint(p3, p4, t), + p6 = midPoint(p4, p5, t), + cp1 = getPointAtSegLength.apply(0, p0.concat( p2, p4, p6, t)), + cp2 = getPointAtSegLength.apply(0, p6.concat( p5, p3, p1, 0)); + return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2] + } + + function segmentToCubic(segment, params) { 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); switch (segment[0]) { case 'M': params.x = segment[1]; params.y = segment[2]; - break + return segment case 'A': - segment = ['C'].concat(a2c.apply(0, [params.x1, params.y1].concat(segment.slice(1)))); - break + return ['C'].concat(arcToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) case 'Q': params.qx = segment[1]; params.qy = segment[2]; - segment = ['C'].concat(quadraticToCubicBezier(params.x1, params.y1, segment[1], segment[2], segment[3], segment[4])); - break + return ['C'].concat(quadToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) case 'L': - segment = ['C'].concat(lineToCubicBezier(params.x1, params.y1, segment[1], segment[2])); - break + return ['C'].concat(lineToCubic(params.x1, params.y1, segment[1], segment[2])) case 'Z': - segment = ['C'].concat(lineToCubicBezier(params.x1, params.y1, params.x, params.y)); - break + return ['C'].concat(lineToCubic(params.x1, params.y1, params.x, params.y)) } return segment } - function pathToCurve(pathArray) { + function pathToCurve(pathArray,round) { if (isCurveArray(pathArray)){ return clonePath(pathArray) } pathArray = normalizePath(pathArray); var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, - allPathCommands = [], pathCommand = '', ii = pathArray.length, - segment, seglen; + allPathCommands = [], pathCommand = '', + ii = pathArray.length, segment, seglen; for (var i = 0; i < ii; i++) { pathArray[i] && (pathCommand = pathArray[i][0]); - if (pathCommand !== 'C') { - allPathCommands[i] = pathCommand; - } - pathArray[i] = segmentToCubicBezier(pathArray[i], params); - allPathCommands[i] !== 'A' && pathCommand === 'C' && ( allPathCommands[i] = 'C' ); + allPathCommands[i] = pathCommand; + pathArray[i] = segmentToCubic(pathArray[i], params); fixArc(pathArray,allPathCommands,i); ii = pathArray.length; segment = pathArray[i]; @@ -2232,7 +2151,7 @@ params.x2 = +(segment[seglen - 4]) || params.x1; params.y2 = +(segment[seglen - 3]) || params.y1; } - return roundPath(pathArray) + return roundPath(pathArray,round) } function reverseCurve(pathArray){ @@ -2241,76 +2160,100 @@ .map(function (x) { return x.map(function (y,i) { return x[x.length - i - 2 * (1 - i % 2)]; } ); }) .reverse(); return [ ['M'].concat( rotatedCurve[0].slice(0,2)) ] - .concat(rotatedCurve.map(function (x){ return ['C'].concat(x.slice(2) ); } )) + .concat(rotatedCurve.map(function (x){ return ['C'].concat(x.slice(2) ); } )) } - function createPath(path) { - var np = document.createElementNS('http://www.w3.org/2000/svg','path'), - d = path instanceof SVGElement && ['path','glyph'].indexOf(path.tagName) > -1 ? path.getAttribute('d') : path; - np.setAttribute('d',d); - return np - } - - function getArea(v) { - var x0 = v[0], y0 = v[1], - x1 = v[2], y1 = v[3], - x2 = v[4], y2 = v[5], - x3 = v[6], y3 = v[7]; + function getCubicSegArea(x0,y0, x1,y1, x2,y2, x3,y3) { return 3 * ((y3 - y0) * (x1 + x2) - (x3 - x0) * (y1 + y2) - + y1 * (x0 - x2) - x1 * (y0 - y2) - + y3 * (x2 + x0 / 3) - x3 * (y2 + y0 / 3)) / 20; + + y1 * (x0 - x2) - x1 * (y0 - y2) + + y3 * (x2 + x0 / 3) - x3 * (y2 + y0 / 3)) / 20; } - function getShapeArea(curveArray) { - return curveArray.slice(1).map(function (seg,i,cv){ - var previous = cv[i === 0 ? cv.length-1 : i-1]; - return getArea(previous.slice(previous.length-2).concat(seg.slice(1))) + function getPathArea(pathArray) { + var x = 0, y = 0, mx = 0, my = 0, len = 0; + return pathToCurve(pathArray).map(function (seg) { + var assign; + switch (seg[0]){ + case 'M': + case 'Z': + mx = seg[0] === 'M' ? seg[1] : mx; + my = seg[0] === 'M' ? seg[2] : my; + x = mx; + y = my; + return 0 + default: + len = getCubicSegArea.apply(0, [x,y].concat(seg.slice(1) )); + (assign = seg.slice(-2), x = assign[0], y = assign[1]); + return len + } }).reduce(function (a, b) { return a + b; }, 0) } - function getDrawDirection(curveArray) { - if (!isCurveArray(curveArray)) { - throw("getDrawDirection expects a curveArray") - } - return getShapeArea(curveArray) >= 0 + function getDrawDirection(pathArray) { + return getPathArea(pathToCurve(pathArray)) >= 0 } - function cubicLerp(a, b, t) { - return [a[0]*(1 - t) + b[0]*t, a[1]*(1 - t) + b[1]*t] - } function splitCubic(pts,t) { t = t || 0.5; var p0 = pts.slice(0,2), p1 = pts.slice(2,4), p2 = pts.slice(4,6), p3 = pts.slice(6,8), - p4 = cubicLerp(p0, p1, t), - p5 = cubicLerp(p1, p2, t), - p6 = cubicLerp(p2, p3, t), - p7 = cubicLerp(p4, p5, t), - p8 = cubicLerp(p5, p6, t), - p9 = cubicLerp(p7, p8, t), - firsthalf = ['C'].concat( p4, p7, p9), - secondhalf = ['C'].concat( p8, p6, p3); - return [firsthalf, secondhalf] + p4 = midPoint(p0, p1, t), + p5 = midPoint(p1, p2, t), + p6 = midPoint(p2, p3, t), + p7 = midPoint(p4, p5, t), + p8 = midPoint(p5, p6, t), + p9 = midPoint(p7, p8, t); + return [ + ['C'].concat( p4, p7, p9), + ['C'].concat( p8, p6, p3) + ] } - function splitPath(pathString) { - return pathString + 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; }) } + function base3(p1, p2, p3, p4, t) { + var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, + t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; + return t * t2 - 3 * p1 + 3 * p2; + } + function getSegCubicLength (x1, y1, x2, y2, x3, y3, x4, y4, z) { + (z === null || isNaN(+z)) && (z = 1); + z = z > 1 ? 1 : z < 0 ? 0 : z; + var z2 = z / 2, ct = 0, xbase = 0, ybase = 0, sum = 0, + Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816], + Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472]; + Tvalues.map(function (T,i){ + ct = z2 * T + z2; + xbase = base3( x1, x2, x3, x4, ct); + ybase = base3( y1, y2, y3, y4, ct); + sum += Cvalues[i] * Math.sqrt(xbase * xbase + ybase * ybase); + }); + return z2 * sum + } + + function distanceSquareRoot(a, b) { + return Math.sqrt( + (a[0] - b[0]) * (a[0] - b[0]) + + (a[1] - b[1]) * (a[1] - b[1]) + ) + } + function getCurveArray(pathString){ - return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map(function (x,i,pathArray){ - var curveToPath = i ? [['M'].concat(pathArray[i-1].slice(-2))].concat([x]) : [], - curveLength = i ? createPath(pathToString(clonePath(curveToPath))).getTotalLength() : 0, - subsegs = i ? (curveLength ? splitCubic( pathArray[i-1].slice(-2).concat(x.slice(1)) ) : [x,x]) : [x]; + return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map(function (segment,i,pathArray){ + var segmentData = i && pathArray[i-1].slice(-2).concat(segment.slice(1)), + curveLength = i ? getSegCubicLength.apply(0, segmentData ) : 0, + subsegs = i ? (curveLength ? splitCubic( segmentData ) : [segment,segment]) : [segment]; return { - seg: x, - subsegs: subsegs, - length: curveLength + s: segment, + ss: subsegs, + l: curveLength } }) } @@ -2319,25 +2262,25 @@ c2 = getCurveArray(path2), L1 = c1.length, L2 = c2.length, - l1 = c1.filter(function (x){ return x.length; }).length, - l2 = c2.filter(function (x){ return x.length; }).length, - m1 = c1.filter(function (x){ return x.length; }).reduce(function (a,ref){ - var length = ref.length; - return a+length; + l1 = c1.filter(function (x){ return x.l; }).length, + l2 = c2.filter(function (x){ return x.l; }).length, + m1 = c1.filter(function (x){ return x.l; }).reduce(function (a,ref){ + var l = ref.l; + return a+l; },0) / l1 || 0, - m2 = c2.filter(function (x){ return x.length; }).reduce(function (a,ref){ - var length = ref.length; - return a+length; + m2 = c2.filter(function (x){ return x.l; }).reduce(function (a,ref){ + var l = ref.l; + return a+l; },0) / l2 || 0, tl = TL || Math.max(L1,L2), mm = [m1,m2], dif = [tl-L1,tl-L2], - result = [c1,c2].map(function (x,i) { return x.length === tl ? x.map(function (y){ return y.seg; }) + canSplit = 0, + result = [c1,c2].map(function (x,i) { return x.l === tl ? x.map(function (y){ return y.s; }) : x.map(function (y,j) { - var canSplit = j && dif[i] && y.length >= mm[i], - segResult = canSplit ? y.subsegs : [y.seg]; + canSplit = j && dif[i] && y.l >= mm[i]; dif[i] -= canSplit ? 1 : 0; - return segResult + return canSplit ? y.ss : [y.s] }).flat(); }); return result[0].length === result[1].length ? result : equalizeSegments(result[0],result[1],tl) } @@ -2358,27 +2301,18 @@ } function getRotatedCurve(a,b) { var segCount = a.length - 1, - linePaths = [], lineLengths = [], + computedIndex = 0, + sumLensSqrd = 0, rotations = getRotations(a); rotations.map(function (r,i){ - var sumLensSqrd = 0, - linePath = createPath('M0,0L0,0'), - linePt1, ll1, - linePt2, ll2, - linePathStr; - for (var j = 0; j < segCount; j++) { - linePt1 = a[(i + j) % segCount]; ll1 = linePt1.length; - linePt2 = b[ j % segCount]; ll2 = linePt2.length; - linePathStr = "M" + (linePt1[ll1-2]) + "," + (linePt1[ll1-1]) + "L" + (linePt2[ll2-2]) + "," + (linePt2[ll2-1]); - linePath.setAttribute('d',linePathStr); - sumLensSqrd += Math.pow(linePath.getTotalLength(),2); - linePaths[j] = linePath; - } + a.slice(1).map(function (s,j) { + sumLensSqrd += distanceSquareRoot(a[(i+j) % segCount].slice(-2),b[j % segCount].slice(-2)); + }); lineLengths[i] = sumLensSqrd; sumLensSqrd = 0; }); - var computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)); + computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)); return rotations[computedIndex] } function getCubicMorph(tweenProp){ @@ -2426,7 +2360,7 @@ Util: { pathToCurve: pathToCurve, pathToAbsolute: pathToAbsolute, pathToString: pathToString, parsePathString: parsePathString, getRotatedCurve: getRotatedCurve, getRotations: getRotations, equalizeSegments: equalizeSegments, - reverseCurve: reverseCurve, createPath: createPath, clonePath: clonePath, getDrawDirection: getDrawDirection, + reverseCurve: reverseCurve, clonePath: clonePath, getDrawDirection: getDrawDirection, splitCubic: splitCubic, getCurveArray: getCurveArray } }; @@ -3055,7 +2989,7 @@ var indexExtra = { Animation: AnimationDevelopment, Components: Components, - TweenExtra: TweenExtra, + Tween: TweenExtra, fromTo: fromTo, to: to, TweenCollection: TweenCollection, diff --git a/demo/src/kute-extra.min.js b/demo/src/kute-extra.min.js index 8f81b2b..cfe7f28 100644 --- a/demo/src/kute-extra.min.js +++ b/demo/src/kute-extra.min.js @@ -1,2 +1,2 @@ -// KUTE.js Extra v2.0.15 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},a={},i={};i.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ea?e=r:n=r,r=.5*(n-e)+e}return r};var P={},L={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function U(){for(var t in a)if("function"==typeof a[t])a[t].call(this,t);else for(var e in a[t])a[t][e].call(this,e);T.call(this)}P.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof L[t])return L[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),L.linear};var j=function(e,n,r,i){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,i=i||{},this._resetStart=i.resetStart||0,this._easing="function"==typeof i.easing?i.easing:P.processEasing(i.easing),this._duration=i.duration||f.duration,this._delay=i.delay||f.delay,i){var o="_"+s;o in this||(this[o]=i[s])}var u=this._easing.name;return a[u]||(a[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};j.prototype.start=function(e){return S(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),U.call(this),this._startFired=!0),!s&&o(),this},j.prototype.stop=function(){return this.playing&&(M(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},j.prototype.close=function(){for(var t in m)for(var e in m[t])m[t][e].call(this,e);this._startFired=!1,u.call(this)},j.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},j.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},j.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[a](this.element,this.valuesStart[a],this.valuesEnd[a],r);return 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)},P.tween=j,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var F=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],a=t[2];if(k.call(this,a,"end"),this._resetStart?this.valuesStart=r:k.call(this,r,"start"),!this._resetStart)for(var i in g)for(var s in g[i])g[i][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,I.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var a in this.valuesEnd)this.valuesRepeat[a]=this.valuesStart[a];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),U.call(this),this._startTime+=t.Time()-this._pauseTime,S(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(M(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[a](this.element,this.valuesStart[a],this.valuesEnd[a],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(j);P.tween=F;var N=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.to=function(t,e){},e.prototype.fromTo=function(t,e){},e.prototype.getTotalDuration=function(){},e.prototype.on=function(t,e){["start","stop","update","complete","pause","resume"].indexOf(t)>-1&&(this["_on"+(t.charAt(0).toUpperCase()+t.slice(1))]=e)},e.prototype.option=function(t,e){this["_"+t]=e},e}(F);P.tween=N;var R=function(t,e,n,r){var a=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var i=[];return Array.from(t).map((function(t,s){i[s]=r||{},i[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?a.tweens.push(new P.tween(t,e,n,i[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};R.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},R.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},R.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},R.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},R.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof R)e.chain(t.tweens);else{if(!(t instanceof P.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},R.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},R.prototype.removeTweens=function(){this.tweens=[]},R.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 q=function(t,e){if(this.element=V(t),this.element.tween=e,this.element.tween.toolbar=this.element,this.element.toolbar=this,this.element.output=this.element.parentNode.getElementsByTagName("OUTPUT")[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 P.tween))throw TypeError("tween parameter is not ["+P.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)};q.prototype.updateBar=function(){var e=this.toolbar.output,n=this.paused?this.toolbar.value:(t.Time()-this._startTime)/this._duration;n=n>.9999?1:n<.01?0:n;var r=this._reversed?1-n:n;this.toolbar.value=r,e&&(e.value=(100*r).toFixed(2)+"%")},q.prototype.toggleEvents=function(t){this.element[t+"EventListener"]("mousemove",this.moveAction,!1),this.element[t+"EventListener"]("mouseup",this.upAction,!1)},q.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)},q.prototype.moveAction=function(){this.toolbar.updateTween.call(this)},q.prototype.downAction=function(){this.tween.playing||this.tween.start(),this.tween.paused||(this.tween.pause(),this.toolbar.toggleEvents("add"),t.Tick=cancelAnimationFrame(t.Ticker))},q.prototype.upAction=function(){this.tween.paused&&(this.tween.paused&&this.tween.resume(),this.tween._startTime=t.Time()-(this.tween._reversed?1-this.value:this.value)*this.tween._duration,this.toolbar.toggleEvents("remove"),t.Tick=requestAnimationFrame(t.Ticker))};var D=function(t){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};D.prototype.setComponent=function(t){var e=this,n=t.component,i={prepareProperty:d,prepareStart:v,onStart:a,onComplete:m,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var b in i)if(b in t.functions)if("function"==typeof t.functions[b])!i[b][n]&&(i[b][n]={}),!i[b][n][s||o]&&(i[b][n][s||o]=t.functions[b]);else for(var x in t.functions[b])!i[b][n]&&(i[b][n]={}),!i[b][n][x]&&(i[b][n][x]=t.functions[b][x]);if(t.Interpolate){for(var S in t.Interpolate){var M=t.Interpolate[S];if("function"!=typeof M||r[S])for(var T in M)"function"!=typeof M[T]||r[S]||(r[S]=M[T]);else r[S]=M}y[n]=t.Interpolate}if(t.Util)for(var C in t.Util)!w[C]&&(w[C]=t.Util[C]);return e};var H=function(t){function e(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setComponent=function(e){t.prototype.setComponent.call(this,e);var n=this,i={prepareProperty:d,prepareStart:v,onStart:a,onComplete:m,crossCheck:g},s=e.category,o=e.property,u=e.properties&&e.properties.length||e.subProperties&&e.subProperties.length;if("defaultValue"in e?(n.supports=o+" property",n.defaultValue=(e.defaultValue+"").length?"YES":"not set or incorrect"):e.defaultValues&&(n.supports=(u||o)+" "+(o||s)+" properties",n.defaultValues=Object.keys(e.defaultValues).length===u?"YES":"Not set or incomplete"),e.defaultOptions){for(var l in n.extends=[],e.defaultOptions)n.extends.push(l);n.extends.length?n.extends="with <"+n.extends.join(", ")+"> new option(s)":delete n.extends}if(e.functions){for(var c in n.interface=[],n.render=[],n.warning=[],i)c in e.functions?("prepareProperty"===c&&n.interface.push("fromTo()"),"prepareStart"===c&&n.interface.push("to()"),"onStart"===c&&(n.render="can render update")):("prepareProperty"===c&&n.warning.push("fromTo()"),"prepareStart"===c&&n.warning.push("to()"),"onStart"===c&&(n.render="no function to render update"));n.interface.length?n.interface=(s||o)+" can use ["+n.interface.join(", ")+"] method(s)":delete n.uses,n.warning.length?n.warning=(s||o)+" can't use ["+n.warning.join(", ")+"] method(s) because values aren't processed":delete n.warning}if(e.Interpolate){for(var p in n.uses=[],n.adds=[],e.Interpolate){var h=e.Interpolate[p];if("function"==typeof h)r[p]||n.adds.push(""+p),n.uses.push(""+p);else for(var f in h)"function"!=typeof h[f]||r[p]||n.adds.push(""+f),n.uses.push(""+f)}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}else n.critical="For "+(o||s)+" no interpolation function[s] is set";return e.Util&&(n.hasUtil=Object.keys(e.Util).join(",")),n},e}(D);function B(t,e,n){return(t=+t)+(e-=t)*n}function Q(t,e){for(var n,r=parseInt(t)||0,a=["px","%","deg","rad","em","rem","vh","vw"],i=0;i>0)/100+"% "+(100*B(n[1],r[1],a)>>0)/100+"%"})}},X={component:"backgroundPositionProp",property:"backgroundPosition",defaultValue:[50,50],Interpolate:{numbers:B},functions:z,Util:{trueDimension:Q}};function Y(t,e,n,r){return(t=+t)+(e-=t)*r+n}function W(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=Y(n.v,r.v,r.u,a)})}x.BackgroundPosition=X;var K=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],$={};K.map((function(t){return $[t]=0}));var G={};K.forEach((function(t){G[t]=W}));var Z={component:"borderRadiusProperties",category:"borderRadius",properties:K,defaultValues:$,Interpolate:{units:Y},functions:{prepareStart:function(t){return _(this.element,t)||h[t]},prepareProperty:function(t,e){return Q(e)},onStart:G},Util:{trueDimension:Q}};function J(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=(a>.99||a<.01?(10*B(n,r,a)>>0)/10:B(n,r,a)>>0)+"px"})}x.BorderRadiusProperties=Z;var tt=["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"],et={};tt.map((function(t){return et[t]=0}));var nt={};tt.map((function(t){return nt[t]=J}));var rt={component:"boxModelProperties",category:"boxModel",properties:tt,defaultValues:et,Interpolate:{numbers:B},functions:{prepareStart:function(t){return _(this.element,t)||h[t]},prepareProperty:function(t,e){var n=Q(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:nt}};x.BoxModelProperties=rt;var at={prepareStart:function(t,e){var n=_(this.element,t),r=_(this.element,"width"),a=_(this.element,"height");return/rect/.test(n)?n:[0,r,a,0]},prepareProperty:function(t,e){if(e instanceof Array)return[Q(e[0]),Q(e[1]),Q(e[2]),Q(e[3])];var n=e.replace(/rect|\(|\)/g,"");return[Q((n=/\,/g.test(n)?n.split(/\,/g):n.split(/\s/g))[0]),Q(n[1]),Q(n[2]),Q(n[3])]},onStart:function(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,e,n,r){for(var a=0,i=[];a<4;a++){var s=e[a].v,o=n[a].v,u=n[a].u||"px";i[a]=(100*B(s,o,r)>>0)/100+u}t.style.clip="rect("+i+")"})}},it={component:"clipProperty",property:"clip",defaultValue:[0,0,0,0],Interpolate:{numbers:B},functions:at,Util:{trueDimension:Q}};function st(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var a=document.getElementsByTagName("head")[0];a.style.color=t;var i=getComputedStyle(a,null).color;return i=/rgb/.test(i)?i.replace(/[^\d,]/g,"").split(","):[0,0,0],a.style.color="",{r:parseInt(i[0]),g:parseInt(i[1]),b:parseInt(i[2])}}}function ot(t,e,n){var r,a={},i=",";for(r in e)a[r]="a"!==r?B(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*B(t[r],e[r],n)>>0)/100:null;return a.a?"rgba("+a.r+i+a.g+i+a.b+i+a.a+")":"rgb("+a.r+i+a.g+i+a.b+")"}function ut(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=ot(n,r,a)})}x.ClipProperty=it;var lt=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],ct={};lt.map((function(t){ct[t]="#000"}));var pt={};lt.map((function(t){return pt[t]=ut}));var ht={component:"colorProperties",category:"colors",properties:lt,defaultValues:ct,Interpolate:{numbers:B,colors:ot},functions:{prepareStart:function(t,e){return _(this.element,t)||h[t]},prepareProperty:function(t,e){return st(e)},onStart:pt},Util:{trueColor:st}};x.ColorProperties=ht;var ft={},dt="htmlAttributes",vt=["fill","stroke","stop-color"];function gt(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var mt={prepareStart:function(t,e){var n={};for(var r in e){var a=gt(r).replace(/_+[a-z]+/,""),i=this.element.getAttribute(a);n[a]=vt.includes(a)?i||"rgba(0,0,0,0)":i||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var i=gt(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(i.replace(/_+[a-z]+/,""));if(vt.includes(i))a.htmlAttributes[i]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in ft)&&(ft[e]=function(t,e,n,r,a){t.setAttribute(e,ot(n,r,a))})},n[i]=st(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=Q(o).u||Q(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;a.htmlAttributes[i+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in ft)&&(ft[e]=function(t,e,n,r,a){var i=e.replace(l,"");t.setAttribute(i,(1e3*B(n.v,r.v,a)>>0)/1e3+r.u)})},n[i+l]=Q(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(a.htmlAttributes[i]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in ft)&&(ft[e]=function(t,e,n,r,a){t.setAttribute(e,(1e3*B(n,r,a)>>0)/1e3)})},n[i]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,a){for(var i in r)t.attributes[i](e,i,n[i],r[i],a)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=ft)}}},yt={component:dt,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:B,colors:ot},functions:mt,Util:{replaceUppercase:gt,trueColor:st,trueDimension:Q}};function bt(t,e,n){for(var r=[],a=0;a<3;a++)r[a]=(100*B(t[a],e[a],n)>>0)/100+"px";return"drop-shadow("+r.concat(ot(t[3],e[3],n)).join(" ")+")"}function wt(t){return t.replace("-r","R").replace("-s","S")}function xt(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++)e[n]=parseFloat(e[n]);return e[3]=st(e[3]),e}function St(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*B(n.blur,r.blur,a)>>0)/100+"em)":"")+(n.saturate||r.saturate?"saturate("+(100*B(n.saturate,r.saturate,a)>>0)/100+"%)":"")+(n.invert||r.invert?"invert("+(100*B(n.invert,r.invert,a)>>0)/100+"%)":"")+(n.grayscale||r.grayscale?"grayscale("+(100*B(n.grayscale,r.grayscale,a)>>0)/100+"%)":"")+(n.hueRotate||r.hueRotate?"hue-rotate("+(100*B(n.hueRotate,r.hueRotate,a)>>0)/100+"deg)":"")+(n.sepia||r.sepia?"sepia("+(100*B(n.sepia,r.sepia,a)>>0)/100+"%)":"")+(n.brightness||r.brightness?"brightness("+(100*B(n.brightness,r.brightness,a)>>0)/100+"%)":"")+(n.contrast||r.contrast?"contrast("+(100*B(n.contrast,r.contrast,a)>>0)/100+"%)":"")+(n.dropShadow||r.dropShadow?bt(n.dropShadow,r.dropShadow,a):"")})},crossCheck:function(t){if(this.valuesEnd[t])for(var e in this.valuesStart[t])this.valuesEnd[t][e]||(this.valuesEnd[t][e]=this.valuesStart[t][e])}},Tt={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:B,blur:B,saturate:B,grayscale:B,brightness:B,contrast:B,sepia:B,invert:B,hueRotate:B,dropShadow:{numbers:B,colors:ot,dropShadow:bt}},functions:Mt,Util:{parseDropShadow:xt,parseFilterString:St,replaceDashNamespace:wt,trueColor:st}};x.FilterEffects=Tt;var Ct={prepareStart:function(t){return _(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=(1e3*B(n,r,a)>>0)/1e3})}},Et={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:B},functions:Ct};function _t(t,e){return parseFloat(t)/100*e}function kt(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function It(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},a=function(t,e){return null!=t&&null!=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*B(e.s,n.s,r)>>0)/100,s=(100*B(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=i+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+a+"px"})}},jt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:B},functions:Ut,Util:{getRectLength:kt,getPolyLength:It,getLineLength:At,getCircleLength:Ot,getEllipseLength:Pt,getTotalLength:Lt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Vt,percent:_t}};function Ft(t){return t.map((function(t){return t[0].concat(t.slice(1).join(" "))})).join("")}function Nt(t){return t.map((function(t){return Array.isArray(t)?Nt(t):isNaN(+t)?t:+t}))}x.SVGDraw=jt;var Rt=3;function qt(t){return t.map((function(t){return t.map((function(t,e){var n=+t,r=Math.pow(10,Rt);return e?n%1==0?n:(n*r>>0)/r:t}))}))}function Dt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}var Ht={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Bt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Ht[n]&&(t.segments.push([e].concat(r.splice(0,Ht[n]))),Ht[n]););}var Qt="Invalid path value";function zt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Qt)}function Xt(t){return t>=48&&t<=57}function Yt(t){var e,n=t.index,r=n,a=t.max,i=!1,s=!1,o=!1,u=!1;if(r>=a)t.err=Qt;else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=48&&t<=57||43===t||45===t||46===t}function Kt(t){for(;t.index=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function $t(t){var e,n,r,a,i=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Ht[t.pathValue[t.index].toLowerCase()],t.index++,Kt(t),t.data=[],r){for(n=!1;;){for(a=r;a>0;a--){if(97!=(32|e)||3!==a&&4!==a?Yt(t):zt(t),t.err.length)return;t.data.push(t.param),Kt(t),n=!1,t.index=t.max)break;if(!Wt(t.pathValue.charCodeAt(t.index)))break}}Bt(t)}else Bt(t);else t.err=Qt}function Gt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ht[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Zt(t){if(Gt(t))return Nt(t);var e=new Dt(t),n=e.max;for(Kt(e);e.indexr;r+=2){var i=[{x:+t[r-2],y:+t[r-1]},{x:+t[r],y:+t[r+1]},{x:+t[r+2],y:+t[r+3]},{x:+t[r+4],y:+t[r+5]}];e?r?a-4==r?i[3]={x:+t[0],y:+t[1]}:a-2==r&&(i[2]={x:+t[0],y:+t[1]},i[3]={x:+t[2],y:+t[3]}):i[0]={x:+t[a-2],y:+t[a-1]}:a-4==r?i[3]=i[2]:r||(i[0]={x:+t[r],y:+t[r+1]}),n.push(["C",(-i[0].x+6*i[1].x+i[2].x)/6,(-i[0].y+6*i[1].y+i[2].y)/6,(i[1].x+6*i[2].x-i[3].x)/6,(i[1].y+6*i[2].y-i[3].y)/6,i[2].x,i[2].y])}return n}function te(t,e,n,r,a){var i;if(null==a&&null==r&&(r=n),t=+t,e=+e,n=+n,r=+r,null!=a){var s=Math.PI/180,o=t+n*Math.cos(-r*s),u=t+n*Math.cos(-a*s);i=[["M",o,e+n*Math.sin(-r*s)],["A",n,n,0,+(a-r>180),0,u,e+n*Math.sin(-a*s)]]}else i=[["M",t,e],["m",0,-r],["a",n,r,0,1,1,0,2*r],["a",n,r,0,1,1,0,-2*r],["z"]];return i}function ee(t){if(Gt(e=t)&&e.every((function(t){return t[0]===t[0].toUpperCase()})))return Nt(t);var e;t=Zt(t);var n=[],r=0,a=0,i=0,s=0,o=0,u=t.length,l=3===t.length&&"M"===t[0][0]&&"R"===t[1][0].toUpperCase()&&"Z"===t[2][0].toUpperCase();"M"===t[0][0]&&(r=+t[0][1],a=+t[0][2],i=r,s=a,o++,n[0]=["M",r,a]);for(var c=function(e){var o=[],u=t[e],c=u[0],p=[];if(n.push(o=[]),c!==c.toUpperCase())switch(o[0]=c.toUpperCase(),o[0]){case"A":o[1]=u[1],o[2]=u[2],o[3]=u[3],o[4]=u[4],o[5]=u[5],o[6]=+u[6]+r,o[7]=+u[7]+a;break;case"V":o[1]=+u[1]+a;break;case"H":o[1]=+u[1]+r;break;case"R":for(var h=2,f=(p=[r,a].concat(u.slice(1))).length;h7){t[n].shift();for(var r=t[n];r.length;)e[n]="A",t.splice(n++,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}function re(t){return Gt(t)&&t.slice(1).every((function(t){return"C"===t[0]}))}function ae(t,e,n){var r,a;switch(t[0]){case"S":a=function(t,e,n,r,a){return"CS".indexOf(a)>-1?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(e.x1,e.y1,e.x2,e.y2,n),e.x1=a.x1,e.y1=a.y1,t=["C",a.x1,a.y1].concat(t.slice(1));break;case"T":r=function(t,e,n,r,a){return"QT".indexOf(a)>-1?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(e.x1,e.y1,e.qx,e.qy,n),e.qx=r.qx,e.qy=r.qy,t=["Q",e.qx,e.qy].concat(t.slice(1));break;case"Q":e.qx=t[1],e.qy=t[2];break;case"H":t=["L",t[1],e.y1];break;case"V":t=["L",e.x1,t[1]]}return t}function ie(t,e,n){return{x:t*Math.cos(n)-e*Math.sin(n),y:t*Math.sin(n)+e*Math.cos(n)}}function se(t,e,n,r,a,i,s,o,u,l){var c,p,h,f,d,v=120*Math.PI/180,g=Math.PI/180*(a||0),m=[];if(l)p=l[0],h=l[1],f=l[2],d=l[3];else{t=(c=ie(t,e,-g)).x,e=c.y;var y=(t-(o=(c=ie(o,u,-g)).x))/2,b=(e-(u=c.y))/2,w=y*y/(n*n)+b*b/(r*r);w>1&&(n*=w=Math.sqrt(w),r*=w);var x=n*n,S=r*r,M=(i==s?-1:1)*Math.sqrt(Math.abs((x*S-x*b*b-S*y*y)/(x*b*b+S*y*y)));f=M*n*b/r+(t+o)/2,d=M*-r*y/n+(e+u)/2,p=Math.asin(((e-d)/r).toFixed(9)),h=Math.asin(((u-d)/r).toFixed(9)),p=th&&(p-=2*Math.PI),!s&&h>p&&(h-=2*Math.PI)}var T=h-p;if(Math.abs(T)>v){var C=h,E=o,_=u;h=p+v*(s&&h>p?1:-1),o=f+n*Math.cos(h),u=d+r*Math.sin(h),m=se(o,u,n,r,a,0,s,E,_,[h,C,f,d])}T=h-p;var k=Math.cos(p),I=Math.sin(p),A=Math.cos(h),O=Math.sin(h),P=Math.tan(T/4),L=4/3*n*P,V=4/3*r*P,U=[t,e],j=[t+L*I,e-V*k],F=[o+L*O,u-V*A],N=[o,u];return j[0]=2*U[0]-j[0],j[1]=2*U[1]-j[1],l?[j,F,N].concat(m):(m=[j,F,N].concat(m).join().split(",")).map((function(t,e){return e%2?ie(m[e-1],t,g).y:ie(t,m[e+1],g).x}))}function oe(t,e,n,r){return[t,e,n,r,n,r]}function ue(t,e){switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"M":e.x=t[1],e.y=t[2];break;case"A":t=["C"].concat(se.apply(0,[e.x1,e.y1].concat(t.slice(1))));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"].concat((n=e.x1,r=e.y1,a=t[1],i=t[2],s=t[3],o=t[4],[(u=1/3)*n+(l=2/3)*a,u*r+l*i,u*s+l*a,u*o+l*i,s,o]));break;case"L":t=["C"].concat(oe(e.x1,e.y1,t[1],t[2]));break;case"Z":t=["C"].concat(oe(e.x1,e.y1,e.x,e.y))}var n,r,a,i,s,o,u,l;return t}function le(t){if(re(t))return Nt(t);t=function(t){for(var e,n,r={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],i="",s="",o=(t=ee(t)).length,u=0;u-1?t.getAttribute("d"):t;return e.setAttribute("d",n),e}function he(t){if(!re(t))throw"getDrawDirection expects a curveArray";return function(t){return t.slice(1).map((function(t,e,n){var r,a,i,s,o,u,l,c,p,h=n[0===e?n.length-1:e-1];return a=(r=h.slice(h.length-2).concat(t.slice(1)))[0],i=r[1],s=r[2],o=r[3],u=r[4],l=r[5],c=r[6],3*(((p=r[7])-i)*(s+u)-(c-a)*(o+l)+o*(a-u)-s*(i-l)+p*(u+a/3)-c*(l+i/3))/20})).reduce((function(t,e){return t+e}),0)}(t)>=0}function fe(t,e,n){return[t[0]*(1-n)+e[0]*n,t[1]*(1-n)+e[1]*n]}function de(t,e){e=e||.5;var n=t.slice(0,2),r=t.slice(2,4),a=t.slice(4,6),i=t.slice(6,8),s=fe(n,r,e),o=fe(r,a,e),u=fe(a,i,e),l=fe(s,o,e),c=fe(o,u,e),p=fe(l,c,e);return[["C"].concat(s,l,p),["C"].concat(c,u,i)]}function ve(t){return le(function(t){return t.replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t}))}(Ft(ee(t)))[0]).map((function(t,e,n){var r=e?[["M"].concat(n[e-1].slice(-2))].concat([t]):[],a=e?pe(Ft(Nt(r))).getTotalLength():0,i=e?a?de(n[e-1].slice(-2).concat(t.slice(1))):[t,t]:[t];return{seg:t,subsegs:i,length:a}}))}function ge(t,e,n){var r=ve(t),a=ve(e),i=r.length,s=a.length,o=r.filter((function(t){return t.length})).length,u=a.filter((function(t){return t.length})).length,l=r.filter((function(t){return t.length})).reduce((function(t,e){return t+e.length}),0)/o||0,c=a.filter((function(t){return t.length})).reduce((function(t,e){return t+e.length}),0)/u||0,p=n||Math.max(i,s),h=[l,c],f=[p-i,p-s],d=[r,a].map((function(t,e){return t.length===p?t.map((function(t){return t.seg})):t.map((function(t,n){var r=n&&f[e]&&t.length>=h[e],a=r?t.subsegs:[t.seg];return f[e]-=r?1:0,a})).flat()}));return d[0].length===d[1].length?d:ge(d[0],d[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 s,o=a+i;return 0===i||t[o]&&"M"===t[o][0]?(s=t[o],["M"].concat(s.slice(-2))):(o>=e&&(o-=n),t[o])}))}))}function ye(t,e){var n=t.length-1,r=[],a=[],i=me(t);return i.map((function(i,s){for(var o,u,l,c,p,h=0,f=pe("M0,0L0,0"),d=0;d>0)/1e3)}t.setAttribute("d",1===r?n.original:Ft(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=ge(this.valuesStart[t].original,this.valuesEnd[t].original),a=he(r[0])!==he(r[1])?ce(r[0]):Nt(r[0]);this.valuesStart[t].curve=a,this.valuesEnd[t].curve=ye(r[1],a)}}}},we={component:"svgCubicMorph",property:"path",defaultValue:[],Interpolate:{numbers:B,pathToString:Ft},functions:be,Util:{pathToCurve:le,pathToAbsolute:ee,pathToString:Ft,parsePathString:Zt,getRotatedCurve:ye,getRotations:me,equalizeSegments:ge,reverseCurve:ce,createPath:pe,clonePath:Nt,getDrawDirection:he,splitCubic:de,getCurveArray:ve}};function xe(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 Se(t){var e=t&&/\)/.test(t)?t.substring(0,t.length-1).split(/\)\s|\)/):"none",n={};if(e instanceof Array)for(var r=0,a=e.length;r>0)/1e3+(s?","+(1e3*s>>0)/1e3:"")+")":"")+(l?"rotate("+(1e3*l>>0)/1e3+")":"")+(h?"skewX("+(1e3*h>>0)/1e3+")":"")+(f?"skewY("+(1e3*f>>0)/1e3+")":"")+(1!==u?"scale("+(1e3*u>>0)/1e3+")":""))})},crossCheck:function(t){if(this._resetStart&&this.valuesEnd[t]){var e=this.valuesStart[t],n=this.valuesEnd[t],r=Me.call(this,t,Se(this.element.getAttribute("transform")));for(var a in r)e[a]=r[a];var i=this.element.ownerSVGElement,s=i.createSVGTransformFromMatrix(i.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]));for(var o in e.translate=[s.matrix.e,s.matrix.f],e)o in n&&"origin"!==o||(n[o]=e[o])}}},Ce={component:"svgTransformProperty",property:"svgTransform",defaultOptions:{transformOrigin:"50% 50%"},defaultValue:{translate:0,rotate:0,skewX:0,skewY:0,scale:1},Interpolate:{numbers:B},functions:Te,Util:{parseStringOrigin:xe,parseTransformString:Se,parseTransformSVG:Me}};x.SVGTransformProperty=Ce;var Ee=function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});document.addEventListener("DOMContentLoaded",(function t(){document.removeEventListener("DOMContentLoaded",t,e)}),e)}catch(t){}return t}(),_e="onmouseleave"in document?["mouseenter","mouseleave"]:["mouseover","mouseout"],ke="ontouchstart"in window||navigator.msMaxTouchPoints||!1?"touchstart":"mousewheel",Ie=navigator&&/(EDGE|Mac)/i.test(navigator.userAgent)?document.body:document.documentElement,Ae=!!Ee&&{passive:!1};function Oe(t){this.scrolling&&t.preventDefault()}function Pe(){var t=this.element;return t===Ie?{el:document,st:document.body}:{el:t,st:t}}function Le(t,e){e[t](_e[0],Oe,Ae),e[t](ke,Oe,Ae)}function Ve(){var t=Pe.call(this);"scroll"in this.valuesEnd&&!t.el.scrolling&&(t.el.scrolling=1,Le("addEventListener",t.el),t.st.style.pointerEvents="none")}function Ue(){var t=Pe.call(this);"scroll"in this.valuesEnd&&t.el.scrolling&&(t.el.scrolling=0,Le("removeEventListener",t.el),t.st.style.pointerEvents="")}var je={prepareStart:function(){return this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Ie,this.element===Ie?window.pageYOffset||Ie.scrollTop:this.element.scrollTop},prepareProperty:function(t,e){return parseInt(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Ie,Ve.call(this),t[e]=function(t,e,n,r){t.scrollTop=B(e,n,r)>>0})},onComplete:function(t){Ue.call(this)}},Fe={component:"scrollProperty",property:"scroll",defaultValue:0,Interpolate:{numbers:B},functions:je,Util:{preventScroll:Oe,scrollIn:Ve,scrollOut:Ue,getScrollTargets:Pe,toggleScrollEvents:Le,supportPassive:Ee}};function Ne(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,a){for(var i=[],s="textShadow"===e?3:4,o=3===s?n[3]:n[4],u=3===s?r[3]:r[4],l=!!(n[5]&&"none"!==n[5]||r[5]&&"none"!==r[5])&&" inset",c=0;c>0)/1e3+"px");t.style[e]=l?ot(o,u,a)+i.join(" ")+l:ot(o,u,a)+i.join(" ")})}x.ScrollProperty=Fe;var Re=["boxShadow","textShadow"];function qe(t,e){var n,r;for(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),r=0;r<4;r++)n[r]=parseFloat(n[r]);return n[4]=st(n[4]),n="boxShadow"===e?n:n.filter((function(t,e){return[0,1,2,4].indexOf(e)>-1}))}var De={};Re.map((function(t){return De[t]=Ne}));var He={component:"shadowProperties",properties:Re,defaultValues:{boxShadow:"0px 0px 0px 0px rgb(0,0,0)",textShadow:"0px 0px 0px rgb(0,0,0)"},Interpolate:{numbers:B,colors:ot},functions:{prepareStart:function(t,e){var n=_(this.element,t);return/^none$|^initial$|^inherit$|^inset$/.test(n)?h[t]:n},prepareProperty:function(t,e){if("string"==typeof e){var n,r="none";r=/inset/.test(e)?"inset":r,n=(e=/inset/.test(e)?e.replace(/(\s+inset|inset+\s)/g,""):e).match(/(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi),e=qe(e=e.replace(n[0],"").split(" ").concat([n[0].replace(/\s/g,"")],[r]),t)}else e instanceof Array&&(e=qe(e,t));return e},onStart:De},Util:{processShadowArray:qe,trueColor:st}};function Be(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=Y(n.v,r.v,r.u,a)})}x.ShadowProperties=He;var Qe=["fontSize","lineHeight","letterSpacing","wordSpacing"],ze={};Qe.forEach((function(t){ze[t]=Be}));var Xe={component:"textProperties",category:"textProperties",properties:Qe,defaultValues:{fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},Interpolate:{units:Y},functions:{prepareStart:function(t){return _(this.element,t)||h[t]},prepareProperty:function(t,e){return Q(e)},onStart:ze},Util:{trueDimension:Q}};x.TextProperties=Xe;var Ye=String("abcdefghijklmnopqrstuvwxyz").split(""),We=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),Ke=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),$e=String("0123456789").split(""),Ge=Ye.concat(We,$e),Ze=Ge.concat(Ke),Je={alpha:Ye,upper:We,symbols:Ke,numeric:$e,alphanumeric:Ge,all:Ze},tn={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in Je?Je[n]:n&&n.length?n:Je[f.textChars];t[e]=function(t,e,n,a){var i="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(a*u.length,u.length)>>0,0),t.innerHTML=a<1?s+l:""===n?" ":n):" "===n?(i=o.substring(0,Math.min((1-a)*o.length,o.length)>>0),t.innerHTML=a<1?i+l:""===n?" ":n):(i=o.substring(o.length,Math.min(a*o.length,o.length)>>0),s=u.substring(0,Math.min(a*u.length,u.length)>>0),t.innerHTML=a<1?s+l+i:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=B(e,n,r)>>0})}};function en(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 nn(t,e){var n=[];if(t.children.length){for(var r,a=[],i=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3;return r}x.TextWriteProperties=rn;var sn="undefined"!=typeof DOMMatrix?DOMMatrix:"undefined"!=typeof WebKitCSSMatrix?WebKitCSSMatrix:"undefined"!=typeof CSSMatrix?CSSMatrix:"undefined"!=typeof MSCSSMatrix?MSCSSMatrix:null,on="transformMatrix";var un={component:on,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={};if(this.element.transformMatrix){var r=this.element.transformMatrix;for(var a in r)n[a]=r[a]}else for(var i in e)n[i]="perspective"===i?e[i]:h.transform[i];return n},prepareProperty:function(t,e){if("object"==typeof e&&!e.length){var n,r={},a={},i={},s={},o={},u=[{translate3d:a},{rotate3d:i},{skew:o},{scale3d:s}],l=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)})),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)){(/translate/.test(t)?a:/rotate/.test(t)?i:/scale/.test(t)?s:/skew/.test(t)?o:{})[t.replace(/translate|rotate|scale|skew/,"").toLowerCase()]=/scale/.test(t)?parseFloat(e[t]):parseInt(e[t])}else"skew"===t?(n=e[t].map((function(t){return parseInt(t)||0})),r[t]=[n[0]||0,n[1]||0]):r[t]=parseInt(e[t])};for(var c in e)l(c);return u.map((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}console.error('KUTE.js - "'+e+'" is not valid/supported transform function')},onStart:{transform:function(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,a){var i=new sn,s={};for(var o in r)s[o]="perspective"===o?B(n[o],r[o],a):an(n[o],r[o],a);s.perspective&&(i.m34=-1/s.perspective),i=s.translate3d?i.translate(s.translate3d[0],s.translate3d[1],s.translate3d[2]):i,i=s.rotate3d?i.rotate(s.rotate3d[0],s.rotate3d[1],s.rotate3d[2]):i,s.skew&&(i=s.skew[0]?i.skewX(s.skew[0]):i,i=s.skew[1]?i.skewY(s.skew[1]):i),i=s.scale3d?i.scale(s.scale3d[0],s.scale3d[1],s.scale3d[2]):i,t.style[e]=i.toString()})},CSS3Matrix:function(e){this.valuesEnd.transform&&!t[e]&&(t[e]=sn)}},onComplete:function(t){if(this.valuesEnd[t])for(var e in this.element.transformMatrix={},this.valuesEnd[t])this.element.transformMatrix[e]=this.valuesEnd[t][e]},crossCheck:function(t){this.valuesEnd[t]&&this.valuesEnd[t].perspective&&!this.valuesStart[t].perspective&&(this.valuesStart[t].perspective=this.valuesEnd[t].perspective)}},Interpolate:{perspective:B,translate3d:an,rotate3d:an,skew:an,scale3d:an}};for(var ln in x.TransformMatrix=un,x){var cn=x[ln];x[ln]=new H(cn)}return{Animation:H,Components:x,TweenExtra:N,fromTo:function(t,e,n,r){return r=r||{},new P.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new P.tween(V(t),e,e,n)},TweenCollection:R,ProgressBar:q,allFromTo:function(t,e,n,r){return r=r||{},new R(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new R(V(t,!0),e,e,n)},Objects:b,Util:w,Easing:L,CubicBezier:O,Render:l,Interpolate:r,Process:A,Internals:C,Selector:V,Version:"2.0.15"}})); +// KUTE.js Extra v2.0.16 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var P={},V={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function L(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function j(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);T.call(this)}P.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof V[t])return V[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),V.linear};var U=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:P.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};U.prototype.start=function(e){return S(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),j.call(this),this._startFired=!0),!s&&o(),this},U.prototype.stop=function(){return this.playing&&(M(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},U.prototype.close=function(){for(var t in m)for(var e in m[t])m[t][e].call(this,e);this._startFired=!1,u.call(this)},U.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},U.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},U.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},P.tween=U,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var F=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(I.call(this,i,"end"),this._resetStart?this.valuesStart=r:I.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,A.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),j.call(this),this._startTime+=t.Time()-this._pauseTime,S(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(M(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(U);P.tween=F;var q=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.to=function(t,e){},e.prototype.fromTo=function(t,e){},e.prototype.getTotalDuration=function(){},e.prototype.on=function(t,e){["start","stop","update","complete","pause","resume"].indexOf(t)>-1&&(this["_on"+(t.charAt(0).toUpperCase()+t.slice(1))]=e)},e.prototype.option=function(t,e){this["_"+t]=e},e}(F);P.tween=q;var N=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new P.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};N.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},N.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},N.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},N.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},N.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof N)e.chain(t.tweens);else{if(!(t instanceof P.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},N.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},N.prototype.removeTweens=function(){this.tweens=[]},N.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=function(t,e){if(this.element=L(t),this.element.tween=e,this.element.tween.toolbar=this.element,this.element.toolbar=this,this.element.output=this.element.parentNode.getElementsByTagName("OUTPUT")[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 P.tween))throw TypeError("tween parameter is not ["+P.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)};H.prototype.updateBar=function(){var e=this.toolbar.output,n=this.paused?this.toolbar.value:(t.Time()-this._startTime)/this._duration;n=n>.9999?1:n<.01?0:n;var r=this._reversed?1-n:n;this.toolbar.value=r,e&&(e.value=(100*r).toFixed(2)+"%")},H.prototype.toggleEvents=function(t){this.element[t+"EventListener"]("mousemove",this.moveAction,!1),this.element[t+"EventListener"]("mouseup",this.upAction,!1)},H.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)},H.prototype.moveAction=function(){this.toolbar.updateTween.call(this)},H.prototype.downAction=function(){this.tween.playing||this.tween.start(),this.tween.paused||(this.tween.pause(),this.toolbar.toggleEvents("add"),t.Tick=cancelAnimationFrame(t.Ticker))},H.prototype.upAction=function(){this.tween.paused&&(this.tween.paused&&this.tween.resume(),this.tween._startTime=t.Time()-(this.tween._reversed?1-this.value:this.value)*this.tween._duration,this.toolbar.toggleEvents("remove"),t.Tick=requestAnimationFrame(t.Ticker))};var D=function(t){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};D.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:m,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var w in a)if(w in t.functions)if("function"==typeof t.functions[w])!a[w][n]&&(a[w][n]={}),!a[w][n][s||o]&&(a[w][n][s||o]=t.functions[w]);else for(var x in t.functions[w])!a[w][n]&&(a[w][n]={}),!a[w][n][x]&&(a[w][n][x]=t.functions[w][x]);if(t.Interpolate){for(var S in t.Interpolate){var M=t.Interpolate[S];if("function"!=typeof M||r[S])for(var T in M)"function"!=typeof M[T]||r[S]||(r[S]=M[T]);else r[S]=M}y[n]=t.Interpolate}if(t.Util)for(var C in t.Util)!b[C]&&(b[C]=t.Util[C]);return e};var R=function(t){function e(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setComponent=function(e){t.prototype.setComponent.call(this,e);var n=this,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:m,crossCheck:g},s=e.category,o=e.property,u=e.properties&&e.properties.length||e.subProperties&&e.subProperties.length;if("defaultValue"in e?(n.supports=o+" property",n.defaultValue=(e.defaultValue+"").length?"YES":"not set or incorrect"):e.defaultValues&&(n.supports=(u||o)+" "+(o||s)+" properties",n.defaultValues=Object.keys(e.defaultValues).length===u?"YES":"Not set or incomplete"),e.defaultOptions){for(var l in n.extends=[],e.defaultOptions)n.extends.push(l);n.extends.length?n.extends="with <"+n.extends.join(", ")+"> new option(s)":delete n.extends}if(e.functions){for(var c in n.interface=[],n.render=[],n.warning=[],a)c in e.functions?("prepareProperty"===c&&n.interface.push("fromTo()"),"prepareStart"===c&&n.interface.push("to()"),"onStart"===c&&(n.render="can render update")):("prepareProperty"===c&&n.warning.push("fromTo()"),"prepareStart"===c&&n.warning.push("to()"),"onStart"===c&&(n.render="no function to render update"));n.interface.length?n.interface=(s||o)+" can use ["+n.interface.join(", ")+"] method(s)":delete n.uses,n.warning.length?n.warning=(s||o)+" can't use ["+n.warning.join(", ")+"] method(s) because values aren't processed":delete n.warning}if(e.Interpolate){for(var p in n.uses=[],n.adds=[],e.Interpolate){var h=e.Interpolate[p];if("function"==typeof h)r[p]||n.adds.push(""+p),n.uses.push(""+p);else for(var f in h)"function"!=typeof h[f]||r[p]||n.adds.push(""+f),n.uses.push(""+f)}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}else n.critical="For "+(o||s)+" no interpolation function[s] is set";return e.Util&&(n.hasUtil=Object.keys(e.Util).join(",")),n},e}(D);function B(t,e,n){return(t=+t)+(e-=t)*n}function Q(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a>0)/100+"% "+(100*B(n[1],r[1],i)>>0)/100+"%"})}},X={component:"backgroundPositionProp",property:"backgroundPosition",defaultValue:[50,50],Interpolate:{numbers:B},functions:z,Util:{trueDimension:Q}};function Y(t,e,n,r){return(t=+t)+(e-=t)*r+n}function W(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=Y(n.v,r.v,r.u,i)})}x.BackgroundPosition=X;var K=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],$={};K.map((function(t){return $[t]=0}));var G={};K.forEach((function(t){G[t]=W}));var Z={component:"borderRadiusProperties",category:"borderRadius",properties:K,defaultValues:$,Interpolate:{units:Y},functions:{prepareStart:function(t){return E(this.element,t)||h[t]},prepareProperty:function(t,e){return Q(e)},onStart:G},Util:{trueDimension:Q}};function J(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(i>.99||i<.01?(10*B(n,r,i)>>0)/10:B(n,r,i)>>0)+"px"})}x.BorderRadiusProperties=Z;var tt=["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"],et={};tt.map((function(t){return et[t]=0}));var nt={};tt.map((function(t){return nt[t]=J}));var rt={component:"boxModelProperties",category:"boxModel",properties:tt,defaultValues:et,Interpolate:{numbers:B},functions:{prepareStart:function(t){return E(this.element,t)||h[t]},prepareProperty:function(t,e){var n=Q(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:nt}};x.BoxModelProperties=rt;var it={prepareStart:function(t,e){var n=E(this.element,t),r=E(this.element,"width"),i=E(this.element,"height");return/rect/.test(n)?n:[0,r,i,0]},prepareProperty:function(t,e){if(e instanceof Array)return[Q(e[0]),Q(e[1]),Q(e[2]),Q(e[3])];var n=e.replace(/rect|\(|\)/g,"");return[Q((n=/\,/g.test(n)?n.split(/\,/g):n.split(/\s/g))[0]),Q(n[1]),Q(n[2]),Q(n[3])]},onStart:function(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,e,n,r){for(var i=0,a=[];i<4;i++){var s=e[i].v,o=n[i].v,u=n[i].u||"px";a[i]=(100*B(s,o,r)>>0)/100+u}t.style.clip="rect("+a+")"})}},at={component:"clipProperty",property:"clip",defaultValue:[0,0,0,0],Interpolate:{numbers:B},functions:it,Util:{trueDimension:Q}};function st(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function ot(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?B(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*B(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function ut(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=ot(n,r,i)})}x.ClipProperty=at;var lt=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],ct={};lt.map((function(t){ct[t]="#000"}));var pt={};lt.map((function(t){return pt[t]=ut}));var ht={component:"colorProperties",category:"colors",properties:lt,defaultValues:ct,Interpolate:{numbers:B,colors:ot},functions:{prepareStart:function(t,e){return E(this.element,t)||h[t]},prepareProperty:function(t,e){return st(e)},onStart:pt},Util:{trueColor:st}};function ft(t,e,n){for(var r=[],i=0;i<3;i++)r[i]=(100*B(t[i],e[i],n)>>0)/100+"px";return"drop-shadow("+r.concat(ot(t[3],e[3],n)).join(" ")+")"}function dt(t){return t.replace("-r","R").replace("-s","S")}function vt(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++)e[n]=parseFloat(e[n]);return e[3]=st(e[3]),e}function gt(t){var e={},n=t.match(/(([a-z].*?)\(.*?\))(?=\s([a-z].*?)\(.*?\)|\s*$)/g),r="none"!==t?n:"none";if(r instanceof Array)for(var i=0,a=r.length;i>0)/100+"%)":"")+(n.blur||r.blur?"blur("+(100*B(n.blur,r.blur,i)>>0)/100+"em)":"")+(n.saturate||r.saturate?"saturate("+(100*B(n.saturate,r.saturate,i)>>0)/100+"%)":"")+(n.invert||r.invert?"invert("+(100*B(n.invert,r.invert,i)>>0)/100+"%)":"")+(n.grayscale||r.grayscale?"grayscale("+(100*B(n.grayscale,r.grayscale,i)>>0)/100+"%)":"")+(n.hueRotate||r.hueRotate?"hue-rotate("+(100*B(n.hueRotate,r.hueRotate,i)>>0)/100+"deg)":"")+(n.sepia||r.sepia?"sepia("+(100*B(n.sepia,r.sepia,i)>>0)/100+"%)":"")+(n.brightness||r.brightness?"brightness("+(100*B(n.brightness,r.brightness,i)>>0)/100+"%)":"")+(n.contrast||r.contrast?"contrast("+(100*B(n.contrast,r.contrast,i)>>0)/100+"%)":"")+(n.dropShadow||r.dropShadow?ft(n.dropShadow,r.dropShadow,i):"")})},crossCheck:function(t){if(this.valuesEnd[t])for(var e in this.valuesStart[t])this.valuesEnd[t][e]||(this.valuesEnd[t][e]=this.valuesStart[t][e])}},yt={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:B,blur:B,saturate:B,grayscale:B,brightness:B,contrast:B,sepia:B,invert:B,hueRotate:B,dropShadow:{numbers:B,colors:ot,dropShadow:ft}},functions:mt,Util:{parseDropShadow:vt,parseFilterString:gt,replaceDashNamespace:dt,trueColor:st}};x.FilterEffects=yt;var wt={},bt="htmlAttributes",xt=["fill","stroke","stop-color"];function St(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var Mt={prepareStart:function(t,e){var n={};for(var r in e){var i=St(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=xt.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=St(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(xt.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in wt)&&(wt[e]=function(t,e,n,r,i){t.setAttribute(e,ot(n,r,i))})},n[a]=st(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=Q(o).u||Q(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in wt)&&(wt[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*B(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=Q(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in wt)&&(wt[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*B(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=wt)}}},Tt={component:bt,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:B,colors:ot},functions:Mt,Util:{replaceUppercase:St,trueColor:st,trueDimension:Q}};x.HTMLAttributes=Tt;var Ct={prepareStart:function(t){return E(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*B(n,r,i)>>0)/1e3})}},_t={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:B},functions:Ct};function Et(t,e){return parseFloat(t)/100*e}function It(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function At(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a-1?At(t):"line"===t.tagName?kt(t):void 0}function Lt(t,e){var n,r,i,a,s=/path|glyph/.test(t.tagName)?t.getTotalLength():Vt(t);return e instanceof Object?e:("string"==typeof e?(e=e.split(/\,|\s/),n=/%/.test(e[0])?Et(e[0].trim(),s):parseFloat(e[0]),r=/%/.test(e[1])?Et(e[1].trim(),s):parseFloat(e[1])):void 0===e&&(a=parseFloat(E(t,"stroke-dashoffset")),i=E(t,"stroke-dasharray").split(/\,/),n=0-a,r=parseFloat(i[0])+n||s),{s:n,e:r,l:s})}x.OpacityProperty=_t;var jt={prepareStart:function(){return Lt(this.element)},prepareProperty:function(t,e){return Lt(this.element,e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){var i=(100*e.l>>0)/100,a=0-(100*B(e.s,n.s,r)>>0)/100,s=(100*B(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Ut={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:B},functions:jt,Util:{getRectLength:It,getPolyLength:At,getLineLength:kt,getCircleLength:Ot,getEllipseLength:Pt,getTotalLength:Vt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Lt,percent:Et}};function Ft(t){return t.map((function(t){return t[0].concat(t.slice(1).join(" "))})).join("")}function qt(t){return t.map((function(t){return Array.isArray(t)?qt(t):isNaN(+t)?t:+t}))}x.SVGDraw=Ut;var Nt=3;function Ht(t,e){var n=isNaN(+e)?Nt:+e;return n?t.map((function(t){return t.map((function(t,e){var r=+t,i=Math.pow(10,n);return r?r%1==0?r:Math.round(r*i)/i:t}))})):qt(t)}var Dt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Rt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Dt[n]&&(t.segments.push([e].concat(r.splice(0,Dt[n]))),Dt[n]););}var Bt="Invalid path value";function Qt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Bt+": invalid Arc flag "+e)}function zt(t){return t>=48&&t<=57}function Xt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Bt+": missing param "+t.pathValue[r];else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function Wt(t){return t>=48&&t<=57||43===t||45===t||46===t}function Kt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Dt[t.pathValue[t.index].toLowerCase()],t.index++,Yt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Xt(t):Qt(t),t.err.length)return;t.data.push(t.param),Yt(t),n=!1,t.index=t.max)break;if(!Wt(t.pathValue.charCodeAt(t.index)))break}}Rt(t)}else Rt(t);else t.err=Bt+": "+t.pathValue[t.index]+" not a path command"}function $t(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}function Gt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Dt[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Zt(t,e){if(Gt(t))return qt(t);var n=new $t(t);for(Yt(n);n.index7){t[n].shift();for(var r=t[n];r.length;)e[n]="A",t.splice(n++,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}function ee(t,e,n){var r,i;switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"H":return["L",t[1],e.y1];case"V":return["L",e.x1,t[1]];case"S":return i=function(t,e,n,r,i){return"CS".indexOf(i)>-1?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(e.x1,e.y1,e.x2,e.y2,n),e.x1=i.x1,e.y1=i.y1,["C",i.x1,i.y1].concat(t.slice(1));case"T":return r=function(t,e,n,r,i){return"QT".indexOf(i)>-1?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(e.x1,e.y1,e.qx,e.qy,n),e.qx=r.qx,e.qy=r.qy,["Q",e.qx,e.qy].concat(t.slice(1));case"Q":e.qx=t[1],e.qy=t[2]}return t}function ne(t,e){if(function(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Dt[e]===t.length-1&&/[ACLMQZ]/.test(t[0])}))}(t))return qt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o="",u=(t=Jt(t)).length,l=0;l1&&(n*=b=Math.sqrt(b),r*=b);var x=n*n,S=r*r,M=(a==s?-1:1)*Math.sqrt(Math.abs((x*S-x*w*w-S*y*y)/(x*w*w+S*y*y)));f=M*n*w/r+(t+o)/2,d=M*-r*y/n+(e+u)/2,p=Math.asin(((e-d)/r).toFixed(9)),h=Math.asin(((u-d)/r).toFixed(9)),p=th&&(p-=2*Math.PI),!s&&h>p&&(h-=2*Math.PI)}var T=h-p;if(Math.abs(T)>v){var C=h,_=o,E=u;h=p+v*(s&&h>p?1:-1),o=f+n*Math.cos(h),u=d+r*Math.sin(h),m=ie(o,u,n,r,i,0,s,_,E,[h,C,f,d])}T=h-p;var I=Math.cos(p),A=Math.sin(p),k=Math.cos(h),O=Math.sin(h),P=Math.tan(T/4),V=4/3*n*P,L=4/3*r*P,j=[t,e],U=[t+V*A,e-L*I],F=[o+V*O,u-L*k],q=[o,u];return U[0]=2*j[0]-U[0],U[1]=2*j[1]-U[1],l?[U,F,q].concat(m):(m=[U,F,q].concat(m).join().split(",")).map((function(t,e){return e%2?re(m[e-1],t,g).y:re(t,m[e+1],g).x}))}function ae(t,e,n,r,i,a){var s=1/3,o=2/3;return[s*t+o*n,s*e+o*r,s*i+o*n,s*a+o*r,i,a]}function se(t,e,n,r,i,a,s,o,u){var l=1-u;return{x:Math.pow(l,3)*t+3*Math.pow(l,2)*u*n+3*l*u*u*i+Math.pow(u,3)*s,y:Math.pow(l,3)*e+3*Math.pow(l,2)*u*r+3*l*u*u*a+Math.pow(u,3)*o}}function oe(t,e,n){var r=t[0],i=t[1];return[r+(e[0]-r)*n,i+(e[1]-i)*n]}function ue(t,e,n,r){var i=.5,a=[t,e],s=[n,r],o=oe(a,s,i),u=oe(s,o,i),l=oe(o,u,i),c=oe(u,l,i),p=oe(l,c,i),h=se.apply(0,a.concat(o,l,p,i)),f=se.apply(0,p.concat(c,u,s,0));return[h.x,h.y,f.x,f.y,n,r]}function le(t,e){switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"M":return e.x=t[1],e.y=t[2],t;case"A":return["C"].concat(ie.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"Q":return e.qx=t[1],e.qy=t[2],["C"].concat(ae.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"L":return["C"].concat(ue(e.x1,e.y1,t[1],t[2]));case"Z":return["C"].concat(ue(e.x1,e.y1,e.x,e.y))}return t}function ce(t,e){if(function(t){return Gt(t)&&t.slice(1).every((function(t){return"C"===t[0]}))}(t))return qt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o=(t=ne(t)).length,u=0;u=0}function de(t,e){e=e||.5;var n=t.slice(0,2),r=t.slice(2,4),i=t.slice(4,6),a=t.slice(6,8),s=oe(n,r,e),o=oe(r,i,e),u=oe(i,a,e),l=oe(s,o,e),c=oe(o,u,e),p=oe(l,c,e);return[["C"].concat(s,l,p),["C"].concat(c,u,a)]}function ve(t,e,n,r,i){return i*(i*(-3*t+9*e-9*n+3*r)+6*t-12*e+6*n)-3*t+3*e}function ge(t,e,n,r,i,a,s,o,u){(null===u||isNaN(+u))&&(u=1);var l=(u=u>1?1:u<0?0:u)/2,c=0,p=0,h=0,f=0,d=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472];return[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816].map((function(u,v){p=ve(t,n,i,s,c=l*u+l),h=ve(e,r,a,o,c),f+=d[v]*Math.sqrt(p*p+h*h)})),l*f}function me(t){return ce((e=Ft(Jt(t)),Ft(Jt(e,0)).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0]).map((function(t,e,n){var r=e&&n[e-1].slice(-2).concat(t.slice(1)),i=e?ge.apply(0,r):0;return{s:t,ss:e?i?de(r):[t,t]:[t],l:i}}));var e}function ye(t,e,n){var r=me(t),i=me(e),a=r.length,s=i.length,o=r.filter((function(t){return t.l})).length,u=i.filter((function(t){return t.l})).length,l=r.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/o||0,c=i.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/u||0,p=n||Math.max(a,s),h=[l,c],f=[p-a,p-s],d=0,v=[r,i].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:ye(v[0],v[1],p)}function we(t){var e=t.length,n=e-1;return t.map((function(r,i){return t.map((function(r,a){var s,o=i+a;return 0===a||t[o]&&"M"===t[o][0]?(s=t[o],["M"].concat(s.slice(-2))):(o>=e&&(o-=n),t[o])}))}))}function be(t,e){var n=t.length-1,r=[],i=0,a=we(t);return a.map((function(a,s){t.slice(1).map((function(r,a){i+=function(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))}(t[(s+a)%n].slice(-2),e[a%n].slice(-2))})),r[s]=i,i=0})),a[r.indexOf(Math.min.apply(null,r))]}var xe={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?L(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.curve?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){for(var i=[],a=e.curve,s=n.curve,o=0,u=s.length;o>0)/1e3)}t.setAttribute("d",1===r?n.original:Ft(i))})},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=ye(this.valuesStart[t].original,this.valuesEnd[t].original),i=fe(r[0])!==fe(r[1])?pe(r[0]):qt(r[0]);this.valuesStart[t].curve=i,this.valuesEnd[t].curve=be(r[1],i)}}}},Se={component:"svgCubicMorph",property:"path",defaultValue:[],Interpolate:{numbers:B,pathToString:Ft},functions:xe,Util:{pathToCurve:ce,pathToAbsolute:Jt,pathToString:Ft,parsePathString:Zt,getRotatedCurve:be,getRotations:we,equalizeSegments:ye,reverseCurve:pe,clonePath:qt,getDrawDirection:fe,splitCubic:de,getCurveArray:me}};function Me(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 Te(t){var e=t&&/\)/.test(t)?t.substring(0,t.length-1).split(/\)\s|\)/):"none",n={};if(e instanceof Array)for(var r=0,i=e.length;r>0)/1e3+(s?","+(1e3*s>>0)/1e3:"")+")":"")+(l?"rotate("+(1e3*l>>0)/1e3+")":"")+(h?"skewX("+(1e3*h>>0)/1e3+")":"")+(f?"skewY("+(1e3*f>>0)/1e3+")":"")+(1!==u?"scale("+(1e3*u>>0)/1e3+")":""))})},crossCheck:function(t){if(this._resetStart&&this.valuesEnd[t]){var e=this.valuesStart[t],n=this.valuesEnd[t],r=Ce.call(this,t,Te(this.element.getAttribute("transform")));for(var i in r)e[i]=r[i];var a=this.element.ownerSVGElement,s=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]));for(var o in e.translate=[s.matrix.e,s.matrix.f],e)o in n&&"origin"!==o||(n[o]=e[o])}}},Ee={component:"svgTransformProperty",property:"svgTransform",defaultOptions:{transformOrigin:"50% 50%"},defaultValue:{translate:0,rotate:0,skewX:0,skewY:0,scale:1},Interpolate:{numbers:B},functions:_e,Util:{parseStringOrigin:Me,parseTransformString:Te,parseTransformSVG:Ce}};x.SVGTransformProperty=Ee;var Ie=function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});document.addEventListener("DOMContentLoaded",(function t(){document.removeEventListener("DOMContentLoaded",t,e)}),e)}catch(t){}return t}(),Ae="onmouseleave"in document?["mouseenter","mouseleave"]:["mouseover","mouseout"],ke="ontouchstart"in window||navigator.msMaxTouchPoints||!1?"touchstart":"mousewheel",Oe=navigator&&/(EDGE|Mac)/i.test(navigator.userAgent)?document.body:document.documentElement,Pe=!!Ie&&{passive:!1};function Ve(t){this.scrolling&&t.preventDefault()}function Le(){var t=this.element;return t===Oe?{el:document,st:document.body}:{el:t,st:t}}function je(t,e){e[t](Ae[0],Ve,Pe),e[t](ke,Ve,Pe)}function Ue(){var t=Le.call(this);"scroll"in this.valuesEnd&&!t.el.scrolling&&(t.el.scrolling=1,je("addEventListener",t.el),t.st.style.pointerEvents="none")}function Fe(){var t=Le.call(this);"scroll"in this.valuesEnd&&t.el.scrolling&&(t.el.scrolling=0,je("removeEventListener",t.el),t.st.style.pointerEvents="")}var qe={prepareStart:function(){return this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Oe,this.element===Oe?window.pageYOffset||Oe.scrollTop:this.element.scrollTop},prepareProperty:function(t,e){return parseInt(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(this.element=!("scroll"in this.valuesEnd)||this.element&&this.element!==window?this.element:Oe,Ue.call(this),t[e]=function(t,e,n,r){t.scrollTop=B(e,n,r)>>0})},onComplete:function(t){Fe.call(this)}},Ne={component:"scrollProperty",property:"scroll",defaultValue:0,Interpolate:{numbers:B},functions:qe,Util:{preventScroll:Ve,scrollIn:Ue,scrollOut:Fe,getScrollTargets:Le,toggleScrollEvents:je,supportPassive:Ie}};function He(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){for(var a=[],s="textShadow"===e?3:4,o=3===s?n[3]:n[4],u=3===s?r[3]:r[4],l=!!(n[5]&&"none"!==n[5]||r[5]&&"none"!==r[5])&&" inset",c=0;c>0)/1e3+"px");t.style[e]=l?ot(o,u,i)+a.join(" ")+l:ot(o,u,i)+a.join(" ")})}x.ScrollProperty=Ne;var De=["boxShadow","textShadow"];function Re(t,e){var n,r;for(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),r=0;r<4;r++)n[r]=parseFloat(n[r]);return n[4]=st(n[4]),n="boxShadow"===e?n:n.filter((function(t,e){return[0,1,2,4].indexOf(e)>-1}))}var Be={};De.map((function(t){return Be[t]=He}));var Qe={component:"shadowProperties",properties:De,defaultValues:{boxShadow:"0px 0px 0px 0px rgb(0,0,0)",textShadow:"0px 0px 0px rgb(0,0,0)"},Interpolate:{numbers:B,colors:ot},functions:{prepareStart:function(t,e){var n=E(this.element,t);return/^none$|^initial$|^inherit$|^inset$/.test(n)?h[t]:n},prepareProperty:function(t,e){if("string"==typeof e){var n,r="none";r=/inset/.test(e)?"inset":r,n=(e=/inset/.test(e)?e.replace(/(\s+inset|inset+\s)/g,""):e).match(/(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi),e=Re(e=e.replace(n[0],"").split(" ").concat([n[0].replace(/\s/g,"")],[r]),t)}else e instanceof Array&&(e=Re(e,t));return e},onStart:Be},Util:{processShadowArray:Re,trueColor:st}};function ze(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=Y(n.v,r.v,r.u,i)})}x.ShadowProperties=Qe;var Xe=["fontSize","lineHeight","letterSpacing","wordSpacing"],Ye={};Xe.forEach((function(t){Ye[t]=ze}));var We={component:"textProperties",category:"textProperties",properties:Xe,defaultValues:{fontSize:0,lineHeight:0,letterSpacing:0,wordSpacing:0},Interpolate:{units:Y},functions:{prepareStart:function(t){return E(this.element,t)||h[t]},prepareProperty:function(t,e){return Q(e)},onStart:Ye},Util:{trueDimension:Q}};x.TextProperties=We;var Ke=String("abcdefghijklmnopqrstuvwxyz").split(""),$e=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),Ge=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),Ze=String("0123456789").split(""),Je=Ke.concat($e,Ze),tn=Je.concat(Ge),en={alpha:Ke,upper:$e,symbols:Ge,numeric:Ze,alphanumeric:Je,all:tn},nn={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in en?en[n]:n&&n.length?n:en[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=B(e,n,r)>>0})}};function rn(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function an(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3;return r}x.TextWriteProperties=sn;var un="undefined"!=typeof DOMMatrix?DOMMatrix:"undefined"!=typeof WebKitCSSMatrix?WebKitCSSMatrix:"undefined"!=typeof CSSMatrix?CSSMatrix:"undefined"!=typeof MSCSSMatrix?MSCSSMatrix:null,ln="transformMatrix";var cn={component:ln,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={};if(this.element.transformMatrix){var r=this.element.transformMatrix;for(var i in r)n[i]=r[i]}else for(var a in e)n[a]="perspective"===a?e[a]:h.transform[a];return n},prepareProperty:function(t,e){if("object"==typeof e&&!e.length){var n,r={},i={},a={},s={},o={},u=[{translate3d:i},{rotate3d:a},{skew:o},{scale3d:s}],l=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)})),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)){(/translate/.test(t)?i:/rotate/.test(t)?a:/scale/.test(t)?s:/skew/.test(t)?o:{})[t.replace(/translate|rotate|scale|skew/,"").toLowerCase()]=/scale/.test(t)?parseFloat(e[t]):parseInt(e[t])}else"skew"===t?(n=e[t].map((function(t){return parseInt(t)||0})),r[t]=[n[0]||0,n[1]||0]):r[t]=parseInt(e[t])};for(var c in e)l(c);return u.map((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}console.error('KUTE.js - "'+e+'" is not valid/supported transform function')},onStart:{transform:function(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){var a=new un,s={};for(var o in r)s[o]="perspective"===o?B(n[o],r[o],i):on(n[o],r[o],i);s.perspective&&(a.m34=-1/s.perspective),a=s.translate3d?a.translate(s.translate3d[0],s.translate3d[1],s.translate3d[2]):a,a=s.rotate3d?a.rotate(s.rotate3d[0],s.rotate3d[1],s.rotate3d[2]):a,s.skew&&(a=s.skew[0]?a.skewX(s.skew[0]):a,a=s.skew[1]?a.skewY(s.skew[1]):a),a=s.scale3d?a.scale(s.scale3d[0],s.scale3d[1],s.scale3d[2]):a,t.style[e]=a.toString()})},CSS3Matrix:function(e){this.valuesEnd.transform&&!t[e]&&(t[e]=un)}},onComplete:function(t){if(this.valuesEnd[t])for(var e in this.element.transformMatrix={},this.valuesEnd[t])this.element.transformMatrix[e]=this.valuesEnd[t][e]},crossCheck:function(t){this.valuesEnd[t]&&this.valuesEnd[t].perspective&&!this.valuesStart[t].perspective&&(this.valuesStart[t].perspective=this.valuesEnd[t].perspective)}},Interpolate:{perspective:B,translate3d:on,rotate3d:on,skew:on,scale3d:on}};for(var pn in x.TransformMatrix=cn,x){var hn=x[pn];x[pn]=new R(hn)}return{Animation:R,Components:x,Tween:q,fromTo:function(t,e,n,r){return r=r||{},new P.tween(L(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new P.tween(L(t),e,e,n)},TweenCollection:N,ProgressBar:H,allFromTo:function(t,e,n,r){return r=r||{},new N(L(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new N(L(t,!0),e,e,n)},Objects:w,Util:b,Easing:V,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:C,Selector:L,Version:"2.0.16"}})); diff --git a/demo/src/kute.min.js b/demo/src/kute.min.js index ef8f16c..e849259 100644 --- a/demo/src/kute.min.js +++ b/demo/src/kute.min.js @@ -1,2 +1,2 @@ -// KUTE.js Standard v2.0.15 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function U(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);T.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var H=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:L.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};H.prototype.start=function(e){return _(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),U.call(this),this._startFired=!0),!s&&o(),this},H.prototype.stop=function(){return this.playing&&(C(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},H.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},H.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},H.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},H.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},L.tween=H,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var N=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(M.call(this,i,"end"),this._resetStart?this.valuesStart=r:M.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,I.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),U.call(this),this._startTime+=t.Time()-this._pauseTime,_(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(C(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(H);L.tween=N;var j=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new L.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};j.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},j.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},j.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},j.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},j.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof j)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},j.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},j.prototype.removeTweens=function(){this.tweens=[]},j.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function R(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a.99||i<.01?(10*D(n,r,i)>>0)/10:D(n,r,i)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var b in a)if(b in t.functions)if("function"==typeof t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][s||o]&&(a[b][n][s||o]=t.functions[b]);else for(var x in t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][x]&&(a[b][n][x]=t.functions[b][x]);if(t.Interpolate){for(var _ in t.Interpolate){var C=t.Interpolate[_];if("function"!=typeof C||r[_])for(var T in C)"function"!=typeof C[T]||r[_]||(r[_]=C[T]);else r[_]=C}m[n]=t.Interpolate}if(t.Util)for(var S in t.Util)!w[S]&&(w[S]=t.Util[S]);return e};var X=["top","left","width","height"],B={};X.map((function(t){return B[t]=Q}));var z={component:"essentialBoxModel",category:"boxModel",properties:X,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:D},functions:{prepareStart:function(t){return A(this.element,t)||h[t]},prepareProperty:function(t,e){var n=R(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:B},Util:{trueDimension:R}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function q(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?D(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*D(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=q(n,r,i)})}x.BoxModelEssential=z;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var G={};K.map((function(t){return G[t]=Y}));var W={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:D,colors:q},functions:{prepareStart:function(t,e){return A(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:G},Util:{trueColor:Z}};x.ColorProperties=W;var J={},tt="htmlAttributes",et=["fill","stroke","stop-color"];function nt(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var rt={prepareStart:function(t,e){var n={};for(var r in e){var i=nt(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=et.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=nt(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(et.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,q(n,r,i))})},n[a]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=R(o).u||R(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*D(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=R(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*D(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},it={component:tt,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:q},functions:rt,Util:{replaceUppercase:nt,trueColor:Z,trueDimension:R}};x.HTMLAttributes=it;var at={prepareStart:function(t){return A(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*D(n,r,i)>>0)/1e3})}},st={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:D},functions:at};x.OpacityProperty=st;var ot=String("abcdefghijklmnopqrstuvwxyz").split(""),ut=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),lt=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ct=String("0123456789").split(""),pt=ot.concat(ut,ct),ht=pt.concat(lt),ft={alpha:ot,upper:ut,symbols:lt,numeric:ct,alphanumeric:pt,all:ht},dt={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ft?ft[n]:n&&n.length?n:ft[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=D(e,n,r)>>0})}};function vt(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function gt(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function bt(t,e,n,r){for(var i=[],a=0;a<3;a++)i[a]=(t[a]||e[a]?(1e3*(t[a]+(e[a]-t[a])*r)>>0)/1e3:0)+n;return"translate3d("+i.join(",")+")"}function wt(t,e,n,r){var i="";return i+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",i+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",i+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function xt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function _t(t,e,n,r){var i=[];return i[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+i.join(",")+")"}x.TextWriteProperties=yt;var Ct={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,e){var n=E(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},i=[],a=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?i:"rotate"===c?a:"skew"===c?s:{},d=0;d>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+i.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:xt,skew:_t}};function Tt(t,e){return parseFloat(t)/100*e}function St(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Et(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a>0)/100,a=0-(100*D(e.s,n.s,r)>>0)/100,s=(100*D(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Pt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:D},functions:Lt,Util:{getRectLength:St,getPolyLength:Et,getLineLength:At,getCircleLength:Mt,getEllipseLength:It,getTotalLength:kt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Ot,percent:Tt}};function Vt(t,e,n,r){for(var i=[],a=0;a>0)/1e3)}return i}function Ut(t){return t.map((function(t){return Array.isArray(t)?Ut(t):isNaN(+t)?t:+t}))}x.SVGDraw=Pt;var Ht=3;function Nt(t){return t.map((function(t){return t.map((function(t,e){var n=+t,r=Math.pow(10,Ht);return e?n%1==0?n:(n*r>>0)/r:t}))}))}function jt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}var Ft={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Rt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Ft[n]&&(t.segments.push([e].concat(r.splice(0,Ft[n]))),Ft[n]););}var Dt="Invalid path value";function Qt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Dt)}function Xt(t){return t>=48&&t<=57}function Bt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Dt;else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=48&&t<=57||43===t||45===t||46===t}function Zt(t){for(;t.index=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function qt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Ft[t.pathValue[t.index].toLowerCase()],t.index++,Zt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Bt(t):Qt(t),t.err.length)return;t.data.push(t.param),Zt(t),n=!1,t.index=t.max)break;if(!zt(t.pathValue.charCodeAt(t.index)))break}}Rt(t)}else Rt(t);else t.err=Dt}function Yt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Kt(t,e){for(var n=[],r=0,i=t.length;i-2*!e>r;r+=2){var a=[{x:+t[r-2],y:+t[r-1]},{x:+t[r],y:+t[r+1]},{x:+t[r+2],y:+t[r+3]},{x:+t[r+4],y:+t[r+5]}];e?r?i-4==r?a[3]={x:+t[0],y:+t[1]}:i-2==r&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[i-2],y:+t[i-1]}:i-4==r?a[3]=a[2]:r||(a[0]={x:+t[r],y:+t[r+1]}),n.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return n}function $t(t,e,n,r,i){var a;if(null==i&&null==r&&(r=n),t=+t,e=+e,n=+n,r=+r,null!=i){var s=Math.PI/180,o=t+n*Math.cos(-r*s),u=t+n*Math.cos(-i*s);a=[["M",o,e+n*Math.sin(-r*s)],["A",n,n,0,+(i-r>180),0,u,e+n*Math.sin(-i*s)]]}else a=[["M",t,e],["m",0,-r],["a",n,r,0,1,1,0,2*r],["a",n,r,0,1,1,0,-2*r],["z"]];return a}function Gt(t){if(Yt(e=t)&&e.every((function(t){return t[0]===t[0].toUpperCase()})))return Ut(t);var e;t=function(t){if(Yt(t))return Ut(t);var e=new jt(t),n=e.max;for(Zt(e);e.index-1?t.getAttribute("d"):t;return e.setAttribute("d",n),e}function te(t){for(var e,n=-1,r=t.length,i=t[r-1],a=0;++n0&&(o=Math.max(o,Math.ceil(n/e)));for(var u=0;ue;)i=ie(r,i,.5),t.splice(n+1,0,i)}function he(t,e){var n,r;if("string"==typeof t){var i=se(t,e);t=i.ring,r=i.skipBisect}else if(!Array.isArray(t))throw Dt;if(!fe(n=t.slice(0)))throw Dt;return n.length>1&&ae(n[0],n[n.length-1])&&n.pop(),te(n)>0&&n.reverse(),!r&&e&&ne(e)&&e>0&&pe(n,e),n}function fe(t){return t.every((function(t){return Array.isArray(t)&&t.length>=2&&ne(t[0])&&ne(t[1])}))}function de(t,e,n){var r=he(t,n=n||f.morphPrecision),i=he(e,n),a=r.length-i.length;return ce(r,a<0?-1*a:0),ce(i,a>0?a:0),le(r,i),[r,i]}var ve={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var i=e.pathArray,a=n.pathArray,s=a.length;t.setAttribute("d",1===r?n.original:"M"+Vt(i,a,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=de(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},ge={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Vt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:ve,Util:{addPoints:ce,bisect:pe,normalizeRing:he,validRing:fe,getInterpolationPoints:de,pathStringToRing:se,isFiniteNumber:ne,distanceSquareRoot:re,pointAlong:ie,samePoint:ae,exactRing:oe,approximateRing:ue,createPath:Jt,rotateRing:le,pathToAbsolute:Gt,pathToString:Wt,polygonLength:ee,polygonArea:te}};for(var ye in x.SVGMorph=ge,x){var me=x[ye];x[ye]=new F(me)}return{Animation:F,Components:x,Tween:N,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:j,allFromTo:function(t,e,n,r){return r=r||{},new j(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new j(V(t,!0),e,e,n)},Objects:b,Util:w,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:S,Selector:V,Version:"2.0.15"}})); +// KUTE.js Standard v2.0.16 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function q(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);C.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var N=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:L.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};N.prototype.start=function(e){return M(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),q.call(this),this._startFired=!0),!s&&o(),this},N.prototype.stop=function(){return this.playing&&(_(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},N.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},N.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},N.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},N.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},L.tween=N,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var j=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(A.call(this,i,"end"),this._resetStart?this.valuesStart=r:A.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,E.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),q.call(this),this._startTime+=t.Time()-this._pauseTime,M(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(_(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(N);L.tween=j;var H=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new L.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};H.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},H.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},H.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},H.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},H.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof H)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},H.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},H.prototype.removeTweens=function(){this.tweens=[]},H.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function U(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a.99||i<.01?(10*Q(n,r,i)>>0)/10:Q(n,r,i)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var x in a)if(x in t.functions)if("function"==typeof t.functions[x])!a[x][n]&&(a[x][n]={}),!a[x][n][s||o]&&(a[x][n][s||o]=t.functions[x]);else for(var w in t.functions[x])!a[x][n]&&(a[x][n]={}),!a[x][n][w]&&(a[x][n][w]=t.functions[x][w]);if(t.Interpolate){for(var M in t.Interpolate){var _=t.Interpolate[M];if("function"!=typeof _||r[M])for(var C in _)"function"!=typeof _[C]||r[M]||(r[M]=_[C]);else r[M]=_}m[n]=t.Interpolate}if(t.Util)for(var T in t.Util)!b[T]&&(b[T]=t.Util[T]);return e};var R=["top","left","width","height"],X={};R.map((function(t){return X[t]=D}));var B={component:"essentialBoxModel",category:"boxModel",properties:R,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:Q},functions:{prepareStart:function(t){return I(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:X},Util:{trueDimension:U}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function z(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?Q(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*Q(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=z(n,r,i)})}w.BoxModelEssential=B;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var W={};K.map((function(t){return W[t]=Y}));var G={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:Q,colors:z},functions:{prepareStart:function(t,e){return I(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:W},Util:{trueColor:Z}};w.ColorProperties=G;var J={},tt="htmlAttributes",et=["fill","stroke","stop-color"];function nt(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var rt={prepareStart:function(t,e){var n={};for(var r in e){var i=nt(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=et.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=nt(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(et.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,z(n,r,i))})},n[a]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=U(o).u||U(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*Q(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=U(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*Q(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},it={component:tt,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:z},functions:rt,Util:{replaceUppercase:nt,trueColor:Z,trueDimension:U}};w.HTMLAttributes=it;var at={prepareStart:function(t){return I(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*Q(n,r,i)>>0)/1e3})}},st={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:Q},functions:at};w.OpacityProperty=st;var ot=String("abcdefghijklmnopqrstuvwxyz").split(""),ut=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),lt=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ct=String("0123456789").split(""),pt=ot.concat(ut,ct),ht=pt.concat(lt),ft={alpha:ot,upper:ut,symbols:lt,numeric:ct,alphanumeric:pt,all:ht},dt={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ft?ft[n]:n&&n.length?n:ft[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=Q(e,n,r)>>0})}};function vt(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function gt(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function xt(t,e,n,r){for(var i=[],a=0;a<3;a++)i[a]=(t[a]||e[a]?(1e3*(t[a]+(e[a]-t[a])*r)>>0)/1e3:0)+n;return"translate3d("+i.join(",")+")"}function bt(t,e,n,r){var i="";return i+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",i+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",i+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function wt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function Mt(t,e,n,r){var i=[];return i[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+i.join(",")+")"}w.TextWriteProperties=yt;var _t={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,e){var n=S(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},i=[],a=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?i:"rotate"===c?a:"skew"===c?s:{},d=0;d>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+i.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:wt,skew:Mt}};function Ct(t,e){return parseFloat(t)/100*e}function Tt(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function St(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a-1?St(t):"line"===t.tagName?It(t):void 0}function Ot(t,e){var n,r,i,a,s=/path|glyph/.test(t.tagName)?t.getTotalLength():kt(t);return e instanceof Object?e:("string"==typeof e?(e=e.split(/\,|\s/),n=/%/.test(e[0])?Ct(e[0].trim(),s):parseFloat(e[0]),r=/%/.test(e[1])?Ct(e[1].trim(),s):parseFloat(e[1])):void 0===e&&(a=parseFloat(I(t,"stroke-dashoffset")),i=I(t,"stroke-dasharray").split(/\,/),n=0-a,r=parseFloat(i[0])+n||s),{s:n,e:r,l:s})}w.TransformFunctions=_t;var Lt={prepareStart:function(){return Ot(this.element)},prepareProperty:function(t,e){return Ot(this.element,e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){var i=(100*e.l>>0)/100,a=0-(100*Q(e.s,n.s,r)>>0)/100,s=(100*Q(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Pt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:Q},functions:Lt,Util:{getRectLength:Tt,getPolyLength:St,getLineLength:It,getCircleLength:At,getEllipseLength:Et,getTotalLength:kt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Ot,percent:Ct}};function Vt(t,e,n,r){for(var i=[],a=0;a>0)/1e3)}return i}w.SVGDraw=Pt;var qt=3;function Nt(t){return t.map((function(t){return Array.isArray(t)?Nt(t):isNaN(+t)?t:+t}))}function jt(t,e){var n=isNaN(+e)?qt:+e;return n?t.map((function(t){return t.map((function(t,e){var r=+t,i=Math.pow(10,n);return r?r%1==0?r:Math.round(r*i)/i:t}))})):Nt(t)}function Ht(t,e,n){if(t[n].length>7){t[n].shift();for(var r=t[n];r.length;)e[n]="A",t.splice(n++,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Ft={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Ut(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Qt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Ft[n]&&(t.segments.push([e].concat(r.splice(0,Ft[n]))),Ft[n]););}var Dt="Invalid path value";function Rt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Dt+": invalid Arc flag "+e)}function Xt(t){return t>=48&&t<=57}function Bt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Dt+": missing param "+t.pathValue[r];else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function zt(t){return t>=48&&t<=57||43===t||45===t||46===t}function Yt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Ft[t.pathValue[t.index].toLowerCase()],t.index++,Zt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Bt(t):Rt(t),t.err.length)return;t.data.push(t.param),Zt(t),n=!1,t.index=t.max)break;if(!zt(t.pathValue.charCodeAt(t.index)))break}}Qt(t)}else Qt(t);else t.err=Dt+": "+t.pathValue[t.index]+" not a path command"}function Kt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}function $t(t,e){if(Ut(n=t)&&n.every((function(t){return t[0]===t[0].toUpperCase()})))return Nt(t);var n;t=function(t,e){if(Ut(t))return Nt(t);var n=new Kt(t);for(Zt(n);n.index-1?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(e.x1,e.y1,e.x2,e.y2,n),e.x1=i.x1,e.y1=i.y1,["C",i.x1,i.y1].concat(t.slice(1));case"T":return r=function(t,e,n,r,i){return"QT".indexOf(i)>-1?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(e.x1,e.y1,e.qx,e.qy,n),e.qx=r.qx,e.qy=r.qy,["Q",e.qx,e.qy].concat(t.slice(1));case"Q":e.qx=t[1],e.qy=t[2]}return t}function Gt(t,e){if(function(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[ACLMQZ]/.test(t[0])}))}(t))return Nt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o="",u=(t=$t(t)).length,l=0;l1&&(n*=b=Math.sqrt(b),r*=b);var w=n*n,M=r*r,_=(a==s?-1:1)*Math.sqrt(Math.abs((w*M-w*x*x-M*m*m)/(w*x*x+M*m*m)));f=_*n*x/r+(t+o)/2,d=_*-r*m/n+(e+u)/2,p=Math.asin(((e-d)/r).toFixed(9)),h=Math.asin(((u-d)/r).toFixed(9)),p=th&&(p-=2*Math.PI),!s&&h>p&&(h-=2*Math.PI)}var C=h-p;if(Math.abs(C)>v){var T=h,S=o,I=u;h=p+v*(s&&h>p?1:-1),o=f+n*Math.cos(h),u=d+r*Math.sin(h),y=te(o,u,n,r,i,0,s,S,I,[h,T,f,d])}C=h-p;var A=Math.cos(p),E=Math.sin(p),k=Math.cos(h),O=Math.sin(h),L=Math.tan(C/4),P=4/3*n*L,V=4/3*r*L,q=[t,e],N=[t+P*E,e-V*A],j=[o+P*O,u-V*k],H=[o,u];return N[0]=2*q[0]-N[0],N[1]=2*q[1]-N[1],l?[N,j,H].concat(y):(y=[N,j,H].concat(y).join().split(",")).map((function(t,e){return e%2?Jt(y[e-1],t,g).y:Jt(t,y[e+1],g).x}))}function ee(t,e,n,r,i,a){var s=1/3,o=2/3;return[s*t+o*n,s*e+o*r,s*i+o*n,s*a+o*r,i,a]}function ne(t,e,n,r,i,a,s,o,u){var l=1-u;return{x:Math.pow(l,3)*t+3*Math.pow(l,2)*u*n+3*l*u*u*i+Math.pow(u,3)*s,y:Math.pow(l,3)*e+3*Math.pow(l,2)*u*r+3*l*u*u*a+Math.pow(u,3)*o}}function re(t,e,n){var r=t[0],i=t[1];return[r+(e[0]-r)*n,i+(e[1]-i)*n]}function ie(t,e,n,r){var i=.5,a=[t,e],s=[n,r],o=re(a,s,i),u=re(s,o,i),l=re(o,u,i),c=re(u,l,i),p=re(l,c,i),h=ne.apply(0,a.concat(o,l,p,i)),f=ne.apply(0,p.concat(c,u,s,0));return[h.x,h.y,f.x,f.y,n,r]}function ae(t,e){switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"M":return e.x=t[1],e.y=t[2],t;case"A":return["C"].concat(te.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"Q":return e.qx=t[1],e.qy=t[2],["C"].concat(ee.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"L":return["C"].concat(ie(e.x1,e.y1,t[1],t[2]));case"Z":return["C"].concat(ie(e.x1,e.y1,e.x,e.y))}return t}function se(t,e){if(function(t){return Ut(t)&&t.slice(1).every((function(t){return"C"===t[0]}))}(t))return Nt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o=(t=Gt(t)).length,u=0;u1?1:u<0?0:u)/2,c=0,p=0,h=0,f=0,d=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472];return[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816].map((function(u,v){p=ue(t,n,i,s,c=l*u+l),h=ue(e,r,a,o,c),f+=d[v]*Math.sqrt(p*p+h*h)})),l*f}function ce(t){var e=0;return se(t).map((function(t,n,r){e+="M"!==t[0]?le.apply(0,r[n-1].slice(-2).concat(t.slice(1))):0})),e}function pe(t,e){var n,r,i=0;return se(t).map((function(t,a,s){return r=a?s[a-1].slice(-2).concat(t.slice(1)):t.slice(1),n=a?le.apply(0,r):0,i+=n,0===a?{x:r[0],y:r[1]}:i>e&&e>i-n?ne.apply(0,r.concat(1-(i-e)/n)):null})).filter((function(t){return t})).slice(-1)[0]}function he(t,e,n,r,i,a,s,o){return 3*((o-e)*(n+i)-(s-t)*(r+a)+r*(t-i)-n*(e-a)+o*(i+t/3)-s*(a+e/3))/20}function fe(t){return function(t){var e=0,n=0,r=0,i=0,a=0;return se(t).map((function(t){var s;switch(t[0]){case"M":case"Z":return r="M"===t[0]?t[1]:r,i="M"===t[0]?t[2]:i,e=r,n=i,0;default:return a=he.apply(0,[e,n].concat(t.slice(1))),s=t.slice(-2),e=s[0],n=s[1],a}})).reduce((function(t,e){return t+e}),0)}(se(t))>=0}function de(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))}function ve(t){return t.reduce((function(e,n,r){return r?e+de(t[r-1],n):0}),0)}function ge(t,e){var n=Gt(t,0);return function(t){var e=[],n=[],r="",i=t.length,a=0;if(!t.length||"M"!==t[0][0])return!1;for(var s=0;s-1))return!1;e.push([n[1],n[2]])}return a=ve(e),!!i&&{ring:e,pathLength:a}}(n)||ye(n,e)}function ye(t,e){var n,r,i=se((r=oe(t),oe($t(r,0)).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0],4),a=ce(i),s=[],o=3;e&&!isNaN(e)&&+e>0&&(o=Math.max(o,Math.ceil(a/e)));for(var u=0;ue;)r=re(n,r,.5),t.splice(i+1,0,r)}function we(t,e){var n,r,i;if("string"==typeof t){var a=ge(t,e);t=a.ring,r=a.skipBisect,i=a.pathLength}else if(!Array.isArray(t))throw Dt;if((n=t.slice(0)).pathLength=i,!Me(n))throw Dt;return n.length>1&&de(n[0],n[n.length-1])<1e-9&&n.pop(),!r&&e&&!isNaN(e)&&+e>0&&be(n,e),n}function Me(t){return Array.isArray(t)&&t.every((function(t){return Array.isArray(t)&&2===t.length&&!isNaN(t[0])&&!isNaN(t[1])}))}function _e(t,e,n){var r=we(t,n=n||f.morphPrecision),i=we(e,n),a=r.length-i.length;return xe(r,a<0?-1*a:0),xe(i,a>0?a:0),me(r,i),[jt(r),jt(i)]}var Ce={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var i=e.pathArray,a=n.pathArray,s=a.length;t.setAttribute("d",1===r?n.original:"M"+Vt(i,a,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=_e(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},Te={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Vt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:Ce,Util:{addPoints:xe,bisect:be,normalizeRing:we,validRing:Me,getInterpolationPoints:_e,pathStringToRing:ge,distanceSquareRoot:de,midPoint:re,approximateRing:ye,rotateRing:me,pathToString:oe,pathToCurve:se,getPathLength:ce,getPointAtLength:pe,getDrawDirection:fe,roundPath:jt}};for(var Se in w.SVGMorph=Te,w){var Ie=w[Se];w[Se]=new F(Ie)}return{Animation:F,Components:w,Tween:j,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:H,allFromTo:function(t,e,n,r){return r=r||{},new H(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new H(V(t,!0),e,e,n)},Objects:x,Util:b,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:T,Selector:V,Version:"2.0.16"}})); diff --git a/demo/svgCubicMorph.html b/demo/svgCubicMorph.html index 15549a4..5e2a2bd 100644 --- a/demo/svgCubicMorph.html +++ b/demo/svgCubicMorph.html @@ -26,95 +26,96 @@ -
+
- +
+

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.

+
+ +
-

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 main difference with the other SVG Morph component is the fact that this components is using some path processing scripts borrowed from - Raphael.js and other libraries to convert all path commands to cubicBezierTo path commands.

+
+
+

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.

-

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.

-
+ 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. 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.

+
+

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"/>
+<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:

+

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

// the fromTo() method
 var tween = KUTE.fromTo('#rectangle', {path: '#rectangle' }, { path: '#star' }).start();
@@ -126,44 +127,55 @@ var tween = KUTE.to('#rectangle', { path: '#star' }).start();
 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:

+

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 -
+
+ + + + + + + + + + + + +
+ Start
+
-

The second blue shape and its corresponding end shape have been edited by adding additional curve points using a vector graphics editor to match the amount of points in both shapes as well as to optimize their travel - distance during the animation. You can use the same technique on your shapes to control the animation to your style.

- -

Chris Coyier wrote an excelent article in which he explains how SVG morphing animation works, from concept, terminology and workflow.

+

Some takeaways:

+
    +
  • The red shape and its corresponding end shape are both the originals, un-edited shapes, both have the Z path command, notice a strange line at the bottom-right of the rectangle + during the animation. We'll have another example about that line.
  • +
  • The olive shape and its corresponding end shape both have been edited by removing the Z path command, notice the strange line during the animation is gone, also a different + presentation.
  • +
  • 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, our shapes here happen to be OK without it.

+

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 morphing animation example is a transition from a line into a circle and this example is to showcase the component's behavior when one of the paths is not closed (it doesn't have the Z path command), - while the other path is closed.

+

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 300L590 300"/>
-  <path id="star" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
+<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>
 
-

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

-
// the fromTo() method
 var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
 // OR
@@ -171,212 +183,233 @@ var tween = KUTE.fromTo('#line', {path: '#line' }, { path: '#circle' }).start();
 var tween = KUTE.to('#line', { path: '#circle' }).start();
 
-
- - - - - - - - -
- Start -
+
+ + + + + + + + + + + + + + + + +
+ Start
+
-

The functionality of this component is different from the svgMorph component in the sense that it will animate shapes as authored. In the above example, the orange line is closed - while the green line is not, and the animation is different.

+

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 and its corresponding shape are both closed, this makes the last Z path command behave like a regular + line, perhaps not the best visual presentation;
  • +
  • the green line is not closed, but its corresponding shape is, still the Z path command seems to cause trouble, while + the presentation looks a bit different;
  • +
  • the blue line is now closed, but its corresponding shape isn't and with the Z path command missing from the second shape, + the animation looks significantly better;
  • +
  • the red line and its corresponding shape are both not closed, another combination that delivers excellent outcome.
  • +
+

As you can see, this is another case where easy steps can be made to optimize the visual presentation. Keep in mind that stroke attributes like + stroke-linejoin such can have a small impact on your animation, particularly on start and end.

-

Subpath Example

-

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

+

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"/>
+<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.

+

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:

+

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 convertToPath 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 something like SVGPath tools 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.
  • -
-
- - - +

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 convertToPath 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 index bcf5d97..24090c5 100644 --- a/demo/svgDraw.html +++ b/demo/svgDraw.html @@ -2,104 +2,104 @@ - - - - - - - - - + + + + + + + + + - KUTE.js SVG Draw + KUTE.js SVG Draw - - + + - - + + - - + + -
+
- + +
+
+
+

SVG Draw

+

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

+
+ +
-

Examples

+
+
+

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%'});
@@ -112,53 +112,53 @@ 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.
  • -
-
- - - - +

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 index adf3f8c..8dddb13 100644 --- a/demo/svgMorph.html +++ b/demo/svgMorph.html @@ -89,8 +89,8 @@

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 applies to inline SVGPathElement shapes and doesn't care if these shapes are closed (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 +

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 @@ -98,7 +98,7 @@

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 transition from closed to and from un-closed shapes.

+ improve the path processing and enable you to prepare your path strings in Node.js.

@@ -166,7 +166,7 @@ var tween = KUTE.to('#rectangle', { path: 'M301.113,12.011l99.25,179.996l201.864
<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="star" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
+  <path id="circle" style="visibility:hidden" d="M10,300a290,290 0 1,0 580,0a290,290 0 1,0 -580,0z"/>
 </svg>
 
@@ -181,12 +181,12 @@ var tween = KUTE.to('#line', { path: '#circle' }).start();
- + - - + +
Start @@ -383,8 +383,8 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start();
  • 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 something like SVGPath tools to - apply a scale transformation to your shapes' path commands.
  • +
  • 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.
  • @@ -419,7 +419,8 @@ var tween2 = KUTE.to('#triangle', { path: '#square' }).start(); - + + diff --git a/demo/svgTransform.html b/demo/svgTransform.html index b279519..f5aa543 100644 --- a/demo/svgTransform.html +++ b/demo/svgTransform.html @@ -1,209 +1,209 @@ - - - - - - - - - + + + + + + + + + - KUTE.js SVG Transform + 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.

    +
    + +
    -

    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.

    +
    +
    +
    -

    Overview

    -

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

    +

    Options

    +

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

    -

    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:

    +

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

    +
      -
    • 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.
    • +
    • 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 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.

    + +

    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.

    -
    -
    -
    -

    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.
    • -
    +
    + +

    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:

    +

    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 
    -    }
    +'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] 
    -    } 
    -  }
    +'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.

    +

    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:

    +

    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.

    +
    + 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.

    +

    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:

    +

    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
    @@ -223,166 +223,166 @@ var OriginY = svgBB.height * 50 / 100 - translation[1];
     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.

    +
    + 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:

    - -
    - - - - +

    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.

    +
    + 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:

    -
    - - - - +

    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.

    +
    + 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:

    -
    - - - - +

    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.

    +
    + 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:

    -
    - - - - +

    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.

    +
    + 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:

    +

    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>
    +  <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:

    - +

    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
    +  {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.

    -
    - - - +

    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.

    +
    + 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.
    • +

      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 index c93e71e..41ac603 100644 --- a/demo/textProperties.html +++ b/demo/textProperties.html @@ -1,158 +1,158 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Text Properties + KUTE.js Text Properties - - + + - - + + - - + + - + -
    +
    - +
    +

    Text Properties

    +

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

    +
    + +
    -

    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:

    -
    +
    +
    +

    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

    +

    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.
    • -
    +
      +
    • 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

    - +

    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.
    • -
    - -
    - - - + +

    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/transformFunctions.html b/demo/transformFunctions.html index f183d05..b10f1fc 100644 --- a/demo/transformFunctions.html +++ b/demo/transformFunctions.html @@ -2,147 +2,147 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Transform Functions + 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.

    +
    + +
    -

    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.

    -
    +
    +
    +

    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.
    • -
    +

    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.

    +

    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

    +

    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});
    @@ -150,21 +150,21 @@ 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
    +
    +
    2D
    +
    X
    +
    Y
    +
    Z
    -
    - Start -
    +
    + 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.

    +

    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

    +

    Rotations

    var tween1 = KUTE.fromTo('selector1',{rotate:0},{rotate:-720});
     var tween2 = KUTE.fromTo('selector2',{rotateX:0},{rotateX:200});
    @@ -172,129 +172,129 @@ var tween3 = KUTE.fromTo('selector3',{perspective:100,rotate3d:[0,0,0]},{perspec
     var tween4 = KUTE.fromTo('selector4',{rotateZ:0},{rotateZ:360});
     
    -
    -
    2D
    -
    X
    -
    Y
    -
    Z
    -
    - Start -
    +
    +
    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.

    +
    +

    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

    +

    Skews

    var tween1 = KUTE.fromTo('selector1',{skewX:0},{skewX:20});
     var tween2 = KUTE.fromTo('selector2',{skew:[0,0]},{skew:[0,45]});
     
    -
    -
    X
    -
    Y
    +
    +
    X
    +
    Y
    -
    - Start -
    +
    + 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:

    +

    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 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.

    +

    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
    +'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
    +'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
    +
    +
    self perspective 200px
    +
    parent perspective 400px
    -
    - Start -
    +
    + 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.
    • -
    - -
    - - - +

    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 index 4ae2373..d028347 100644 --- a/demo/transformMatrix.html +++ b/demo/transformMatrix.html @@ -1,142 +1,142 @@ - - - - - - - - - + + + + + + + + + - KUTE.js Transform Matrix + 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.

    +
    + +
    -

    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.

    -
    +
    +
    +

    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.
    • -
    +
    + +

    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:

    +

    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} })
    @@ -144,71 +144,71 @@ 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
    +
    +
    MX1
    +
    MX2
    +
    MX3
    +
    MX4
    -
    - Start -
    +
    + 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.

    +
    +

    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
    +

    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 -
    +
    + 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.
    • -
    - - - +

    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 index b5b92f0..969a50c 100644 --- a/dist/kute.esm.js +++ b/dist/kute.esm.js @@ -1,9 +1,9 @@ /*! -* KUTE.js Standard v2.0.15 (http://thednp.github.io/kute.js) +* KUTE.js Standard v2.0.16 (http://thednp.github.io/kute.js) * Copyright 2015-2020 © thednp * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) */ -var version = "2.0.15"; +var version = "2.0.16"; var KUTE = {}; @@ -915,8 +915,8 @@ function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); function getAttr(tweenProp,value){ var attrStartValues = {}; for (var attr in value){ - var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''); - var currentValue = this.element.getAttribute(attribute); + var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), + 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; @@ -924,13 +924,13 @@ function getAttr(tweenProp,value){ function prepareAttr(tweenProp,attrObj){ var attributesObject = {}; for ( var p in attrObj ) { - var prop = replaceUppercase(p); - var regex = /(%|[a-z]+)$/; - var currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); + var prop = replaceUppercase(p), + regex = /(%|[a-z]+)$/, + currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); if ( !svgColors.includes(prop)) { if ( currentValue !== null && regex.test(currentValue) ) { - var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - var suffix = /%/.test(unit) ? '_percent' : ("_" + unit); + var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u, + suffix = /%/.test(unit) ? '_percent' : ("_" + unit); onStart[ComponentName][prop+suffix] = function(tp) { if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { attributes[tp] = function (elem, p, a, b, v) { @@ -1373,15 +1373,15 @@ function getEllipseLength(el) { return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; } function getTotalLength(el) { - if (/rect/.test(el.tagName)) { + if ('rect'===el.tagName) { return getRectLength(el); - } else if (/circle/.test(el.tagName)) { + } else if ('circle'===el.tagName) { return getCircleLength(el); - } else if (/ellipse/.test(el.tagName)) { + } else if ('ellipse'===el.tagName) { return getEllipseLength(el); - } else if (/polygon|polyline/.test(el.tagName)) { + } else if (['polygon,polyline'].indexOf(el.tagName)>-1) { return getPolyLength(el); - } else if (/line/.test(el.tagName)) { + } else if ('line'===el.tagName) { return getLineLength(el); } } @@ -1457,51 +1457,69 @@ function onStartSVGMorph(tweenProp){ } } -function clonePath(pathArray){ - return pathArray.map(function (x) { return Array.isArray(x) ? clonePath(x) : !isNaN(+x) ? +x : x; } ) -} - -var SVGPathCommanderOptions = { +var options = { + origin:null, decimals:3, round:1 }; -function roundPath(pathArray) { - return pathArray.map( function (seg) { return seg.map(function (c,i) { - var nr = +c, dc = Math.pow(10,SVGPathCommanderOptions.decimals); - return i ? (nr % 1 === 0 ? nr : (nr*dc>>0)/dc) : c - } - ); }) +function clonePath(pathArray){ + return pathArray.map(function (x) { return Array.isArray(x) + ? clonePath(x) + : !isNaN(+x) ? +x : x; } ) } -function SVGPathArray(pathString){ - this.segments = []; - this.pathValue = pathString; - this.max = pathString.length; - this.index = 0; - this.param = 0.0; - this.segmentStart = 0; - this.data = []; - this.err = ''; - return this +function roundPath(pathArray,round) { + var decimalsOption = !isNaN(+round) ? +round : options.decimals; + return decimalsOption ? + pathArray.map( function (seg) { return seg.map(function (c,i) { + var nr = +c, dc = Math.pow(10,decimalsOption); + return nr ? (nr % 1 === 0 ? nr : Math.round(nr*dc)/dc) : c + } + ); }) : clonePath(pathArray) +} + +function fixArc(pathArray, allPathCommands, i) { + if (pathArray[i].length > 7) { + pathArray[i].shift(); + var pi = pathArray[i]; + while (pi.length) { + allPathCommands[i] = "A"; + pathArray.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + } + pathArray.splice(i, 1); + } } var paramsCount = { a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0 }; +function isPathArray(pathArray){ + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[achlmrqstvz]/g.test(pathCommand) + }) +} + +function isCurveArray(pathArray){ + return isPathArray(pathArray) && pathArray.slice(1).every(function (seg){ return seg[0] === 'C'; }) +} + function finalizeSegment(state) { - var cmd = state.pathValue[state.segmentStart], cmdLC = cmd.toLowerCase(), params = state.data; - if (cmdLC === 'm' && params.length > 2) { - state.segments.push([ cmd, params[0], params[1] ]); + var pathCommand = state.pathValue[state.segmentStart], + pathComLK = pathCommand.toLowerCase(), + params = state.data; + if (pathComLK === 'm' && params.length > 2) { + state.segments.push([ pathCommand, params[0], params[1] ]); params = params.slice(2); - cmdLC = 'l'; - cmd = (cmd === 'm') ? 'l' : 'L'; + pathComLK = 'l'; + pathCommand = (pathCommand === 'm') ? 'l' : 'L'; } - if (cmdLC === 'r') { - state.segments.push([ cmd ].concat(params)); + if (pathComLK === 'r') { + state.segments.push([ pathCommand ].concat(params)); } else { - while (params.length >= paramsCount[cmdLC]) { - state.segments.push([ cmd ].concat(params.splice(0, paramsCount[cmdLC]))); - if (!paramsCount[cmdLC]) { + while (params.length >= paramsCount[pathComLK]) { + state.segments.push([ pathCommand ].concat(params.splice(0, paramsCount[pathComLK]))); + if (!paramsCount[pathComLK]) { break; } } @@ -1522,7 +1540,7 @@ function scanFlag(state) { state.index++; return; } - state.err = invalidPathValue; + state.err = invalidPathValue + ": invalid Arc flag " + ch; } function isDigit(code) { @@ -1539,7 +1557,7 @@ function scanParam(state) { hasDot = false, ch; if (index >= max) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing param " + (state.pathValue[index]); return; } ch = state.pathValue.charCodeAt(index); @@ -1548,7 +1566,7 @@ function scanParam(state) { ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; } if (!isDigit(ch) && ch !== 0x2E) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " not number"; return; } if (ch !== 0x2E) { @@ -1557,7 +1575,7 @@ function scanParam(state) { ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; if (zeroFirst && index < max) { if (ch && isDigit(ch)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[start]) + " illegal number"; return; } } @@ -1578,7 +1596,7 @@ function scanParam(state) { } if (ch === 0x65 || ch === 0x45) { if (hasDot && !hasCeiling && !hasDecimal) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } index++; @@ -1591,7 +1609,7 @@ function scanParam(state) { index++; } } else { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } } @@ -1599,6 +1617,21 @@ function scanParam(state) { state.param = +state.pathValue.slice(start, index); } +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) || + (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); +} + +function skipSpaces(state) { + while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { + state.index++; + } +} + function isPathCommand(code) { switch (code | 0x20) { case 0x6D: @@ -1628,27 +1661,12 @@ function isArcCommand(code) { return (code | 0x20) === 0x61; } -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) || - (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || - (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); -} - -function skipSpaces(state) { - while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { - state.index++; - } -} - function scanSegment(state) { var max = state.max, cmdCode, comma_found, need_params, i; state.segmentStart = state.index; cmdCode = state.pathValue.charCodeAt(state.index); if (!isPathCommand(cmdCode)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[state.index]) + " not a path command"; return; } need_params = paramsCount[state.pathValue[state.index].toLowerCase()]; @@ -1689,106 +1707,45 @@ function scanSegment(state) { finalizeSegment(state); } -function isPathArray(pathArray){ - return Array.isArray(pathArray) && pathArray.every(function (x){ - var pathCommand = x[0].toLowerCase(); - return paramsCount[pathCommand] === x.length - 1 && /[achlmrqstvz]/g.test(pathCommand) - }) +function SVGPathArray(pathString){ + this.segments = []; + this.pathValue = pathString; + this.max = pathString.length; + this.index = 0; + this.param = 0.0; + this.segmentStart = 0; + this.data = []; + this.err = ''; + return this } -function parsePathString(pathString) { +function parsePathString(pathString,round) { if ( isPathArray(pathString) ) { return clonePath(pathString) } - var state = new SVGPathArray(pathString), max = state.max; + var state = new SVGPathArray(pathString); skipSpaces(state); - while (state.index < max && !state.err.length) { + while (state.index < state.max && !state.err.length) { scanSegment(state); } if (state.err.length) { state.segments = []; } else if (state.segments.length) { if ('mM'.indexOf(state.segments[0][0]) < 0) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing M/m"; state.segments = []; } else { state.segments[0][0] = 'M'; } } - return roundPath(state.segments) -} - -function catmullRom2bezier(crp, z) { - var d = []; - for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { - var p = [ - {x: +crp[i - 2], y: +crp[i - 1]}, - {x: +crp[i], y: +crp[i + 1]}, - {x: +crp[i + 2], y: +crp[i + 3]}, - {x: +crp[i + 4], y: +crp[i + 5]} - ]; - if (z) { - if (!i) { - p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; - } else if (iLen - 4 == i) { - p[3] = {x: +crp[0], y: +crp[1]}; - } else if (iLen - 2 == i) { - p[2] = {x: +crp[0], y: +crp[1]}; - p[3] = {x: +crp[2], y: +crp[3]}; - } - } else { - if (iLen - 4 == i) { - p[3] = p[2]; - } else if (!i) { - p[0] = {x: +crp[i], y: +crp[i + 1]}; - } - } - d.push([ - "C", - (-p[0].x + 6 * p[1].x + p[2].x) / 6, - (-p[0].y + 6 * p[1].y + p[2].y) / 6, - (p[1].x + 6 * p[2].x - p[3].x) / 6, - (p[1].y + 6*p[2].y - p[3].y) / 6, - p[2].x, - p[2].y - ]); - } - return d -} - -function ellipseToArc(x, y, rx, ry, a) { - if (a == null && ry == null) { - ry = rx; - } - x = +x; - y = +y; - rx = +rx; - ry = +ry; - var res; - if (a != null) { - var rad = Math.PI / 180, - x1 = x + rx * Math.cos(-ry * rad), - x2 = x + rx * Math.cos(-a * rad), - y1 = y + rx * Math.sin(-ry * rad), - y2 = y + rx * Math.sin(-a * rad); - res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; - } else { - res = [ - ["M", x, y], - ["m", 0, -ry], - ["a", rx, ry, 0, 1, 1, 0, 2 * ry], - ["a", rx, ry, 0, 1, 1, 0, -2 * ry], - ["z"] - ]; - } - return res; + return roundPath(state.segments,round) } function isAbsoluteArray(pathInput){ return isPathArray(pathInput) && pathInput.every(function (x){ return x[0] === x[0].toUpperCase(); }) } -function pathToAbsolute(pathArray) { +function pathToAbsolute(pathArray,round) { if (isAbsoluteArray(pathArray)) { return clonePath(pathArray) } @@ -1796,10 +1753,8 @@ function pathToAbsolute(pathArray) { var resultArray = [], x = 0, y = 0, mx = 0, my = 0, start = 0, ii = pathArray.length, - crz = pathArray.length === 3 && - pathArray[0][0] === "M" && - pathArray[1][0].toUpperCase() === "R" && - pathArray[2][0].toUpperCase() === "Z"; + pathCommand = '', segment = [], segLength = 0, + absoluteSegment = []; if (pathArray[0][0] === "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; @@ -1808,215 +1763,417 @@ function pathToAbsolute(pathArray) { start++; resultArray[0] = ["M", x, y]; } - var loop = function ( i ) { - var r = [], pa = pathArray[i], pa0 = pa[0], dots = []; - resultArray.push(r = []); - if (pa0 !== pa0.toUpperCase()) { - r[0] = pa0.toUpperCase(); - switch (r[0]) { + for (var i = start; i < ii; i++) { + segment = pathArray[i]; + pathCommand = segment[0]; + resultArray.push(absoluteSegment = []); + if (pathCommand !== pathCommand.toUpperCase()) { + absoluteSegment[0] = pathCommand.toUpperCase(); + switch (absoluteSegment[0]) { case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +pa[6] + x; - r[7] = +pa[7] + y; + segment.slice(1,-2) + .concat([+segment[6] + x, +segment[7] + y]) + .map(function (s){ return absoluteSegment.push(s); }); break; case "V": - r[1] = +pa[1] + y; + absoluteSegment[1] = +segment[1] + y; break; case "H": - r[1] = +pa[1] + x; - break; - case "R": - dots = [x, y].concat(pa.slice(1)); - for (var j = 2, jj = dots.length; j < jj; j++) { - dots[j] = +dots[j] + x; - dots[++j] = +dots[j] + y; - } - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - break; - case "O": - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - break; - case "U": - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, pa[1], pa[2], pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); + absoluteSegment[1] = +segment[1] + x; break; case "M": - mx = +pa[1] + x; - my = +pa[2] + y; + mx = +segment[1] + x; + my = +segment[2] + y; default: - for (var k = 1, kk = pa.length; k < kk; k++) { - r[k] = +pa[k] + ((k % 2) ? x : y); - } + segment.map(function (s,j){ return j && absoluteSegment.push(+s + ((j % 2) ? x : y)); }); } - } else if (pa0 === "R") { - dots = [x, y].concat(pa.slice(1)); - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - r = ["R"].concat(pa.slice(-2)); - } else if (pa0 === "O") { - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - } else if (pa0 === "U") { - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, +pa[1], +pa[2], +pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); } else { - pa.map(function (k){ return r.push(k); }); + segment.map(function (k){ return absoluteSegment.push(k); }); } - pa0 = pa0.toUpperCase(); - if (pa0 !== "O") { - switch (r[0]) { - case "Z": - x = mx; - y = my; - break; - case "H": - x = +r[1]; - break; - case "V": - y = +r[1]; - break; - case "M": - mx = +r[r.length - 2]; - my = +r[r.length - 1]; - default: - x = +r[r.length - 2]; - y = +r[r.length - 1]; - } + segLength = absoluteSegment.length; + switch (absoluteSegment[0]) { + case "Z": + x = mx; + y = my; + break; + case "H": + x = +absoluteSegment[1]; + break; + case "V": + y = +absoluteSegment[1]; + break; + case "M": + mx = +absoluteSegment[segLength - 2]; + my = +absoluteSegment[segLength - 1]; + default: + x = +absoluteSegment[segLength - 2]; + y = +absoluteSegment[segLength - 1]; } + } + return roundPath(resultArray,round) +} + +function shorthandToQuad(x1,y1,qx,qy,prevCommand){ + return 'QT'.indexOf(prevCommand)>-1 ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy} + : { qx: x1, qy: y1 } +} + +function shorthandToCubic(x1,y1,x2,y2,prevCommand){ + return 'CS'.indexOf(prevCommand)>-1 ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2} + : { x1: x1, y1: y1 } +} + +function normalizeSegment(segment, params, prevCommand) { + var nqxy, nxy; + 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); + switch (segment[0]) { + case "H": + return ["L", segment[1], params.y1] + case "V": + return ["L", params.x1, segment[1]] + case "S": + nxy = shorthandToCubic(params.x1,params.y1, params.x2,params.y2, prevCommand); + params.x1 = nxy.x1; + params.y1 = nxy.y1; + return ["C", nxy.x1, nxy.y1].concat(segment.slice(1)) + case "T": + nqxy = shorthandToQuad(params.x1,params.y1, params.qx, params.qy, prevCommand); + params.qx = nqxy.qx; + params.qy = nqxy.qy; + return ["Q", params.qx, params.qy].concat(segment.slice(1)) + case "Q": + params.qx = segment[1]; + params.qy = segment[2]; + } + return segment +} + +function isNormalizedArray(pathArray){ + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[ACLMQZ]/.test(seg[0]) + }) +} + +function normalizePath(pathArray,round) { + if (isNormalizedArray(pathArray)) { + return clonePath(pathArray) + } + pathArray = pathToAbsolute(pathArray); + var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, + allPathCommands = [], pathCommand = '', prevCommand = '', + ii = pathArray.length, segment, seglen; + for (var i = 0; i < ii; i++) { + pathCommand = pathArray[i][0]; + allPathCommands[i] = pathCommand; + i && ( prevCommand = allPathCommands[i - 1]); + pathArray[i] = normalizeSegment(pathArray[i], params, prevCommand); + segment = pathArray[i]; + 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 roundPath(pathArray,round) +} + +function rotateVector(x, y, rad) { + var X = x * Math.cos(rad) - y * Math.sin(rad), + Y = x * Math.sin(rad) + y * Math.cos(rad); + return {x: X, y: Y} +} + +function arcToCubic(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + var _120 = Math.PI * 120 / 180, + rad = Math.PI / 180 * (angle || 0), + res = [], xy, f1, f2, cx, 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, + y = (y1 - y2) / 2, + h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + if (h > 1) { + h = Math.sqrt(h); + rx = h * rx; + ry = h * ry; + } + var rx2 = rx * rx, + ry2 = ry * ry, + k = (large_arc_flag == sweep_flag ? -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; + f1 = Math.asin( ((y1 - cy) / ry).toFixed(9) ); + f2 = Math.asin( ((y2 - cy) / ry).toFixed(9) ); + f1 = x1 < cx ? Math.PI - f1 : f1; + f2 = x2 < cx ? Math.PI - f2 : f2; + f1 < 0 && (f1 = Math.PI * 2 + f1); + f2 < 0 && (f2 = Math.PI * 2 + f2); + if (sweep_flag && f1 > f2) { + f1 = f1 - Math.PI * 2; + } + if (!sweep_flag && f2 > f1) { + f2 = f2 - Math.PI * 2; + } + } else { + f1 = recursive[0]; + f2 = recursive[1]; + cx = recursive[2]; + cy = recursive[3]; + } + var df = f2 - f1; + if (Math.abs(df) > _120) { + var f2old = f2, x2old = x2, y2old = y2; + f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); + x2 = cx + rx * Math.cos(f2); + y2 = cy + ry * Math.sin(f2); + res = arcToCubic(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + } + df = f2 - f1; + var c1 = Math.cos(f1), + s1 = Math.sin(f1), + c2 = Math.cos(f2), + s2 = Math.sin(f2), + t = Math.tan(df / 4), + hx = 4 / 3 * rx * t, + hy = 4 / 3 * ry * t, + m1 = [x1, y1], + m2 = [x1 + hx * s1, y1 - hy * c1], + m3 = [x2 + hx * s2, y2 - hy * c2], + m4 = [x2, y2]; + m2[0] = 2 * m1[0] - m2[0]; + m2[1] = 2 * m1[1] - m2[1]; + if (recursive) { + return [m2, m3, m4].concat(res); + } else { + res = [m2, m3, m4].concat(res).join().split(","); + return res.map(function (rz,i){ return i % 2 ? rotateVector(res[i - 1], rz, rad).y : rotateVector(rz, res[i + 1], rad).x; }); + } +} + +function quadToCubic (x1, y1, qx, qy, x2, y2) { + var _13 = 1 / 3, _23 = 2 / 3; + return [ + _13 * x1 + _23 * qx, + _13 * y1 + _23 * qy, + _13 * x2 + _23 * qx, + _13 * y2 + _23 * qy, + x2, y2 ] +} + +function getPointAtSegLength (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: Math.pow(t1, 3) * p1x + Math.pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + Math.pow(t, 3) * p2x, + y: Math.pow(t1, 3) * p1y + Math.pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + Math.pow(t, 3) * p2y }; - for (var i = start; i < ii; i++) loop( i ); - return roundPath(resultArray) +} + +function midPoint(a, b, t) { + var ax = a[0], ay = a[1], bx = b[0], by = b[1]; + return [ ax + (bx - ax) * t, ay + (by - ay) * t]; +} + +function lineToCubic(x1, y1, x2, y2) { + var t = 0.5, + p0 = [x1,y1], + p1 = [x2,y2], + p2 = midPoint(p0, p1, t), + p3 = midPoint(p1, p2, t), + p4 = midPoint(p2, p3, t), + p5 = midPoint(p3, p4, t), + p6 = midPoint(p4, p5, t), + cp1 = getPointAtSegLength.apply(0, p0.concat( p2, p4, p6, t)), + cp2 = getPointAtSegLength.apply(0, p6.concat( p5, p3, p1, 0)); + return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2] +} + +function segmentToCubic(segment, params) { + 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); + switch (segment[0]) { + case 'M': + params.x = segment[1]; + params.y = segment[2]; + return segment + case 'A': + return ['C'].concat(arcToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) + case 'Q': + params.qx = segment[1]; + params.qy = segment[2]; + return ['C'].concat(quadToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) + case 'L': + return ['C'].concat(lineToCubic(params.x1, params.y1, segment[1], segment[2])) + case 'Z': + return ['C'].concat(lineToCubic(params.x1, params.y1, params.x, params.y)) + } + return segment +} + +function pathToCurve(pathArray,round) { + if (isCurveArray(pathArray)){ + return clonePath(pathArray) + } + pathArray = normalizePath(pathArray); + var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, + allPathCommands = [], pathCommand = '', + ii = pathArray.length, segment, seglen; + for (var i = 0; i < ii; i++) { + pathArray[i] && (pathCommand = pathArray[i][0]); + allPathCommands[i] = pathCommand; + pathArray[i] = segmentToCubic(pathArray[i], params); + fixArc(pathArray,allPathCommands,i); + ii = pathArray.length; + segment = pathArray[i]; + 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 roundPath(pathArray,round) } function pathToString(pathArray) { return pathArray.map(function (x){ return x[0].concat(x.slice(1).join(' ')); }).join('') } -function splitPath(pathString) { - return pathString +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; }) } -function createPath(path) { - var np = document.createElementNS('http://www.w3.org/2000/svg','path'), - d = path instanceof SVGElement && ['path','glyph'].indexOf(path.tagName) > -1 ? path.getAttribute('d') : path; - np.setAttribute('d',d); - return np +function base3(p1, p2, p3, p4, t) { + var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, + t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; + return t * t2 - 3 * p1 + 3 * p2; +} +function getSegCubicLength (x1, y1, x2, y2, x3, y3, x4, y4, z) { + (z === null || isNaN(+z)) && (z = 1); + z = z > 1 ? 1 : z < 0 ? 0 : z; + var z2 = z / 2, ct = 0, xbase = 0, ybase = 0, sum = 0, + Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816], + Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472]; + Tvalues.map(function (T,i){ + ct = z2 * T + z2; + xbase = base3( x1, x2, x3, x4, ct); + ybase = base3( y1, y2, y3, y4, ct); + sum += Cvalues[i] * Math.sqrt(xbase * xbase + ybase * ybase); + }); + return z2 * sum } -function polygonArea(polygon) { - var i = -1, - n = polygon.length, - a, - b = polygon[n - 1], - area = 0; - while (++i < n) { - a = b; - b = polygon[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area / 2; +function getPathLength(pathArray){ + var totalLength = 0; + pathToCurve(pathArray).map(function (s,i,curveArray) { + totalLength += 'M' !== s[0] ? getSegCubicLength.apply(0, curveArray[i-1].slice(-2).concat(s.slice(1)) ) : 0; + }); + return totalLength } -function polygonLength(polygon) { - var i = -1, - n = polygon.length, - b = polygon[n - 1], - xa, - ya, - xb = b[0], - yb = b[1], - perimeter = 0; - while (++i < n) { - xa = xb; - ya = yb; - b = polygon[i]; - xb = b[0]; - yb = b[1]; - xa -= xb; - ya -= yb; - perimeter += Math.hypot(xa, ya); - } - return perimeter; +function getPointAtLength(pathArray,length){ + var totalLength = 0, segLen, data; + return pathToCurve(pathArray).map(function (seg,i,curveArray) { + data = i ? curveArray[i-1].slice(-2).concat(seg.slice(1)) : seg.slice(1); + segLen = i ? getSegCubicLength.apply(0, data) : 0; + totalLength += segLen; + return i === 0 ? {x:data[0], y:data[1]} : + totalLength>length && length>totalLength-segLen ? + getPointAtSegLength.apply(0,data.concat(1 - (totalLength-length)/segLen)) : null + }).filter(function (x){ return x; }).slice(-1)[0] } -function isFiniteNumber(number) { - return typeof number === "number" && isFinite(number); +function getCubicSegArea(x0,y0, x1,y1, x2,y2, x3,y3) { + return 3 * ((y3 - y0) * (x1 + x2) - (x3 - x0) * (y1 + y2) + + y1 * (x0 - x2) - x1 * (y0 - y2) + + y3 * (x2 + x0 / 3) - x3 * (y2 + y0 / 3)) / 20; } +function getPathArea(pathArray) { + var x = 0, y = 0, mx = 0, my = 0, len = 0; + return pathToCurve(pathArray).map(function (seg) { + var assign; + switch (seg[0]){ + case 'M': + case 'Z': + mx = seg[0] === 'M' ? seg[1] : mx; + my = seg[0] === 'M' ? seg[2] : my; + x = mx; + y = my; + return 0 + default: + len = getCubicSegArea.apply(0, [x,y].concat(seg.slice(1) )); + (assign = seg.slice(-2), x = assign[0], y = assign[1]); + return len + } + }).reduce(function (a, b) { return a + b; }, 0) +} + +function getDrawDirection(pathArray) { + return getPathArea(pathToCurve(pathArray)) >= 0 +} + +var epsilon = 1e-9; + function distanceSquareRoot(a, b) { return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) - ); + (a[0] - b[0]) * (a[0] - b[0]) + + (a[1] - b[1]) * (a[1] - b[1]) + ) } -function pointAlong(a, b, pct) { - return [a[0] + (b[0] - a[0]) * pct, a[1] + (b[1] - a[1]) * pct]; -} -function samePoint(a, b) { - return distanceSquareRoot(a, b) < 1e-9; + +function polygonLength(ring){ + return ring.reduce(function (length, point, i) { return i ? length + distanceSquareRoot(ring[i-1],point) : 0; }, 0 ) } function pathStringToRing(str, maxSegmentLength) { - var parsed = pathToAbsolute(str); + var parsed = normalizePath(str,0); return exactRing(parsed) || approximateRing(parsed, maxSegmentLength); } -function exactRing(segments) { - var ring = []; - if (!segments.length || segments[0][0] !== "M") { +function exactRing(pathArray) { + var ring = [], + segment = [], pathCommand = '', + pathlen = pathArray.length, + pathLength = 0; + if (!pathArray.length || pathArray[0][0] !== "M") { return false; } - for (var i = 0; i < segments.length; i++) { - var ref = segments[i]; - var command = ref[0]; - var x = ref[1]; - var y = ref[2]; - if ((command === "M" && i) || command === "Z") { + for (var i = 0; i < pathlen; i++) { + segment = pathArray[i]; + pathCommand = segment[0]; + if (pathCommand === "M" && i || pathCommand === "Z") { break; - } else if (command === "M" || command === "L") { - ring.push([x, y]); - } else if (command === "H") { - ring.push([x, ring[ring.length - 1][1]]); - } else if (command === "V") { - ring.push([ring[ring.length - 1][0], x]); + } else if ('ML'.indexOf( pathCommand) > -1) { + ring.push([segment[1], segment[2]]); } else { return false; } } - return ring.length ? { ring: ring } : false; + pathLength = polygonLength(ring); + return pathlen ? { ring: ring, pathLength: pathLength } : false; } function approximateRing(parsed, maxSegmentLength) { var ringPath = splitPath(pathToString(parsed))[0], - ring = [], len, testPath, numPoints = 3; - if (!ringPath) { - throw (invalidPathValue); - } - testPath = createPath(ringPath); - len = testPath.getTotalLength(); - if ( - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { - numPoints = Math.max(numPoints, Math.ceil(len / maxSegmentLength)); + curvePath = pathToCurve(ringPath,4), + pathLength = getPathLength(curvePath), + ring = [], numPoints = 3, point; + if ( maxSegmentLength && !isNaN(maxSegmentLength) && +maxSegmentLength > 0 ) { + numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength)); } for (var i = 0; i < numPoints; i++) { - var p = testPath.getPointAtLength((len * i) / numPoints); - ring.push([p.x, p.y]); + point = getPointAtLength(curvePath,pathLength * i / numPoints); + ring.push([point.x, point.y]); + } + if (!getDrawDirection(curvePath)) { + ring.reverse(); } return { + pathLength: pathLength, ring: ring, skipBisect: true }; @@ -2042,12 +2199,14 @@ function rotateRing(ring, vs) { } function addPoints(ring, numPoints) { var desiredLength = ring.length + numPoints, - step = polygonLength(ring) / numPoints; - var i = 0, cursor = 0, insertAt = step / 2; + step = polygonLength(ring) / numPoints; + var i = 0, cursor = 0, insertAt = step / 2, a, b, segment; while (ring.length < desiredLength) { - var a = ring[i], b = ring[(i + 1) % ring.length], segment = distanceSquareRoot(a, b); + a = ring[i]; + b = ring[(i + 1) % ring.length]; + segment = distanceSquareRoot(a, b); if (insertAt <= cursor + segment) { - ring.splice( i + 1, 0, segment ? pointAlong(a, b, (insertAt - cursor) / segment) : a.slice(0) ); + ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) ); insertAt += step; continue; } @@ -2057,53 +2216,40 @@ function addPoints(ring, numPoints) { } function bisect(ring, maxSegmentLength) { if ( maxSegmentLength === void 0 ) maxSegmentLength = Infinity; + var a = [], b = []; for (var i = 0; i < ring.length; i++) { - var a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; + a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = pointAlong(a, b, 0.5); + b = midPoint(a, b, 0.5); ring.splice(i + 1, 0, b); } } } function normalizeRing(ring, maxSegmentLength) { - var points, area, skipBisect; + var points, skipBisect, pathLength; if (typeof ring === "string") { var converted = pathStringToRing(ring, maxSegmentLength); ring = converted.ring; skipBisect = converted.skipBisect; + pathLength = converted.pathLength; } else if (!Array.isArray(ring)) { - throw (invalidPathValue); + throw (invalidPathValue) } points = ring.slice(0); + points.pathLength = pathLength; if (!validRing(points)) { - throw (invalidPathValue); + throw (invalidPathValue) } - if (points.length > 1 && samePoint(points[0], points[points.length - 1])) { + if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { points.pop(); } - area = polygonArea(points); - if (area > 0) { - points.reverse(); - } - if ( - !skipBisect && - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { + if ( !skipBisect && maxSegmentLength && !isNaN(maxSegmentLength) && (+maxSegmentLength) > 0 ) { bisect(points, maxSegmentLength); } - return points; + return points } function validRing(ring) { - return ring.every(function(point) { - return ( - Array.isArray(point) && - point.length >= 2 && - isFiniteNumber(point[0]) && - isFiniteNumber(point[1]) - ); - }); + return Array.isArray(ring) && ring.every( function (point) { return Array.isArray(point) && point.length === 2 && !isNaN(point[0]) && !isNaN(point[1]); }) } function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { morphPrecision = morphPrecision || defaultOptions.morphPrecision; @@ -2112,8 +2258,8 @@ function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { diff = fromRing.length - toRing.length; addPoints(fromRing, diff < 0 ? diff * -1 : 0); addPoints(toRing, diff > 0 ? diff : 0); - rotateRing(fromRing, toRing); - return [fromRing,toRing] + rotateRing(fromRing,toRing); + return [roundPath(fromRing),roundPath(toRing)] } function getSVGMorph(tweenProp){ return this.element.getAttribute('d'); @@ -2160,10 +2306,10 @@ var svgMorph = { Util: { addPoints: addPoints,bisect: bisect,normalizeRing: normalizeRing,validRing: validRing, getInterpolationPoints: getInterpolationPoints,pathStringToRing: pathStringToRing, - isFiniteNumber: isFiniteNumber,distanceSquareRoot: distanceSquareRoot,pointAlong: pointAlong,samePoint: samePoint, - exactRing: exactRing,approximateRing: approximateRing,createPath: createPath,rotateRing: rotateRing, - pathToAbsolute: pathToAbsolute,pathToString: pathToString, - polygonLength: polygonLength,polygonArea: polygonArea + distanceSquareRoot: distanceSquareRoot,midPoint: midPoint, + approximateRing: approximateRing,rotateRing: rotateRing, + pathToString: pathToString,pathToCurve: pathToCurve, + getPathLength: getPathLength,getPointAtLength: getPointAtLength,getDrawDirection: getDrawDirection,roundPath: roundPath } }; Components.SVGMorph = svgMorph; diff --git a/dist/kute.esm.min.js b/dist/kute.esm.min.js index de62223..1e5ec0e 100644 --- a/dist/kute.esm.min.js +++ b/dist/kute.esm.min.js @@ -1,2 +1,2 @@ -// KUTE.js Standard v2.0.15 | thednp © 2020 | MIT-License -var t={},e=[],n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function U(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);S.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var H=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:L.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};H.prototype.start=function(e){return _(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),U.call(this),this._startFired=!0),!s&&o(),this},H.prototype.stop=function(){return this.playing&&(C(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},H.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},H.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},H.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},H.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},L.tween=H,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var N=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(M.call(this,i,"end"),this._resetStart?this.valuesStart=r:M.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,I.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),U.call(this),this._startTime+=t.Time()-this._pauseTime,_(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(C(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(H);L.tween=N;var j=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new L.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};j.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},j.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},j.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},j.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},j.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof j)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},j.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},j.prototype.removeTweens=function(){this.tweens=[]},j.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function R(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a.99||i<.01?(10*D(n,r,i)>>0)/10:D(n,r,i)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:v,prepareStart:d,onStart:i,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var b in a)if(b in t.functions)if("function"==typeof t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][s||o]&&(a[b][n][s||o]=t.functions[b]);else for(var x in t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][x]&&(a[b][n][x]=t.functions[b][x]);if(t.Interpolate){for(var _ in t.Interpolate){var C=t.Interpolate[_];if("function"!=typeof C||r[_])for(var S in C)"function"!=typeof C[S]||r[_]||(r[_]=C[S]);else r[_]=C}m[n]=t.Interpolate}if(t.Util)for(var T in t.Util)!w[T]&&(w[T]=t.Util[T]);return e};var X=["top","left","width","height"],B={};X.map((function(t){return B[t]=Q}));var z={component:"essentialBoxModel",category:"boxModel",properties:X,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:D},functions:{prepareStart:function(t){return A(this.element,t)||h[t]},prepareProperty:function(t,e){var n=R(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:B},Util:{trueDimension:R}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function q(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?D(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*D(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=q(n,r,i)})}x.BoxModelEssential=z;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var G={};K.map((function(t){return G[t]=Y}));var W={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:D,colors:q},functions:{prepareStart:function(t,e){return A(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:G},Util:{trueColor:Z}};x.ColorProperties=W;var J={},tt=["fill","stroke","stop-color"];function et(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var nt={prepareStart:function(t,e){var n={};for(var r in e){var i=et(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=tt.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=et(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(tt.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,q(n,r,i))})},n[a]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=R(o).u||R(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*D(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=R(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*D(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},rt={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:D,colors:q},functions:nt,Util:{replaceUppercase:et,trueColor:Z,trueDimension:R}};x.HTMLAttributes=rt;var it={prepareStart:function(t){return A(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*D(n,r,i)>>0)/1e3})}},at={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:D},functions:it};x.OpacityProperty=at;var st=String("abcdefghijklmnopqrstuvwxyz").split(""),ot=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),ut=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),lt=String("0123456789").split(""),ct=st.concat(ot,lt),pt=ct.concat(ut),ht={alpha:st,upper:ot,symbols:ut,numeric:lt,alphanumeric:ct,all:pt},ft={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ht?ht[n]:n&&n.length?n:ht[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=D(e,n,r)>>0})}};function vt(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function dt(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function mt(t,e,n,r){for(var i=[],a=0;a<3;a++)i[a]=(t[a]||e[a]?(1e3*(t[a]+(e[a]-t[a])*r)>>0)/1e3:0)+n;return"translate3d("+i.join(",")+")"}function bt(t,e,n,r){var i="";return i+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",i+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",i+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function wt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function xt(t,e,n,r){var i=[];return i[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+i.join(",")+")"}x.TextWriteProperties=gt;var _t={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,e){var n=E(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},i=[],a=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?i:"rotate"===c?a:"skew"===c?s:{},v=0;v>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+i.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:wt,skew:xt}};function Ct(t,e){return parseFloat(t)/100*e}function St(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Tt(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a>0)/100,a=0-(100*D(e.s,n.s,r)>>0)/100,s=(100*D(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Lt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:D},functions:Ot,Util:{getRectLength:St,getPolyLength:Tt,getLineLength:Et,getCircleLength:At,getEllipseLength:Mt,getTotalLength:It,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:kt,percent:Ct}};function Pt(t,e,n,r){for(var i=[],a=0;a>0)/1e3)}return i}function Vt(t){return t.map((function(t){return Array.isArray(t)?Vt(t):isNaN(+t)?t:+t}))}x.SVGDraw=Lt;var Ut=3;function Ht(t){return t.map((function(t){return t.map((function(t,e){var n=+t,r=Math.pow(10,Ut);return e?n%1==0?n:(n*r>>0)/r:t}))}))}function Nt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}var jt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Ft(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=jt[n]&&(t.segments.push([e].concat(r.splice(0,jt[n]))),jt[n]););}var Rt="Invalid path value";function Dt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Rt)}function Qt(t){return t>=48&&t<=57}function Xt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Rt;else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=48&&t<=57||43===t||45===t||46===t}function zt(t){for(;t.index=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function Zt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=jt[t.pathValue[t.index].toLowerCase()],t.index++,zt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Xt(t):Dt(t),t.err.length)return;t.data.push(t.param),zt(t),n=!1,t.index=t.max)break;if(!Bt(t.pathValue.charCodeAt(t.index)))break}}Ft(t)}else Ft(t);else t.err=Rt}function qt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return jt[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Yt(t,e){for(var n=[],r=0,i=t.length;i-2*!e>r;r+=2){var a=[{x:+t[r-2],y:+t[r-1]},{x:+t[r],y:+t[r+1]},{x:+t[r+2],y:+t[r+3]},{x:+t[r+4],y:+t[r+5]}];e?r?i-4==r?a[3]={x:+t[0],y:+t[1]}:i-2==r&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[i-2],y:+t[i-1]}:i-4==r?a[3]=a[2]:r||(a[0]={x:+t[r],y:+t[r+1]}),n.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return n}function Kt(t,e,n,r,i){var a;if(null==i&&null==r&&(r=n),t=+t,e=+e,n=+n,r=+r,null!=i){var s=Math.PI/180,o=t+n*Math.cos(-r*s),u=t+n*Math.cos(-i*s);a=[["M",o,e+n*Math.sin(-r*s)],["A",n,n,0,+(i-r>180),0,u,e+n*Math.sin(-i*s)]]}else a=[["M",t,e],["m",0,-r],["a",n,r,0,1,1,0,2*r],["a",n,r,0,1,1,0,-2*r],["z"]];return a}function $t(t){if(qt(e=t)&&e.every((function(t){return t[0]===t[0].toUpperCase()})))return Vt(t);var e;t=function(t){if(qt(t))return Vt(t);var e=new Nt(t),n=e.max;for(zt(e);e.index-1?t.getAttribute("d"):t;return e.setAttribute("d",n),e}function Jt(t){for(var e,n=-1,r=t.length,i=t[r-1],a=0;++n0&&(o=Math.max(o,Math.ceil(n/e)));for(var u=0;ue;)i=re(r,i,.5),t.splice(n+1,0,i)}function pe(t,e){var n,r;if("string"==typeof t){var i=ae(t,e);t=i.ring,r=i.skipBisect}else if(!Array.isArray(t))throw Rt;if(!he(n=t.slice(0)))throw Rt;return n.length>1&&ie(n[0],n[n.length-1])&&n.pop(),Jt(n)>0&&n.reverse(),!r&&e&&ee(e)&&e>0&&ce(n,e),n}function he(t){return t.every((function(t){return Array.isArray(t)&&t.length>=2&&ee(t[0])&&ee(t[1])}))}function fe(t,e,n){var r=pe(t,n=n||f.morphPrecision),i=pe(e,n),a=r.length-i.length;return le(r,a<0?-1*a:0),le(i,a>0?a:0),ue(r,i),[r,i]}var ve={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var i=e.pathArray,a=n.pathArray,s=a.length;t.setAttribute("d",1===r?n.original:"M"+Pt(i,a,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=fe(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},de={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Pt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:ve,Util:{addPoints:le,bisect:ce,normalizeRing:pe,validRing:he,getInterpolationPoints:fe,pathStringToRing:ae,isFiniteNumber:ee,distanceSquareRoot:ne,pointAlong:re,samePoint:ie,exactRing:se,approximateRing:oe,createPath:Wt,rotateRing:ue,pathToAbsolute:$t,pathToString:Gt,polygonLength:te,polygonArea:Jt}};for(var ge in x.SVGMorph=de,x){var ye=x[ge];x[ge]=new F(ye)}var me={Animation:F,Components:x,Tween:N,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:j,allFromTo:function(t,e,n,r){return r=r||{},new j(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new j(V(t,!0),e,e,n)},Objects:b,Util:w,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:T,Selector:V,Version:"2.0.15"};export default me; +// KUTE.js Standard v2.0.16 | thednp © 2020 | MIT-License +var t={},e=[],n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},r={},a={},i={};i.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ea?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function q(){for(var t in a)if("function"==typeof a[t])a[t].call(this,t);else for(var e in a[t])a[t][e].call(this,e);C.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var N=function(e,n,r,i){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,i=i||{},this._resetStart=i.resetStart||0,this._easing="function"==typeof i.easing?i.easing:L.processEasing(i.easing),this._duration=i.duration||f.duration,this._delay=i.delay||f.delay,i){var o="_"+s;o in this||(this[o]=i[s])}var u=this._easing.name;return a[u]||(a[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};N.prototype.start=function(e){return M(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),q.call(this),this._startFired=!0),!s&&o(),this},N.prototype.stop=function(){return this.playing&&(_(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},N.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},N.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},N.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},N.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[a](this.element,this.valuesStart[a],this.valuesEnd[a],r);return 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)},L.tween=N,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var H=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],a=t[2];if(A.call(this,a,"end"),this._resetStart?this.valuesStart=r:A.call(this,r,"start"),!this._resetStart)for(var i in g)for(var s in g[i])g[i][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,E.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var a in this.valuesEnd)this.valuesRepeat[a]=this.valuesStart[a];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),q.call(this),this._startTime+=t.Time()-this._pauseTime,M(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(_(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[a](this.element,this.valuesStart[a],this.valuesEnd[a],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(N);L.tween=H;var j=function(t,e,n,r){var a=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var i=[];return Array.from(t).map((function(t,s){i[s]=r||{},i[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?a.tweens.push(new L.tween(t,e,n,i[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};j.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},j.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},j.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},j.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},j.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof j)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},j.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},j.prototype.removeTweens=function(){this.tweens=[]},j.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function U(t,e){for(var n,r=parseInt(t)||0,a=["px","%","deg","rad","em","rem","vh","vw"],i=0;i.99||a<.01?(10*Q(n,r,a)>>0)/10:Q(n,r,a)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,i={prepareProperty:v,prepareStart:d,onStart:a,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var x in i)if(x in t.functions)if("function"==typeof t.functions[x])!i[x][n]&&(i[x][n]={}),!i[x][n][s||o]&&(i[x][n][s||o]=t.functions[x]);else for(var b in t.functions[x])!i[x][n]&&(i[x][n]={}),!i[x][n][b]&&(i[x][n][b]=t.functions[x][b]);if(t.Interpolate){for(var M in t.Interpolate){var _=t.Interpolate[M];if("function"!=typeof _||r[M])for(var C in _)"function"!=typeof _[C]||r[M]||(r[M]=_[C]);else r[M]=_}m[n]=t.Interpolate}if(t.Util)for(var T in t.Util)!w[T]&&(w[T]=t.Util[T]);return e};var R=["top","left","width","height"],X={};R.map((function(t){return X[t]=D}));var B={component:"essentialBoxModel",category:"boxModel",properties:R,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:Q},functions:{prepareStart:function(t){return I(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:X},Util:{trueDimension:U}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var a=document.getElementsByTagName("head")[0];a.style.color=t;var i=getComputedStyle(a,null).color;return i=/rgb/.test(i)?i.replace(/[^\d,]/g,"").split(","):[0,0,0],a.style.color="",{r:parseInt(i[0]),g:parseInt(i[1]),b:parseInt(i[2])}}}function z(t,e,n){var r,a={},i=",";for(r in e)a[r]="a"!==r?Q(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*Q(t[r],e[r],n)>>0)/100:null;return a.a?"rgba("+a.r+i+a.g+i+a.b+i+a.a+")":"rgb("+a.r+i+a.g+i+a.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=z(n,r,a)})}b.BoxModelEssential=B;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var W={};K.map((function(t){return W[t]=Y}));var G={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:Q,colors:z},functions:{prepareStart:function(t,e){return I(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:W},Util:{trueColor:Z}};b.ColorProperties=G;var J={},tt=["fill","stroke","stop-color"];function et(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var nt={prepareStart:function(t,e){var n={};for(var r in e){var a=et(r).replace(/_+[a-z]+/,""),i=this.element.getAttribute(a);n[a]=tt.includes(a)?i||"rgba(0,0,0,0)":i||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var i=et(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(i.replace(/_+[a-z]+/,""));if(tt.includes(i))a.htmlAttributes[i]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,a){t.setAttribute(e,z(n,r,a))})},n[i]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=U(o).u||U(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;a.htmlAttributes[i+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[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)})},n[i+l]=U(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(a.htmlAttributes[i]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,a){t.setAttribute(e,(1e3*Q(n,r,a)>>0)/1e3)})},n[i]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,a){for(var i in r)t.attributes[i](e,i,n[i],r[i],a)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},rt={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:Q,colors:z},functions:nt,Util:{replaceUppercase:et,trueColor:Z,trueDimension:U}};b.HTMLAttributes=rt;var at={prepareStart:function(t){return I(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,a){t.style[e]=(1e3*Q(n,r,a)>>0)/1e3})}},it={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:Q},functions:at};b.OpacityProperty=it;var st=String("abcdefghijklmnopqrstuvwxyz").split(""),ot=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),ut=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),lt=String("0123456789").split(""),ct=st.concat(ot,lt),pt=ct.concat(ut),ht={alpha:st,upper:ot,symbols:ut,numeric:lt,alphanumeric:ct,all:pt},ft={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ht?ht[n]:n&&n.length?n:ht[f.textChars];t[e]=function(t,e,n,a){var i="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(a*u.length,u.length)>>0,0),t.innerHTML=a<1?s+l:""===n?" ":n):" "===n?(i=o.substring(0,Math.min((1-a)*o.length,o.length)>>0),t.innerHTML=a<1?i+l:""===n?" ":n):(i=o.substring(o.length,Math.min(a*o.length,o.length)>>0),s=u.substring(0,Math.min(a*u.length,u.length)>>0),t.innerHTML=a<1?s+l+i:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=Q(e,n,r)>>0})}};function vt(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 dt(t,e){var n=[];if(t.children.length){for(var r,a=[],i=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function mt(t,e,n,r){for(var a=[],i=0;i<3;i++)a[i]=(t[i]||e[i]?(1e3*(t[i]+(e[i]-t[i])*r)>>0)/1e3:0)+n;return"translate3d("+a.join(",")+")"}function xt(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 wt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function bt(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(",")+")"}b.TextWriteProperties=gt;var Mt={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,e){var n=S(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},a=[],i=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?a:"rotate"===c?i:"skew"===c?s:{},v=0;v>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:wt,skew:bt}};function _t(t,e){return parseFloat(t)/100*e}function Ct(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Tt(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},a=function(t,e){return null!=t&&null!=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-1?Tt(t):"line"===t.tagName?St(t):void 0}function kt(t,e){var n,r,a,i,s=/path|glyph/.test(t.tagName)?t.getTotalLength():Et(t);return e instanceof Object?e:("string"==typeof e?(e=e.split(/\,|\s/),n=/%/.test(e[0])?_t(e[0].trim(),s):parseFloat(e[0]),r=/%/.test(e[1])?_t(e[1].trim(),s):parseFloat(e[1])):void 0===e&&(i=parseFloat(I(t,"stroke-dashoffset")),a=I(t,"stroke-dasharray").split(/\,/),n=0-i,r=parseFloat(a[0])+n||s),{s:n,e:r,l:s})}b.TransformFunctions=Mt;var Ot={prepareStart:function(){return kt(this.element)},prepareProperty:function(t,e){return kt(this.element,e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){var a=(100*e.l>>0)/100,i=0-(100*Q(e.s,n.s,r)>>0)/100,s=(100*Q(e.e,n.e,r)>>0)/100+i;t.style.strokeDashoffset=i+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+a+"px"})}},Lt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:Q},functions:Ot,Util:{getRectLength:Ct,getPolyLength:Tt,getLineLength:St,getCircleLength:It,getEllipseLength:At,getTotalLength:Et,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:kt,percent:_t}};function Pt(t,e,n,r){for(var a=[],i=0;i>0)/1e3)}return a}b.SVGDraw=Lt;var Vt=3;function qt(t){return t.map((function(t){return Array.isArray(t)?qt(t):isNaN(+t)?t:+t}))}function Nt(t,e){var n=isNaN(+e)?Vt:+e;return n?t.map((function(t){return t.map((function(t,e){var r=+t,a=Math.pow(10,n);return r?r%1==0?r:Math.round(r*a)/a:t}))})):qt(t)}function Ht(t,e,n){if(t[n].length>7){t[n].shift();for(var r=t[n];r.length;)e[n]="A",t.splice(n++,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var jt={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Ft(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return jt[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Ut(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=jt[n]&&(t.segments.push([e].concat(r.splice(0,jt[n]))),jt[n]););}var Qt="Invalid path value";function Dt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Qt+": invalid Arc flag "+e)}function Rt(t){return t>=48&&t<=57}function Xt(t){var e,n=t.index,r=n,a=t.max,i=!1,s=!1,o=!1,u=!1;if(r>=a)t.err=Qt+": missing param "+t.pathValue[r];else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function Zt(t){return t>=48&&t<=57||43===t||45===t||46===t}function zt(t){var e,n,r,a,i=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=jt[t.pathValue[t.index].toLowerCase()],t.index++,Bt(t),t.data=[],r){for(n=!1;;){for(a=r;a>0;a--){if(97!=(32|e)||3!==a&&4!==a?Xt(t):Dt(t),t.err.length)return;t.data.push(t.param),Bt(t),n=!1,t.index=t.max)break;if(!Zt(t.pathValue.charCodeAt(t.index)))break}}Ut(t)}else Ut(t);else t.err=Qt+": "+t.pathValue[t.index]+" not a path command"}function Yt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}function Kt(t,e){if(Ft(n=t)&&n.every((function(t){return t[0]===t[0].toUpperCase()})))return qt(t);var n;t=function(t,e){if(Ft(t))return qt(t);var n=new Yt(t);for(Bt(n);n.index-1?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(e.x1,e.y1,e.x2,e.y2,n),e.x1=a.x1,e.y1=a.y1,["C",a.x1,a.y1].concat(t.slice(1));case"T":return r=function(t,e,n,r,a){return"QT".indexOf(a)>-1?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(e.x1,e.y1,e.qx,e.qy,n),e.qx=r.qx,e.qy=r.qy,["Q",e.qx,e.qy].concat(t.slice(1));case"Q":e.qx=t[1],e.qy=t[2]}return t}function Wt(t,e){if(function(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return jt[e]===t.length-1&&/[ACLMQZ]/.test(t[0])}))}(t))return qt(t);for(var n,r,a={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},i=[],s="",o="",u=(t=Kt(t)).length,l=0;l1&&(n*=w=Math.sqrt(w),r*=w);var b=n*n,M=r*r,_=(i==s?-1:1)*Math.sqrt(Math.abs((b*M-b*x*x-M*m*m)/(b*x*x+M*m*m)));f=_*n*x/r+(t+o)/2,v=_*-r*m/n+(e+u)/2,p=Math.asin(((e-v)/r).toFixed(9)),h=Math.asin(((u-v)/r).toFixed(9)),p=th&&(p-=2*Math.PI),!s&&h>p&&(h-=2*Math.PI)}var C=h-p;if(Math.abs(C)>d){var T=h,S=o,I=u;h=p+d*(s&&h>p?1:-1),o=f+n*Math.cos(h),u=v+r*Math.sin(h),y=Jt(o,u,n,r,a,0,s,S,I,[h,T,f,v])}C=h-p;var A=Math.cos(p),E=Math.sin(p),k=Math.cos(h),O=Math.sin(h),L=Math.tan(C/4),P=4/3*n*L,V=4/3*r*L,q=[t,e],N=[t+P*E,e-V*A],H=[o+P*O,u-V*k],j=[o,u];return N[0]=2*q[0]-N[0],N[1]=2*q[1]-N[1],l?[N,H,j].concat(y):(y=[N,H,j].concat(y).join().split(",")).map((function(t,e){return e%2?Gt(y[e-1],t,g).y:Gt(t,y[e+1],g).x}))}function te(t,e,n,r,a,i){var s=1/3,o=2/3;return[s*t+o*n,s*e+o*r,s*a+o*n,s*i+o*r,a,i]}function ee(t,e,n,r,a,i,s,o,u){var l=1-u;return{x:Math.pow(l,3)*t+3*Math.pow(l,2)*u*n+3*l*u*u*a+Math.pow(u,3)*s,y:Math.pow(l,3)*e+3*Math.pow(l,2)*u*r+3*l*u*u*i+Math.pow(u,3)*o}}function ne(t,e,n){var r=t[0],a=t[1];return[r+(e[0]-r)*n,a+(e[1]-a)*n]}function re(t,e,n,r){var a=.5,i=[t,e],s=[n,r],o=ne(i,s,a),u=ne(s,o,a),l=ne(o,u,a),c=ne(u,l,a),p=ne(l,c,a),h=ee.apply(0,i.concat(o,l,p,a)),f=ee.apply(0,p.concat(c,u,s,0));return[h.x,h.y,f.x,f.y,n,r]}function ae(t,e){switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"M":return e.x=t[1],e.y=t[2],t;case"A":return["C"].concat(Jt.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"Q":return e.qx=t[1],e.qy=t[2],["C"].concat(te.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"L":return["C"].concat(re(e.x1,e.y1,t[1],t[2]));case"Z":return["C"].concat(re(e.x1,e.y1,e.x,e.y))}return t}function ie(t,e){if(function(t){return Ft(t)&&t.slice(1).every((function(t){return"C"===t[0]}))}(t))return qt(t);for(var n,r,a={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},i=[],s="",o=(t=Wt(t)).length,u=0;u1?1:u<0?0:u)/2,c=0,p=0,h=0,f=0,v=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472];return[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816].map((function(u,d){p=oe(t,n,a,s,c=l*u+l),h=oe(e,r,i,o,c),f+=v[d]*Math.sqrt(p*p+h*h)})),l*f}function le(t){var e=0;return ie(t).map((function(t,n,r){e+="M"!==t[0]?ue.apply(0,r[n-1].slice(-2).concat(t.slice(1))):0})),e}function ce(t,e){var n,r,a=0;return ie(t).map((function(t,i,s){return r=i?s[i-1].slice(-2).concat(t.slice(1)):t.slice(1),n=i?ue.apply(0,r):0,a+=n,0===i?{x:r[0],y:r[1]}:a>e&&e>a-n?ee.apply(0,r.concat(1-(a-e)/n)):null})).filter((function(t){return t})).slice(-1)[0]}function pe(t,e,n,r,a,i,s,o){return 3*((o-e)*(n+a)-(s-t)*(r+i)+r*(t-a)-n*(e-i)+o*(a+t/3)-s*(i+e/3))/20}function he(t){return function(t){var e=0,n=0,r=0,a=0,i=0;return ie(t).map((function(t){var s;switch(t[0]){case"M":case"Z":return r="M"===t[0]?t[1]:r,a="M"===t[0]?t[2]:a,e=r,n=a,0;default:return i=pe.apply(0,[e,n].concat(t.slice(1))),s=t.slice(-2),e=s[0],n=s[1],i}})).reduce((function(t,e){return t+e}),0)}(ie(t))>=0}function fe(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))}function ve(t){return t.reduce((function(e,n,r){return r?e+fe(t[r-1],n):0}),0)}function de(t,e){var n=Wt(t,0);return function(t){var e=[],n=[],r="",a=t.length,i=0;if(!t.length||"M"!==t[0][0])return!1;for(var s=0;s-1))return!1;e.push([n[1],n[2]])}return i=ve(e),!!a&&{ring:e,pathLength:i}}(n)||ge(n,e)}function ge(t,e){var n,r,a=ie((r=se(t),se(Kt(r,0)).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0],4),i=le(a),s=[],o=3;e&&!isNaN(e)&&+e>0&&(o=Math.max(o,Math.ceil(i/e)));for(var u=0;ue;)r=ne(n,r,.5),t.splice(a+1,0,r)}function we(t,e){var n,r,a;if("string"==typeof t){var i=de(t,e);t=i.ring,r=i.skipBisect,a=i.pathLength}else if(!Array.isArray(t))throw Qt;if((n=t.slice(0)).pathLength=a,!be(n))throw Qt;return n.length>1&&fe(n[0],n[n.length-1])<1e-9&&n.pop(),!r&&e&&!isNaN(e)&&+e>0&&xe(n,e),n}function be(t){return Array.isArray(t)&&t.every((function(t){return Array.isArray(t)&&2===t.length&&!isNaN(t[0])&&!isNaN(t[1])}))}function Me(t,e,n){var r=we(t,n=n||f.morphPrecision),a=we(e,n),i=r.length-a.length;return me(r,i<0?-1*i:0),me(a,i>0?i:0),ye(r,a),[Nt(r),Nt(a)]}var _e={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,a=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(a,""):r||"string"!=typeof e||(n.original=e.replace(a,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var a=e.pathArray,i=n.pathArray,s=i.length;t.setAttribute("d",1===r?n.original:"M"+Pt(a,i,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=Me(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},Ce={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Pt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:_e,Util:{addPoints:me,bisect:xe,normalizeRing:we,validRing:be,getInterpolationPoints:Me,pathStringToRing:de,distanceSquareRoot:fe,midPoint:ne,approximateRing:ge,rotateRing:ye,pathToString:se,pathToCurve:ie,getPathLength:le,getPointAtLength:ce,getDrawDirection:he,roundPath:Nt}};for(var Te in b.SVGMorph=Ce,b){var Se=b[Te];b[Te]=new F(Se)}var Ie={Animation:F,Components:b,Tween:H,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:j,allFromTo:function(t,e,n,r){return r=r||{},new j(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new j(V(t,!0),e,e,n)},Objects:x,Util:w,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:T,Selector:V,Version:"2.0.16"};export default Ie; diff --git a/dist/kute.js b/dist/kute.js index 7330c1d..67f032d 100644 --- a/dist/kute.js +++ b/dist/kute.js @@ -1,5 +1,5 @@ /*! -* KUTE.js Standard v2.0.15 (http://thednp.github.io/kute.js) +* KUTE.js Standard v2.0.16 (http://thednp.github.io/kute.js) * Copyright 2015-2020 © thednp * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) */ @@ -9,7 +9,7 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KUTE = factory()); }(this, (function () { 'use strict'; - var version = "2.0.15"; + var version = "2.0.16"; var KUTE = {}; @@ -921,8 +921,8 @@ function getAttr(tweenProp,value){ var attrStartValues = {}; for (var attr in value){ - var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''); - var currentValue = this.element.getAttribute(attribute); + var attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), + 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; @@ -930,13 +930,13 @@ function prepareAttr(tweenProp,attrObj){ var attributesObject = {}; for ( var p in attrObj ) { - var prop = replaceUppercase(p); - var regex = /(%|[a-z]+)$/; - var currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); + var prop = replaceUppercase(p), + regex = /(%|[a-z]+)$/, + currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); if ( !svgColors.includes(prop)) { if ( currentValue !== null && regex.test(currentValue) ) { - var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - var suffix = /%/.test(unit) ? '_percent' : ("_" + unit); + var unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u, + suffix = /%/.test(unit) ? '_percent' : ("_" + unit); onStart[ComponentName][prop+suffix] = function(tp) { if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { attributes[tp] = function (elem, p, a, b, v) { @@ -1379,15 +1379,15 @@ return ((Math.sqrt(.5 * ((len * len) + (wid * wid)))) * (Math.PI * 2)) / 2; } function getTotalLength(el) { - if (/rect/.test(el.tagName)) { + if ('rect'===el.tagName) { return getRectLength(el); - } else if (/circle/.test(el.tagName)) { + } else if ('circle'===el.tagName) { return getCircleLength(el); - } else if (/ellipse/.test(el.tagName)) { + } else if ('ellipse'===el.tagName) { return getEllipseLength(el); - } else if (/polygon|polyline/.test(el.tagName)) { + } else if (['polygon,polyline'].indexOf(el.tagName)>-1) { return getPolyLength(el); - } else if (/line/.test(el.tagName)) { + } else if ('line'===el.tagName) { return getLineLength(el); } } @@ -1463,51 +1463,69 @@ } } - function clonePath(pathArray){ - return pathArray.map(function (x) { return Array.isArray(x) ? clonePath(x) : !isNaN(+x) ? +x : x; } ) - } - - var SVGPathCommanderOptions = { + var options = { + origin:null, decimals:3, round:1 }; - function roundPath(pathArray) { - return pathArray.map( function (seg) { return seg.map(function (c,i) { - var nr = +c, dc = Math.pow(10,SVGPathCommanderOptions.decimals); - return i ? (nr % 1 === 0 ? nr : (nr*dc>>0)/dc) : c - } - ); }) + function clonePath(pathArray){ + return pathArray.map(function (x) { return Array.isArray(x) + ? clonePath(x) + : !isNaN(+x) ? +x : x; } ) } - function SVGPathArray(pathString){ - this.segments = []; - this.pathValue = pathString; - this.max = pathString.length; - this.index = 0; - this.param = 0.0; - this.segmentStart = 0; - this.data = []; - this.err = ''; - return this + function roundPath(pathArray,round) { + var decimalsOption = !isNaN(+round) ? +round : options.decimals; + return decimalsOption ? + pathArray.map( function (seg) { return seg.map(function (c,i) { + var nr = +c, dc = Math.pow(10,decimalsOption); + return nr ? (nr % 1 === 0 ? nr : Math.round(nr*dc)/dc) : c + } + ); }) : clonePath(pathArray) + } + + function fixArc(pathArray, allPathCommands, i) { + if (pathArray[i].length > 7) { + pathArray[i].shift(); + var pi = pathArray[i]; + while (pi.length) { + allPathCommands[i] = "A"; + pathArray.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + } + pathArray.splice(i, 1); + } } var paramsCount = { a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0 }; + function isPathArray(pathArray){ + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[achlmrqstvz]/g.test(pathCommand) + }) + } + + function isCurveArray(pathArray){ + return isPathArray(pathArray) && pathArray.slice(1).every(function (seg){ return seg[0] === 'C'; }) + } + function finalizeSegment(state) { - var cmd = state.pathValue[state.segmentStart], cmdLC = cmd.toLowerCase(), params = state.data; - if (cmdLC === 'm' && params.length > 2) { - state.segments.push([ cmd, params[0], params[1] ]); + var pathCommand = state.pathValue[state.segmentStart], + pathComLK = pathCommand.toLowerCase(), + params = state.data; + if (pathComLK === 'm' && params.length > 2) { + state.segments.push([ pathCommand, params[0], params[1] ]); params = params.slice(2); - cmdLC = 'l'; - cmd = (cmd === 'm') ? 'l' : 'L'; + pathComLK = 'l'; + pathCommand = (pathCommand === 'm') ? 'l' : 'L'; } - if (cmdLC === 'r') { - state.segments.push([ cmd ].concat(params)); + if (pathComLK === 'r') { + state.segments.push([ pathCommand ].concat(params)); } else { - while (params.length >= paramsCount[cmdLC]) { - state.segments.push([ cmd ].concat(params.splice(0, paramsCount[cmdLC]))); - if (!paramsCount[cmdLC]) { + while (params.length >= paramsCount[pathComLK]) { + state.segments.push([ pathCommand ].concat(params.splice(0, paramsCount[pathComLK]))); + if (!paramsCount[pathComLK]) { break; } } @@ -1528,7 +1546,7 @@ state.index++; return; } - state.err = invalidPathValue; + state.err = invalidPathValue + ": invalid Arc flag " + ch; } function isDigit(code) { @@ -1545,7 +1563,7 @@ hasDot = false, ch; if (index >= max) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing param " + (state.pathValue[index]); return; } ch = state.pathValue.charCodeAt(index); @@ -1554,7 +1572,7 @@ ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; } if (!isDigit(ch) && ch !== 0x2E) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " not number"; return; } if (ch !== 0x2E) { @@ -1563,7 +1581,7 @@ ch = (index < max) ? state.pathValue.charCodeAt(index) : 0; if (zeroFirst && index < max) { if (ch && isDigit(ch)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[start]) + " illegal number"; return; } } @@ -1584,7 +1602,7 @@ } if (ch === 0x65 || ch === 0x45) { if (hasDot && !hasCeiling && !hasDecimal) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } index++; @@ -1597,7 +1615,7 @@ index++; } } else { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[index]) + " invalid float exponent"; return; } } @@ -1605,6 +1623,21 @@ state.param = +state.pathValue.slice(start, index); } + 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) || + (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); + } + + function skipSpaces(state) { + while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { + state.index++; + } + } + function isPathCommand(code) { switch (code | 0x20) { case 0x6D: @@ -1634,27 +1667,12 @@ return (code | 0x20) === 0x61; } - 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) || - (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || - (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0); - } - - function skipSpaces(state) { - while (state.index < state.max && isSpace(state.pathValue.charCodeAt(state.index))) { - state.index++; - } - } - function scanSegment(state) { var max = state.max, cmdCode, comma_found, need_params, i; state.segmentStart = state.index; cmdCode = state.pathValue.charCodeAt(state.index); if (!isPathCommand(cmdCode)) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": " + (state.pathValue[state.index]) + " not a path command"; return; } need_params = paramsCount[state.pathValue[state.index].toLowerCase()]; @@ -1695,106 +1713,45 @@ finalizeSegment(state); } - function isPathArray(pathArray){ - return Array.isArray(pathArray) && pathArray.every(function (x){ - var pathCommand = x[0].toLowerCase(); - return paramsCount[pathCommand] === x.length - 1 && /[achlmrqstvz]/g.test(pathCommand) - }) + function SVGPathArray(pathString){ + this.segments = []; + this.pathValue = pathString; + this.max = pathString.length; + this.index = 0; + this.param = 0.0; + this.segmentStart = 0; + this.data = []; + this.err = ''; + return this } - function parsePathString(pathString) { + function parsePathString(pathString,round) { if ( isPathArray(pathString) ) { return clonePath(pathString) } - var state = new SVGPathArray(pathString), max = state.max; + var state = new SVGPathArray(pathString); skipSpaces(state); - while (state.index < max && !state.err.length) { + while (state.index < state.max && !state.err.length) { scanSegment(state); } if (state.err.length) { state.segments = []; } else if (state.segments.length) { if ('mM'.indexOf(state.segments[0][0]) < 0) { - state.err = invalidPathValue; + state.err = invalidPathValue + ": missing M/m"; state.segments = []; } else { state.segments[0][0] = 'M'; } } - return roundPath(state.segments) - } - - function catmullRom2bezier(crp, z) { - var d = []; - for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { - var p = [ - {x: +crp[i - 2], y: +crp[i - 1]}, - {x: +crp[i], y: +crp[i + 1]}, - {x: +crp[i + 2], y: +crp[i + 3]}, - {x: +crp[i + 4], y: +crp[i + 5]} - ]; - if (z) { - if (!i) { - p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; - } else if (iLen - 4 == i) { - p[3] = {x: +crp[0], y: +crp[1]}; - } else if (iLen - 2 == i) { - p[2] = {x: +crp[0], y: +crp[1]}; - p[3] = {x: +crp[2], y: +crp[3]}; - } - } else { - if (iLen - 4 == i) { - p[3] = p[2]; - } else if (!i) { - p[0] = {x: +crp[i], y: +crp[i + 1]}; - } - } - d.push([ - "C", - (-p[0].x + 6 * p[1].x + p[2].x) / 6, - (-p[0].y + 6 * p[1].y + p[2].y) / 6, - (p[1].x + 6 * p[2].x - p[3].x) / 6, - (p[1].y + 6*p[2].y - p[3].y) / 6, - p[2].x, - p[2].y - ]); - } - return d - } - - function ellipseToArc(x, y, rx, ry, a) { - if (a == null && ry == null) { - ry = rx; - } - x = +x; - y = +y; - rx = +rx; - ry = +ry; - var res; - if (a != null) { - var rad = Math.PI / 180, - x1 = x + rx * Math.cos(-ry * rad), - x2 = x + rx * Math.cos(-a * rad), - y1 = y + rx * Math.sin(-ry * rad), - y2 = y + rx * Math.sin(-a * rad); - res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; - } else { - res = [ - ["M", x, y], - ["m", 0, -ry], - ["a", rx, ry, 0, 1, 1, 0, 2 * ry], - ["a", rx, ry, 0, 1, 1, 0, -2 * ry], - ["z"] - ]; - } - return res; + return roundPath(state.segments,round) } function isAbsoluteArray(pathInput){ return isPathArray(pathInput) && pathInput.every(function (x){ return x[0] === x[0].toUpperCase(); }) } - function pathToAbsolute(pathArray) { + function pathToAbsolute(pathArray,round) { if (isAbsoluteArray(pathArray)) { return clonePath(pathArray) } @@ -1802,10 +1759,8 @@ var resultArray = [], x = 0, y = 0, mx = 0, my = 0, start = 0, ii = pathArray.length, - crz = pathArray.length === 3 && - pathArray[0][0] === "M" && - pathArray[1][0].toUpperCase() === "R" && - pathArray[2][0].toUpperCase() === "Z"; + pathCommand = '', segment = [], segLength = 0, + absoluteSegment = []; if (pathArray[0][0] === "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; @@ -1814,215 +1769,417 @@ start++; resultArray[0] = ["M", x, y]; } - var loop = function ( i ) { - var r = [], pa = pathArray[i], pa0 = pa[0], dots = []; - resultArray.push(r = []); - if (pa0 !== pa0.toUpperCase()) { - r[0] = pa0.toUpperCase(); - switch (r[0]) { + for (var i = start; i < ii; i++) { + segment = pathArray[i]; + pathCommand = segment[0]; + resultArray.push(absoluteSegment = []); + if (pathCommand !== pathCommand.toUpperCase()) { + absoluteSegment[0] = pathCommand.toUpperCase(); + switch (absoluteSegment[0]) { case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +pa[6] + x; - r[7] = +pa[7] + y; + segment.slice(1,-2) + .concat([+segment[6] + x, +segment[7] + y]) + .map(function (s){ return absoluteSegment.push(s); }); break; case "V": - r[1] = +pa[1] + y; + absoluteSegment[1] = +segment[1] + y; break; case "H": - r[1] = +pa[1] + x; - break; - case "R": - dots = [x, y].concat(pa.slice(1)); - for (var j = 2, jj = dots.length; j < jj; j++) { - dots[j] = +dots[j] + x; - dots[++j] = +dots[j] + y; - } - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - break; - case "O": - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - break; - case "U": - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, pa[1], pa[2], pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); + absoluteSegment[1] = +segment[1] + x; break; case "M": - mx = +pa[1] + x; - my = +pa[2] + y; + mx = +segment[1] + x; + my = +segment[2] + y; default: - for (var k = 1, kk = pa.length; k < kk; k++) { - r[k] = +pa[k] + ((k % 2) ? x : y); - } + segment.map(function (s,j){ return j && absoluteSegment.push(+s + ((j % 2) ? x : y)); }); } - } else if (pa0 === "R") { - dots = [x, y].concat(pa.slice(1)); - resultArray.pop(); - resultArray = resultArray.concat(catmullRom2bezier(dots, crz)); - r = ["R"].concat(pa.slice(-2)); - } else if (pa0 === "O") { - resultArray.pop(); - dots = ellipseToArc(x, y, +pa[1], +pa[2]); - dots.push(dots[0]); - resultArray = resultArray.concat(dots); - } else if (pa0 === "U") { - resultArray.pop(); - resultArray = resultArray.concat(ellipseToArc(x, y, +pa[1], +pa[2], +pa[3])); - r = ["U"].concat(resultArray[resultArray.length - 1].slice(-2)); } else { - pa.map(function (k){ return r.push(k); }); + segment.map(function (k){ return absoluteSegment.push(k); }); } - pa0 = pa0.toUpperCase(); - if (pa0 !== "O") { - switch (r[0]) { - case "Z": - x = mx; - y = my; - break; - case "H": - x = +r[1]; - break; - case "V": - y = +r[1]; - break; - case "M": - mx = +r[r.length - 2]; - my = +r[r.length - 1]; - default: - x = +r[r.length - 2]; - y = +r[r.length - 1]; - } + segLength = absoluteSegment.length; + switch (absoluteSegment[0]) { + case "Z": + x = mx; + y = my; + break; + case "H": + x = +absoluteSegment[1]; + break; + case "V": + y = +absoluteSegment[1]; + break; + case "M": + mx = +absoluteSegment[segLength - 2]; + my = +absoluteSegment[segLength - 1]; + default: + x = +absoluteSegment[segLength - 2]; + y = +absoluteSegment[segLength - 1]; } + } + return roundPath(resultArray,round) + } + + function shorthandToQuad(x1,y1,qx,qy,prevCommand){ + return 'QT'.indexOf(prevCommand)>-1 ? { qx: x1 * 2 - qx, qy: y1 * 2 - qy} + : { qx: x1, qy: y1 } + } + + function shorthandToCubic(x1,y1,x2,y2,prevCommand){ + return 'CS'.indexOf(prevCommand)>-1 ? { x1: x1 * 2 - x2, y1: y1 * 2 - y2} + : { x1: x1, y1: y1 } + } + + function normalizeSegment(segment, params, prevCommand) { + var nqxy, nxy; + 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); + switch (segment[0]) { + case "H": + return ["L", segment[1], params.y1] + case "V": + return ["L", params.x1, segment[1]] + case "S": + nxy = shorthandToCubic(params.x1,params.y1, params.x2,params.y2, prevCommand); + params.x1 = nxy.x1; + params.y1 = nxy.y1; + return ["C", nxy.x1, nxy.y1].concat(segment.slice(1)) + case "T": + nqxy = shorthandToQuad(params.x1,params.y1, params.qx, params.qy, prevCommand); + params.qx = nqxy.qx; + params.qy = nqxy.qy; + return ["Q", params.qx, params.qy].concat(segment.slice(1)) + case "Q": + params.qx = segment[1]; + params.qy = segment[2]; + } + return segment + } + + function isNormalizedArray(pathArray){ + return Array.isArray(pathArray) && pathArray.every(function (seg){ + var pathCommand = seg[0].toLowerCase(); + return paramsCount[pathCommand] === seg.length - 1 && /[ACLMQZ]/.test(seg[0]) + }) + } + + function normalizePath(pathArray,round) { + if (isNormalizedArray(pathArray)) { + return clonePath(pathArray) + } + pathArray = pathToAbsolute(pathArray); + var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, + allPathCommands = [], pathCommand = '', prevCommand = '', + ii = pathArray.length, segment, seglen; + for (var i = 0; i < ii; i++) { + pathCommand = pathArray[i][0]; + allPathCommands[i] = pathCommand; + i && ( prevCommand = allPathCommands[i - 1]); + pathArray[i] = normalizeSegment(pathArray[i], params, prevCommand); + segment = pathArray[i]; + 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 roundPath(pathArray,round) + } + + function rotateVector(x, y, rad) { + var X = x * Math.cos(rad) - y * Math.sin(rad), + Y = x * Math.sin(rad) + y * Math.cos(rad); + return {x: X, y: Y} + } + + function arcToCubic(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + var _120 = Math.PI * 120 / 180, + rad = Math.PI / 180 * (angle || 0), + res = [], xy, f1, f2, cx, 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, + y = (y1 - y2) / 2, + h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + if (h > 1) { + h = Math.sqrt(h); + rx = h * rx; + ry = h * ry; + } + var rx2 = rx * rx, + ry2 = ry * ry, + k = (large_arc_flag == sweep_flag ? -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; + f1 = Math.asin( ((y1 - cy) / ry).toFixed(9) ); + f2 = Math.asin( ((y2 - cy) / ry).toFixed(9) ); + f1 = x1 < cx ? Math.PI - f1 : f1; + f2 = x2 < cx ? Math.PI - f2 : f2; + f1 < 0 && (f1 = Math.PI * 2 + f1); + f2 < 0 && (f2 = Math.PI * 2 + f2); + if (sweep_flag && f1 > f2) { + f1 = f1 - Math.PI * 2; + } + if (!sweep_flag && f2 > f1) { + f2 = f2 - Math.PI * 2; + } + } else { + f1 = recursive[0]; + f2 = recursive[1]; + cx = recursive[2]; + cy = recursive[3]; + } + var df = f2 - f1; + if (Math.abs(df) > _120) { + var f2old = f2, x2old = x2, y2old = y2; + f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); + x2 = cx + rx * Math.cos(f2); + y2 = cy + ry * Math.sin(f2); + res = arcToCubic(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + } + df = f2 - f1; + var c1 = Math.cos(f1), + s1 = Math.sin(f1), + c2 = Math.cos(f2), + s2 = Math.sin(f2), + t = Math.tan(df / 4), + hx = 4 / 3 * rx * t, + hy = 4 / 3 * ry * t, + m1 = [x1, y1], + m2 = [x1 + hx * s1, y1 - hy * c1], + m3 = [x2 + hx * s2, y2 - hy * c2], + m4 = [x2, y2]; + m2[0] = 2 * m1[0] - m2[0]; + m2[1] = 2 * m1[1] - m2[1]; + if (recursive) { + return [m2, m3, m4].concat(res); + } else { + res = [m2, m3, m4].concat(res).join().split(","); + return res.map(function (rz,i){ return i % 2 ? rotateVector(res[i - 1], rz, rad).y : rotateVector(rz, res[i + 1], rad).x; }); + } + } + + function quadToCubic (x1, y1, qx, qy, x2, y2) { + var _13 = 1 / 3, _23 = 2 / 3; + return [ + _13 * x1 + _23 * qx, + _13 * y1 + _23 * qy, + _13 * x2 + _23 * qx, + _13 * y2 + _23 * qy, + x2, y2 ] + } + + function getPointAtSegLength (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: Math.pow(t1, 3) * p1x + Math.pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + Math.pow(t, 3) * p2x, + y: Math.pow(t1, 3) * p1y + Math.pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + Math.pow(t, 3) * p2y }; - for (var i = start; i < ii; i++) loop( i ); - return roundPath(resultArray) + } + + function midPoint(a, b, t) { + var ax = a[0], ay = a[1], bx = b[0], by = b[1]; + return [ ax + (bx - ax) * t, ay + (by - ay) * t]; + } + + function lineToCubic(x1, y1, x2, y2) { + var t = 0.5, + p0 = [x1,y1], + p1 = [x2,y2], + p2 = midPoint(p0, p1, t), + p3 = midPoint(p1, p2, t), + p4 = midPoint(p2, p3, t), + p5 = midPoint(p3, p4, t), + p6 = midPoint(p4, p5, t), + cp1 = getPointAtSegLength.apply(0, p0.concat( p2, p4, p6, t)), + cp2 = getPointAtSegLength.apply(0, p6.concat( p5, p3, p1, 0)); + return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2] + } + + function segmentToCubic(segment, params) { + 'TQ'.indexOf(segment[0])<0 && (params.qx = params.qy = null); + switch (segment[0]) { + case 'M': + params.x = segment[1]; + params.y = segment[2]; + return segment + case 'A': + return ['C'].concat(arcToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) + case 'Q': + params.qx = segment[1]; + params.qy = segment[2]; + return ['C'].concat(quadToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1)))) + case 'L': + return ['C'].concat(lineToCubic(params.x1, params.y1, segment[1], segment[2])) + case 'Z': + return ['C'].concat(lineToCubic(params.x1, params.y1, params.x, params.y)) + } + return segment + } + + function pathToCurve(pathArray,round) { + if (isCurveArray(pathArray)){ + return clonePath(pathArray) + } + pathArray = normalizePath(pathArray); + var params = {x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null}, + allPathCommands = [], pathCommand = '', + ii = pathArray.length, segment, seglen; + for (var i = 0; i < ii; i++) { + pathArray[i] && (pathCommand = pathArray[i][0]); + allPathCommands[i] = pathCommand; + pathArray[i] = segmentToCubic(pathArray[i], params); + fixArc(pathArray,allPathCommands,i); + ii = pathArray.length; + segment = pathArray[i]; + 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 roundPath(pathArray,round) } function pathToString(pathArray) { return pathArray.map(function (x){ return x[0].concat(x.slice(1).join(' ')); }).join('') } - function splitPath(pathString) { - return pathString + 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; }) } - function createPath(path) { - var np = document.createElementNS('http://www.w3.org/2000/svg','path'), - d = path instanceof SVGElement && ['path','glyph'].indexOf(path.tagName) > -1 ? path.getAttribute('d') : path; - np.setAttribute('d',d); - return np + function base3(p1, p2, p3, p4, t) { + var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, + t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; + return t * t2 - 3 * p1 + 3 * p2; + } + function getSegCubicLength (x1, y1, x2, y2, x3, y3, x4, y4, z) { + (z === null || isNaN(+z)) && (z = 1); + z = z > 1 ? 1 : z < 0 ? 0 : z; + var z2 = z / 2, ct = 0, xbase = 0, ybase = 0, sum = 0, + Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816], + Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472]; + Tvalues.map(function (T,i){ + ct = z2 * T + z2; + xbase = base3( x1, x2, x3, x4, ct); + ybase = base3( y1, y2, y3, y4, ct); + sum += Cvalues[i] * Math.sqrt(xbase * xbase + ybase * ybase); + }); + return z2 * sum } - function polygonArea(polygon) { - var i = -1, - n = polygon.length, - a, - b = polygon[n - 1], - area = 0; - while (++i < n) { - a = b; - b = polygon[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area / 2; + function getPathLength(pathArray){ + var totalLength = 0; + pathToCurve(pathArray).map(function (s,i,curveArray) { + totalLength += 'M' !== s[0] ? getSegCubicLength.apply(0, curveArray[i-1].slice(-2).concat(s.slice(1)) ) : 0; + }); + return totalLength } - function polygonLength(polygon) { - var i = -1, - n = polygon.length, - b = polygon[n - 1], - xa, - ya, - xb = b[0], - yb = b[1], - perimeter = 0; - while (++i < n) { - xa = xb; - ya = yb; - b = polygon[i]; - xb = b[0]; - yb = b[1]; - xa -= xb; - ya -= yb; - perimeter += Math.hypot(xa, ya); - } - return perimeter; + function getPointAtLength(pathArray,length){ + var totalLength = 0, segLen, data; + return pathToCurve(pathArray).map(function (seg,i,curveArray) { + data = i ? curveArray[i-1].slice(-2).concat(seg.slice(1)) : seg.slice(1); + segLen = i ? getSegCubicLength.apply(0, data) : 0; + totalLength += segLen; + return i === 0 ? {x:data[0], y:data[1]} : + totalLength>length && length>totalLength-segLen ? + getPointAtSegLength.apply(0,data.concat(1 - (totalLength-length)/segLen)) : null + }).filter(function (x){ return x; }).slice(-1)[0] } - function isFiniteNumber(number) { - return typeof number === "number" && isFinite(number); + function getCubicSegArea(x0,y0, x1,y1, x2,y2, x3,y3) { + return 3 * ((y3 - y0) * (x1 + x2) - (x3 - x0) * (y1 + y2) + + y1 * (x0 - x2) - x1 * (y0 - y2) + + y3 * (x2 + x0 / 3) - x3 * (y2 + y0 / 3)) / 20; } + function getPathArea(pathArray) { + var x = 0, y = 0, mx = 0, my = 0, len = 0; + return pathToCurve(pathArray).map(function (seg) { + var assign; + switch (seg[0]){ + case 'M': + case 'Z': + mx = seg[0] === 'M' ? seg[1] : mx; + my = seg[0] === 'M' ? seg[2] : my; + x = mx; + y = my; + return 0 + default: + len = getCubicSegArea.apply(0, [x,y].concat(seg.slice(1) )); + (assign = seg.slice(-2), x = assign[0], y = assign[1]); + return len + } + }).reduce(function (a, b) { return a + b; }, 0) + } + + function getDrawDirection(pathArray) { + return getPathArea(pathToCurve(pathArray)) >= 0 + } + + var epsilon = 1e-9; + function distanceSquareRoot(a, b) { return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) - ); + (a[0] - b[0]) * (a[0] - b[0]) + + (a[1] - b[1]) * (a[1] - b[1]) + ) } - function pointAlong(a, b, pct) { - return [a[0] + (b[0] - a[0]) * pct, a[1] + (b[1] - a[1]) * pct]; - } - function samePoint(a, b) { - return distanceSquareRoot(a, b) < 1e-9; + + function polygonLength(ring){ + return ring.reduce(function (length, point, i) { return i ? length + distanceSquareRoot(ring[i-1],point) : 0; }, 0 ) } function pathStringToRing(str, maxSegmentLength) { - var parsed = pathToAbsolute(str); + var parsed = normalizePath(str,0); return exactRing(parsed) || approximateRing(parsed, maxSegmentLength); } - function exactRing(segments) { - var ring = []; - if (!segments.length || segments[0][0] !== "M") { + function exactRing(pathArray) { + var ring = [], + segment = [], pathCommand = '', + pathlen = pathArray.length, + pathLength = 0; + if (!pathArray.length || pathArray[0][0] !== "M") { return false; } - for (var i = 0; i < segments.length; i++) { - var ref = segments[i]; - var command = ref[0]; - var x = ref[1]; - var y = ref[2]; - if ((command === "M" && i) || command === "Z") { + for (var i = 0; i < pathlen; i++) { + segment = pathArray[i]; + pathCommand = segment[0]; + if (pathCommand === "M" && i || pathCommand === "Z") { break; - } else if (command === "M" || command === "L") { - ring.push([x, y]); - } else if (command === "H") { - ring.push([x, ring[ring.length - 1][1]]); - } else if (command === "V") { - ring.push([ring[ring.length - 1][0], x]); + } else if ('ML'.indexOf( pathCommand) > -1) { + ring.push([segment[1], segment[2]]); } else { return false; } } - return ring.length ? { ring: ring } : false; + pathLength = polygonLength(ring); + return pathlen ? { ring: ring, pathLength: pathLength } : false; } function approximateRing(parsed, maxSegmentLength) { var ringPath = splitPath(pathToString(parsed))[0], - ring = [], len, testPath, numPoints = 3; - if (!ringPath) { - throw (invalidPathValue); - } - testPath = createPath(ringPath); - len = testPath.getTotalLength(); - if ( - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { - numPoints = Math.max(numPoints, Math.ceil(len / maxSegmentLength)); + curvePath = pathToCurve(ringPath,4), + pathLength = getPathLength(curvePath), + ring = [], numPoints = 3, point; + if ( maxSegmentLength && !isNaN(maxSegmentLength) && +maxSegmentLength > 0 ) { + numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength)); } for (var i = 0; i < numPoints; i++) { - var p = testPath.getPointAtLength((len * i) / numPoints); - ring.push([p.x, p.y]); + point = getPointAtLength(curvePath,pathLength * i / numPoints); + ring.push([point.x, point.y]); + } + if (!getDrawDirection(curvePath)) { + ring.reverse(); } return { + pathLength: pathLength, ring: ring, skipBisect: true }; @@ -2048,12 +2205,14 @@ } function addPoints(ring, numPoints) { var desiredLength = ring.length + numPoints, - step = polygonLength(ring) / numPoints; - var i = 0, cursor = 0, insertAt = step / 2; + step = polygonLength(ring) / numPoints; + var i = 0, cursor = 0, insertAt = step / 2, a, b, segment; while (ring.length < desiredLength) { - var a = ring[i], b = ring[(i + 1) % ring.length], segment = distanceSquareRoot(a, b); + a = ring[i]; + b = ring[(i + 1) % ring.length]; + segment = distanceSquareRoot(a, b); if (insertAt <= cursor + segment) { - ring.splice( i + 1, 0, segment ? pointAlong(a, b, (insertAt - cursor) / segment) : a.slice(0) ); + ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) ); insertAt += step; continue; } @@ -2063,53 +2222,40 @@ } function bisect(ring, maxSegmentLength) { if ( maxSegmentLength === void 0 ) maxSegmentLength = Infinity; + var a = [], b = []; for (var i = 0; i < ring.length; i++) { - var a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; + a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = pointAlong(a, b, 0.5); + b = midPoint(a, b, 0.5); ring.splice(i + 1, 0, b); } } } function normalizeRing(ring, maxSegmentLength) { - var points, area, skipBisect; + var points, skipBisect, pathLength; if (typeof ring === "string") { var converted = pathStringToRing(ring, maxSegmentLength); ring = converted.ring; skipBisect = converted.skipBisect; + pathLength = converted.pathLength; } else if (!Array.isArray(ring)) { - throw (invalidPathValue); + throw (invalidPathValue) } points = ring.slice(0); + points.pathLength = pathLength; if (!validRing(points)) { - throw (invalidPathValue); + throw (invalidPathValue) } - if (points.length > 1 && samePoint(points[0], points[points.length - 1])) { + if (points.length > 1 && distanceSquareRoot(points[0], points[points.length - 1]) < epsilon) { points.pop(); } - area = polygonArea(points); - if (area > 0) { - points.reverse(); - } - if ( - !skipBisect && - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { + if ( !skipBisect && maxSegmentLength && !isNaN(maxSegmentLength) && (+maxSegmentLength) > 0 ) { bisect(points, maxSegmentLength); } - return points; + return points } function validRing(ring) { - return ring.every(function(point) { - return ( - Array.isArray(point) && - point.length >= 2 && - isFiniteNumber(point[0]) && - isFiniteNumber(point[1]) - ); - }); + return Array.isArray(ring) && ring.every( function (point) { return Array.isArray(point) && point.length === 2 && !isNaN(point[0]) && !isNaN(point[1]); }) } function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { morphPrecision = morphPrecision || defaultOptions.morphPrecision; @@ -2118,8 +2264,8 @@ diff = fromRing.length - toRing.length; addPoints(fromRing, diff < 0 ? diff * -1 : 0); addPoints(toRing, diff > 0 ? diff : 0); - rotateRing(fromRing, toRing); - return [fromRing,toRing] + rotateRing(fromRing,toRing); + return [roundPath(fromRing),roundPath(toRing)] } function getSVGMorph(tweenProp){ return this.element.getAttribute('d'); @@ -2166,10 +2312,10 @@ Util: { addPoints: addPoints,bisect: bisect,normalizeRing: normalizeRing,validRing: validRing, getInterpolationPoints: getInterpolationPoints,pathStringToRing: pathStringToRing, - isFiniteNumber: isFiniteNumber,distanceSquareRoot: distanceSquareRoot,pointAlong: pointAlong,samePoint: samePoint, - exactRing: exactRing,approximateRing: approximateRing,createPath: createPath,rotateRing: rotateRing, - pathToAbsolute: pathToAbsolute,pathToString: pathToString, - polygonLength: polygonLength,polygonArea: polygonArea + distanceSquareRoot: distanceSquareRoot,midPoint: midPoint, + approximateRing: approximateRing,rotateRing: rotateRing, + pathToString: pathToString,pathToCurve: pathToCurve, + getPathLength: getPathLength,getPointAtLength: getPointAtLength,getDrawDirection: getDrawDirection,roundPath: roundPath } }; Components.SVGMorph = svgMorph; diff --git a/dist/kute.min.js b/dist/kute.min.js index ef8f16c..e849259 100644 --- a/dist/kute.min.js +++ b/dist/kute.min.js @@ -1,2 +1,2 @@ -// KUTE.js Standard v2.0.15 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function U(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);T.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var H=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:L.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};H.prototype.start=function(e){return _(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),U.call(this),this._startFired=!0),!s&&o(),this},H.prototype.stop=function(){return this.playing&&(C(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},H.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},H.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},H.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},H.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},L.tween=H,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var N=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(M.call(this,i,"end"),this._resetStart?this.valuesStart=r:M.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,I.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),U.call(this),this._startTime+=t.Time()-this._pauseTime,_(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(C(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(H);L.tween=N;var j=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new L.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};j.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},j.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},j.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},j.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},j.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof j)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},j.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},j.prototype.removeTweens=function(){this.tweens=[]},j.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function R(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a.99||i<.01?(10*D(n,r,i)>>0)/10:D(n,r,i)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var b in a)if(b in t.functions)if("function"==typeof t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][s||o]&&(a[b][n][s||o]=t.functions[b]);else for(var x in t.functions[b])!a[b][n]&&(a[b][n]={}),!a[b][n][x]&&(a[b][n][x]=t.functions[b][x]);if(t.Interpolate){for(var _ in t.Interpolate){var C=t.Interpolate[_];if("function"!=typeof C||r[_])for(var T in C)"function"!=typeof C[T]||r[_]||(r[_]=C[T]);else r[_]=C}m[n]=t.Interpolate}if(t.Util)for(var S in t.Util)!w[S]&&(w[S]=t.Util[S]);return e};var X=["top","left","width","height"],B={};X.map((function(t){return B[t]=Q}));var z={component:"essentialBoxModel",category:"boxModel",properties:X,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:D},functions:{prepareStart:function(t){return A(this.element,t)||h[t]},prepareProperty:function(t,e){var n=R(e),r="height"===t?"offsetHeight":"offsetWidth";return"%"===n.u?n.v*this.element[r]/100:n.v},onStart:B},Util:{trueDimension:R}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function q(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?D(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*D(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=q(n,r,i)})}x.BoxModelEssential=z;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var G={};K.map((function(t){return G[t]=Y}));var W={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:D,colors:q},functions:{prepareStart:function(t,e){return A(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:G},Util:{trueColor:Z}};x.ColorProperties=W;var J={},tt="htmlAttributes",et=["fill","stroke","stop-color"];function nt(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var rt={prepareStart:function(t,e){var n={};for(var r in e){var i=nt(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=et.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=nt(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(et.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,q(n,r,i))})},n[a]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=R(o).u||R(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*D(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=R(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*D(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},it={component:tt,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:q},functions:rt,Util:{replaceUppercase:nt,trueColor:Z,trueDimension:R}};x.HTMLAttributes=it;var at={prepareStart:function(t){return A(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*D(n,r,i)>>0)/1e3})}},st={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:D},functions:at};x.OpacityProperty=st;var ot=String("abcdefghijklmnopqrstuvwxyz").split(""),ut=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),lt=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ct=String("0123456789").split(""),pt=ot.concat(ut,ct),ht=pt.concat(lt),ft={alpha:ot,upper:ut,symbols:lt,numeric:ct,alphanumeric:pt,all:ht},dt={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ft?ft[n]:n&&n.length?n:ft[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=D(e,n,r)>>0})}};function vt(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function gt(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function bt(t,e,n,r){for(var i=[],a=0;a<3;a++)i[a]=(t[a]||e[a]?(1e3*(t[a]+(e[a]-t[a])*r)>>0)/1e3:0)+n;return"translate3d("+i.join(",")+")"}function wt(t,e,n,r){var i="";return i+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",i+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",i+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function xt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function _t(t,e,n,r){var i=[];return i[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+i.join(",")+")"}x.TextWriteProperties=yt;var Ct={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,e){var n=E(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},i=[],a=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?i:"rotate"===c?a:"skew"===c?s:{},d=0;d>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+i.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:xt,skew:_t}};function Tt(t,e){return parseFloat(t)/100*e}function St(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function Et(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a>0)/100,a=0-(100*D(e.s,n.s,r)>>0)/100,s=(100*D(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Pt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:D},functions:Lt,Util:{getRectLength:St,getPolyLength:Et,getLineLength:At,getCircleLength:Mt,getEllipseLength:It,getTotalLength:kt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Ot,percent:Tt}};function Vt(t,e,n,r){for(var i=[],a=0;a>0)/1e3)}return i}function Ut(t){return t.map((function(t){return Array.isArray(t)?Ut(t):isNaN(+t)?t:+t}))}x.SVGDraw=Pt;var Ht=3;function Nt(t){return t.map((function(t){return t.map((function(t,e){var n=+t,r=Math.pow(10,Ht);return e?n%1==0?n:(n*r>>0)/r:t}))}))}function jt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}var Ft={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Rt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Ft[n]&&(t.segments.push([e].concat(r.splice(0,Ft[n]))),Ft[n]););}var Dt="Invalid path value";function Qt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Dt)}function Xt(t){return t>=48&&t<=57}function Bt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Dt;else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=48&&t<=57||43===t||45===t||46===t}function Zt(t){for(;t.index=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function qt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Ft[t.pathValue[t.index].toLowerCase()],t.index++,Zt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Bt(t):Qt(t),t.err.length)return;t.data.push(t.param),Zt(t),n=!1,t.index=t.max)break;if(!zt(t.pathValue.charCodeAt(t.index)))break}}Rt(t)}else Rt(t);else t.err=Dt}function Yt(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Kt(t,e){for(var n=[],r=0,i=t.length;i-2*!e>r;r+=2){var a=[{x:+t[r-2],y:+t[r-1]},{x:+t[r],y:+t[r+1]},{x:+t[r+2],y:+t[r+3]},{x:+t[r+4],y:+t[r+5]}];e?r?i-4==r?a[3]={x:+t[0],y:+t[1]}:i-2==r&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[i-2],y:+t[i-1]}:i-4==r?a[3]=a[2]:r||(a[0]={x:+t[r],y:+t[r+1]}),n.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return n}function $t(t,e,n,r,i){var a;if(null==i&&null==r&&(r=n),t=+t,e=+e,n=+n,r=+r,null!=i){var s=Math.PI/180,o=t+n*Math.cos(-r*s),u=t+n*Math.cos(-i*s);a=[["M",o,e+n*Math.sin(-r*s)],["A",n,n,0,+(i-r>180),0,u,e+n*Math.sin(-i*s)]]}else a=[["M",t,e],["m",0,-r],["a",n,r,0,1,1,0,2*r],["a",n,r,0,1,1,0,-2*r],["z"]];return a}function Gt(t){if(Yt(e=t)&&e.every((function(t){return t[0]===t[0].toUpperCase()})))return Ut(t);var e;t=function(t){if(Yt(t))return Ut(t);var e=new jt(t),n=e.max;for(Zt(e);e.index-1?t.getAttribute("d"):t;return e.setAttribute("d",n),e}function te(t){for(var e,n=-1,r=t.length,i=t[r-1],a=0;++n0&&(o=Math.max(o,Math.ceil(n/e)));for(var u=0;ue;)i=ie(r,i,.5),t.splice(n+1,0,i)}function he(t,e){var n,r;if("string"==typeof t){var i=se(t,e);t=i.ring,r=i.skipBisect}else if(!Array.isArray(t))throw Dt;if(!fe(n=t.slice(0)))throw Dt;return n.length>1&&ae(n[0],n[n.length-1])&&n.pop(),te(n)>0&&n.reverse(),!r&&e&&ne(e)&&e>0&&pe(n,e),n}function fe(t){return t.every((function(t){return Array.isArray(t)&&t.length>=2&&ne(t[0])&&ne(t[1])}))}function de(t,e,n){var r=he(t,n=n||f.morphPrecision),i=he(e,n),a=r.length-i.length;return ce(r,a<0?-1*a:0),ce(i,a>0?a:0),le(r,i),[r,i]}var ve={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var i=e.pathArray,a=n.pathArray,s=a.length;t.setAttribute("d",1===r?n.original:"M"+Vt(i,a,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=de(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},ge={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Vt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:ve,Util:{addPoints:ce,bisect:pe,normalizeRing:he,validRing:fe,getInterpolationPoints:de,pathStringToRing:se,isFiniteNumber:ne,distanceSquareRoot:re,pointAlong:ie,samePoint:ae,exactRing:oe,approximateRing:ue,createPath:Jt,rotateRing:le,pathToAbsolute:Gt,pathToString:Wt,polygonLength:ee,polygonArea:te}};for(var ye in x.SVGMorph=ge,x){var me=x[ye];x[ye]=new F(me)}return{Animation:F,Components:x,Tween:N,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:j,allFromTo:function(t,e,n,r){return r=r||{},new j(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new j(V(t,!0),e,e,n)},Objects:b,Util:w,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:S,Selector:V,Version:"2.0.15"}})); +// KUTE.js Standard v2.0.16 | thednp © 2020 | 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 self?self:"undefined"!=typeof window?window:{},r={},i={},a={};a.now=self.performance.now.bind(self.performance);var s=0,o=function(t){for(var n=0;n(n=1))return n;for(;ei?e=r:n=r,r=.5*(n-e)+e}return r};var L={},P={linear:new O(0,0,1,1,"linear"),easingSinusoidalIn:new O(.47,0,.745,.715,"easingSinusoidalIn"),easingSinusoidalOut:new O(.39,.575,.565,1,"easingSinusoidalOut"),easingSinusoidalInOut:new O(.445,.05,.55,.95,"easingSinusoidalInOut"),easingQuadraticIn:new O(.55,.085,.68,.53,"easingQuadraticIn"),easingQuadraticOut:new O(.25,.46,.45,.94,"easingQuadraticOut"),easingQuadraticInOut:new O(.455,.03,.515,.955,"easingQuadraticInOut"),easingCubicIn:new O(.55,.055,.675,.19,"easingCubicIn"),easingCubicOut:new O(.215,.61,.355,1,"easingCubicOut"),easingCubicInOut:new O(.645,.045,.355,1,"easingCubicInOut"),easingQuarticIn:new O(.895,.03,.685,.22,"easingQuarticIn"),easingQuarticOut:new O(.165,.84,.44,1,"easingQuarticOut"),easingQuarticInOut:new O(.77,0,.175,1,"easingQuarticInOut"),easingQuinticIn:new O(.755,.05,.855,.06,"easingQuinticIn"),easingQuinticOut:new O(.23,1,.32,1,"easingQuinticOut"),easingQuinticInOut:new O(.86,0,.07,1,"easingQuinticInOut"),easingExponentialIn:new O(.95,.05,.795,.035,"easingExponentialIn"),easingExponentialOut:new O(.19,1,.22,1,"easingExponentialOut"),easingExponentialInOut:new O(1,0,0,1,"easingExponentialInOut"),easingCircularIn:new O(.6,.04,.98,.335,"easingCircularIn"),easingCircularOut:new O(.075,.82,.165,1,"easingCircularOut"),easingCircularInOut:new O(.785,.135,.15,.86,"easingCircularInOut"),easingBackIn:new O(.6,-.28,.735,.045,"easingBackIn"),easingBackOut:new O(.175,.885,.32,1.275,"easingBackOut"),easingBackInOut:new O(.68,-.55,.265,1.55,"easingBackInOut")};function V(t,e){try{return e?t instanceof HTMLCollection||t instanceof NodeList||t instanceof Array&&t.every((function(t){return t instanceof Element}))?t:document.querySelectorAll(t):t instanceof Element||t===window?t:document.querySelector(t)}catch(e){console.error("KUTE.js - Element(s) not found: "+t+".")}}function q(){for(var t in i)if("function"==typeof i[t])i[t].call(this,t);else for(var e in i[t])i[t][e].call(this,e);C.call(this)}L.processEasing=function(t){if("function"==typeof t)return t;if("function"==typeof P[t])return P[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(",");return new O(1*e[0],1*e[1],1*e[2],1*e[3])}return/elastic|bounce/i.test(t)&&console.warn("KUTE.js - CubicBezier doesn't support "+t+" easing."),P.linear};var N=function(e,n,r,a){for(var s in this.element=e,this.playing=!1,this._startTime=null,this._startFired=!1,this.valuesEnd=r,this.valuesStart=n,a=a||{},this._resetStart=a.resetStart||0,this._easing="function"==typeof a.easing?a.easing:L.processEasing(a.easing),this._duration=a.duration||f.duration,this._delay=a.delay||f.delay,a){var o="_"+s;o in this||(this[o]=a[s])}var u=this._easing.name;return i[u]||(i[u]=function(e){!t[e]&&e===this._easing.name&&(t[e]=this._easing)}),this};N.prototype.start=function(e){return M(this),this.playing=!0,this._startTime=void 0!==e?e:t.Time(),this._startTime+=this._delay,this._startFired||(this._onStart&&this._onStart.call(this),q.call(this),this._startFired=!0),!s&&o(),this},N.prototype.stop=function(){return this.playing&&(_(this),this.playing=!1,this._onStop&&this._onStop.call(this),this.close()),this},N.prototype.close=function(){for(var t in y)for(var e in y[t])y[t][e].call(this,e);this._startFired=!1,u.call(this)},N.prototype.chain=function(t){return this._chain=[],this._chain=t.length?t:this._chain.concat(t),this},N.prototype.stopChainedTweens=function(){this._chain&&this._chain.length&&this._chain.map((function(t){return t.stop()}))},N.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return 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)},L.tween=N,f.repeat=0,f.repeatDelay=0,f.yoyo=!1,f.resetStart=!1;var j=function(e){function n(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];e.apply(this,t),this.valuesStart={},this.valuesEnd={};var r=t[1],i=t[2];if(A.call(this,i,"end"),this._resetStart?this.valuesStart=r:A.call(this,r,"start"),!this._resetStart)for(var a in g)for(var s in g[a])g[a][s].call(this,s);this.paused=!1,this._pauseTime=null;var o=t[3];return this._repeat=o.repeat||f.repeat,this._repeatDelay=o.repeatDelay||f.repeatDelay,this._repeatOption=this._repeat,this.valuesRepeat={},this._yoyo=o.yoyo||f.yoyo,this._reversed=!1,this}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.start=function(t){if(this._resetStart)for(var n in this.valuesStart=this._resetStart,E.call(this),g)for(var r in g[n])g[n][r].call(this,r);if(this.paused=!1,this._yoyo)for(var i in this.valuesEnd)this.valuesRepeat[i]=this.valuesStart[i];return e.prototype.start.call(this,t),this},n.prototype.stop=function(){return e.prototype.stop.call(this),!this.paused&&this.playing&&(this.paused=!1,this.stopChainedTweens()),this},n.prototype.close=function(){return e.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),q.call(this),this._startTime+=t.Time()-this._pauseTime,M(this),!s&&o()),this},n.prototype.pause=function(){return!this.paused&&this.playing&&(_(this),this.paused=!0,this._pauseTime=t.Time(),void 0!==this._onPause&&this._onPause.call(this)),this},n.prototype.reverse=function(){for(var t in this.valuesEnd){var e=this.valuesRepeat[t];this.valuesRepeat[t]=this.valuesEnd[t],this.valuesEnd[t]=e,this.valuesStart[t]=this.valuesRepeat[t]}},n.prototype.update=function(e){var n,r;if((e=void 0!==e?e:t.Time())1?1:n,r=this._easing(n),this.valuesEnd)t[i](this.element,this.valuesStart[i],this.valuesEnd[i],r);return this._onUpdate&&this._onUpdate.call(this),1!==n||(this._repeat>0?(isFinite(this._repeat)&&this._repeat--,this._startTime=isFinite(this._repeat)&&this._yoyo&&!this._reversed?e+this._repeatDelay:e,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.map((function(t){return t.start()})),!1))},n}(N);L.tween=j;var H=function(t,e,n,r){var i=this;this.tweens=[],!("offset"in f)&&(f.offset=0),(r=r||{}).delay=r.delay||f.delay;var a=[];return Array.from(t).map((function(t,s){a[s]=r||{},a[s].delay=s>0?r.delay+(r.offset||f.offset):r.delay,t instanceof Element?i.tweens.push(new L.tween(t,e,n,a[s])):console.error("KUTE.js - "+t+" not instanceof [Element]")})),this.length=this.tweens.length,this};H.prototype.start=function(e){return e=void 0===e?t.Time():e,this.tweens.map((function(t){return t.start(e)})),this},H.prototype.stop=function(){return this.tweens.map((function(t){return t.stop(time)})),this},H.prototype.pause=function(){return this.tweens.map((function(t){return t.pause(time)})),this},H.prototype.resume=function(){return this.tweens.map((function(t){return t.resume(time)})),this},H.prototype.chain=function(t){var e=this.tweens[this.length-1];if(t instanceof H)e.chain(t.tweens);else{if(!(t instanceof L.tween))throw new TypeError("KUTE.js - invalid chain value");e.chain(t)}return this},H.prototype.playing=function(){return this.tweens.some((function(t){return t.playing}))},H.prototype.removeTweens=function(){this.tweens=[]},H.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){try{t.component in p?console.error("KUTE.js - "+t.component+" already registered"):t.property in h?console.error("KUTE.js - "+t.property+" already registered"):this.setComponent(t)}catch(t){console.error(t)}};function U(t,e){for(var n,r=parseInt(t)||0,i=["px","%","deg","rad","em","rem","vh","vw"],a=0;a.99||i<.01?(10*Q(n,r,i)>>0)/10:Q(n,r,i)>>0)+"px"})}F.prototype.setComponent=function(t){var e=this,n=t.component,a={prepareProperty:d,prepareStart:v,onStart:i,onComplete:y,crossCheck:g},s=t.category,o=t.property,u=t.properties&&t.properties.length||t.subProperties&&t.subProperties.length;if(p[n]=t.properties||t.subProperties||t.property,"defaultValue"in t)h[o]=t.defaultValue,e.supports=o+" property";else if(t.defaultValues){for(var l in t.defaultValues)h[l]=t.defaultValues[l];e.supports=(u||o)+" "+(o||s)+" properties"}if(t.defaultOptions)for(var c in t.defaultOptions)f[c]=t.defaultOptions[c];if(t.functions)for(var x in a)if(x in t.functions)if("function"==typeof t.functions[x])!a[x][n]&&(a[x][n]={}),!a[x][n][s||o]&&(a[x][n][s||o]=t.functions[x]);else for(var w in t.functions[x])!a[x][n]&&(a[x][n]={}),!a[x][n][w]&&(a[x][n][w]=t.functions[x][w]);if(t.Interpolate){for(var M in t.Interpolate){var _=t.Interpolate[M];if("function"!=typeof _||r[M])for(var C in _)"function"!=typeof _[C]||r[M]||(r[M]=_[C]);else r[M]=_}m[n]=t.Interpolate}if(t.Util)for(var T in t.Util)!b[T]&&(b[T]=t.Util[T]);return e};var R=["top","left","width","height"],X={};R.map((function(t){return X[t]=D}));var B={component:"essentialBoxModel",category:"boxModel",properties:R,defaultValues:{top:0,left:0,width:0,height:0},Interpolate:{numbers:Q},functions:{prepareStart:function(t){return I(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:X},Util:{trueDimension:U}};function Z(t){if(/rgb|rgba/.test(t)){var e=t.replace(/\s|\)/,"").split("(")[1].split(","),n=e[3]?e[3]:null;return n?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(n)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}}if(/^#/.test(t)){var r=function(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,n,r){return e+e+n+n+r+r}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}(t);return{r:r.r,g:r.g,b:r.b}}if(/transparent|none|initial|inherit/.test(t))return{r:0,g:0,b:0,a:0};if(!/^#|^rgb/.test(t)){var i=document.getElementsByTagName("head")[0];i.style.color=t;var a=getComputedStyle(i,null).color;return a=/rgb/.test(a)?a.replace(/[^\d,]/g,"").split(","):[0,0,0],i.style.color="",{r:parseInt(a[0]),g:parseInt(a[1]),b:parseInt(a[2])}}}function z(t,e,n){var r,i={},a=",";for(r in e)i[r]="a"!==r?Q(t[r],e[r],n)>>0||0:t[r]&&e[r]?(100*Q(t[r],e[r],n)>>0)/100:null;return i.a?"rgba("+i.r+a+i.g+a+i.b+a+i.a+")":"rgb("+i.r+a+i.g+a+i.b+")"}function Y(e){this.valuesEnd[e]&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=z(n,r,i)})}w.BoxModelEssential=B;var K=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],$={};K.map((function(t){$[t]="#000"}));var W={};K.map((function(t){return W[t]=Y}));var G={component:"colorProperties",category:"colors",properties:K,defaultValues:$,Interpolate:{numbers:Q,colors:z},functions:{prepareStart:function(t,e){return I(this.element,t)||h[t]},prepareProperty:function(t,e){return Z(e)},onStart:W},Util:{trueColor:Z}};w.ColorProperties=G;var J={},tt="htmlAttributes",et=["fill","stroke","stop-color"];function nt(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()}var rt={prepareStart:function(t,e){var n={};for(var r in e){var i=nt(r).replace(/_+[a-z]+/,""),a=this.element.getAttribute(i);n[i]=et.includes(i)?a||"rgba(0,0,0,0)":a||(/opacity/i.test(r)?1:0)}return n},prepareProperty:function(t,e){var n={};for(var r in e){var a=nt(r),s=/(%|[a-z]+)$/,o=this.element.getAttribute(a.replace(/_+[a-z]+/,""));if(et.includes(a))i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,z(n,r,i))})},n[a]=Z(e[r])||h.htmlAttributes[r];else if(null!==o&&s.test(o)){var u=U(o).u||U(e[r]).u,l=/%/.test(u)?"_percent":"_"+u;i.htmlAttributes[a+l]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){var a=e.replace(l,"");t.setAttribute(a,(1e3*Q(n.v,r.v,i)>>0)/1e3+r.u)})},n[a+l]=U(e[r])}else s.test(e[r])&&null!==o&&(null===o||s.test(o))||(i.htmlAttributes[a]=function(e){this.valuesEnd[t]&&this.valuesEnd[t][e]&&!(e in J)&&(J[e]=function(t,e,n,r,i){t.setAttribute(e,(1e3*Q(n,r,i)>>0)/1e3)})},n[a]=parseFloat(e[r]))}return n},onStart:{attr:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(e,n,r,i){for(var a in r)t.attributes[a](e,a,n[a],r[a],i)})},attributes:function(e){!t[e]&&this.valuesEnd.attr&&(t[e]=J)}}},it={component:tt,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:z},functions:rt,Util:{replaceUppercase:nt,trueColor:Z,trueDimension:U}};w.HTMLAttributes=it;var at={prepareStart:function(t){return I(this.element,t)},prepareProperty:function(t,e){return parseFloat(e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,n,r,i){t.style[e]=(1e3*Q(n,r,i)>>0)/1e3})}},st={component:"opacityProperty",property:"opacity",defaultValue:1,Interpolate:{numbers:Q},functions:at};w.OpacityProperty=st;var ot=String("abcdefghijklmnopqrstuvwxyz").split(""),ut=String("abcdefghijklmnopqrstuvwxyz").toUpperCase().split(""),lt=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),ct=String("0123456789").split(""),pt=ot.concat(ut,ct),ht=pt.concat(lt),ft={alpha:ot,upper:ut,symbols:lt,numeric:ct,alphanumeric:pt,all:ht},dt={text:function(e){if(!t[e]&&this.valuesEnd[e]){var n=this._textChars,r=n in ft?ft[n]:n&&n.length?n:ft[f.textChars];t[e]=function(t,e,n,i){var a="",s="",o=e.substring(0),u=n.substring(0),l=r[Math.random()*r.length>>0];" "===e?(s=u.substring(Math.min(i*u.length,u.length)>>0,0),t.innerHTML=i<1?s+l:""===n?" ":n):" "===n?(a=o.substring(0,Math.min((1-i)*o.length,o.length)>>0),t.innerHTML=i<1?a+l:""===n?" ":n):(a=o.substring(o.length,Math.min(i*o.length,o.length)>>0),s=u.substring(0,Math.min(i*u.length,u.length)>>0),t.innerHTML=i<1?s+l+a:""===n?" ":n)}}},number:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){t.innerHTML=Q(e,n,r)>>0})}};function vt(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 i=t.innerHTML;(n=document.createElement("SPAN")).className=e,n.innerHTML=i,t.appendChild(n),t.innerHTML=n.outerHTML}else t.children.length&&t.children[0].className===e&&(n=t.children[0]);return n}function gt(t,e){var n=[];if(t.children.length){for(var r,i=[],a=t.innerHTML,s=0,o=t.children.length,u=void 0,l=void 0,c=void 0;s>0)/1e3+n+")"}function xt(t,e,n,r){for(var i=[],a=0;a<3;a++)i[a]=(t[a]||e[a]?(1e3*(t[a]+(e[a]-t[a])*r)>>0)/1e3:0)+n;return"translate3d("+i.join(",")+")"}function bt(t,e,n,r){var i="";return i+=t[0]||e[0]?"rotateX("+(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3+n+")":"",i+=t[1]||e[1]?"rotateY("+(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3+n+")":"",i+=t[2]||e[2]?"rotateZ("+(1e3*(t[2]+(e[2]-t[2])*r)>>0)/1e3+n+")":""}function wt(t,e,n){return"scale("+(1e3*(t+(e-t)*n)>>0)/1e3+")"}function Mt(t,e,n,r){var i=[];return i[0]=(t[0]===e[0]?e[0]:(1e3*(t[0]+(e[0]-t[0])*r)>>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","skew("+i.join(",")+")"}w.TextWriteProperties=yt;var _t={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,e){var n=S(this.element);return n[t]?n[t]:h[t]},prepareProperty:function(t,e){var n=["X","Y","Z"],r={},i=[],a=[],s=[],o=["translate3d","translate","rotate3d","skew"];for(var u in e){var l="object"==typeof e[u]&&e[u].length?e[u].map((function(t){return parseInt(t)})):parseInt(e[u]);if(o.includes(u))r["translate"===u||"rotate"===u?u+"3d":u]="skew"===u?l.length?[l[0]||0,l[1]||0]:[l||0,0]:"translate"===u?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(u)){for(var c=u.replace(/[XYZ]/,""),p="skew"===c?c:c+"3d",h="skew"===c?2:3,f="translate"===c?i:"rotate"===c?a:"skew"===c?s:{},d=0;d>0)/1e3)+n,i[1]=t[1]||e[1]?(t[1]===e[1]?e[1]:(1e3*(t[1]+(e[1]-t[1])*r)>>0)/1e3)+n:"0","translate("+i.join(",")+")"},rotate:function(t,e,n,r){return"rotate("+(1e3*(t+(e-t)*r)>>0)/1e3+n+")"},scale:wt,skew:Mt}};function Ct(t,e){return parseFloat(t)/100*e}function Tt(t){return 2*t.getAttribute("width")+2*t.getAttribute("height")}function St(t){var e=t.getAttribute("points").split(" "),n=0;if(e.length>1){var r=function(t){var e=t.split(",");if(2==e.length&&!isNaN(e[0])&&!isNaN(e[1]))return[parseFloat(e[0]),parseFloat(e[1])]},i=function(t,e){return null!=t&&null!=e?Math.sqrt(Math.pow(e[0]-t[0],2)+Math.pow(e[1]-t[1],2)):0};if(e.length>2)for(var a=0;a-1?St(t):"line"===t.tagName?It(t):void 0}function Ot(t,e){var n,r,i,a,s=/path|glyph/.test(t.tagName)?t.getTotalLength():kt(t);return e instanceof Object?e:("string"==typeof e?(e=e.split(/\,|\s/),n=/%/.test(e[0])?Ct(e[0].trim(),s):parseFloat(e[0]),r=/%/.test(e[1])?Ct(e[1].trim(),s):parseFloat(e[1])):void 0===e&&(a=parseFloat(I(t,"stroke-dashoffset")),i=I(t,"stroke-dasharray").split(/\,/),n=0-a,r=parseFloat(i[0])+n||s),{s:n,e:r,l:s})}w.TransformFunctions=_t;var Lt={prepareStart:function(){return Ot(this.element)},prepareProperty:function(t,e){return Ot(this.element,e)},onStart:function(e){e in this.valuesEnd&&!t[e]&&(t[e]=function(t,e,n,r){var i=(100*e.l>>0)/100,a=0-(100*Q(e.s,n.s,r)>>0)/100,s=(100*Q(e.e,n.e,r)>>0)/100+a;t.style.strokeDashoffset=a+"px",t.style.strokeDasharray=(100*(s<1?0:s)>>0)/100+"px, "+i+"px"})}},Pt={component:"svgDraw",property:"draw",defaultValue:"0% 0%",Interpolate:{numbers:Q},functions:Lt,Util:{getRectLength:Tt,getPolyLength:St,getLineLength:It,getCircleLength:At,getEllipseLength:Et,getTotalLength:kt,resetDraw:function(t){t.style.strokeDashoffset="",t.style.strokeDasharray=""},getDraw:Ot,percent:Ct}};function Vt(t,e,n,r){for(var i=[],a=0;a>0)/1e3)}return i}w.SVGDraw=Pt;var qt=3;function Nt(t){return t.map((function(t){return Array.isArray(t)?Nt(t):isNaN(+t)?t:+t}))}function jt(t,e){var n=isNaN(+e)?qt:+e;return n?t.map((function(t){return t.map((function(t,e){var r=+t,i=Math.pow(10,n);return r?r%1==0?r:Math.round(r*i)/i:t}))})):Nt(t)}function Ht(t,e,n){if(t[n].length>7){t[n].shift();for(var r=t[n];r.length;)e[n]="A",t.splice(n++,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Ft={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function Ut(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[achlmrqstvz]/g.test(e)}))}function Qt(t){var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;if("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"===n)t.segments.push([e].concat(r));else for(;r.length>=Ft[n]&&(t.segments.push([e].concat(r.splice(0,Ft[n]))),Ft[n]););}var Dt="Invalid path value";function Rt(t){var e=t.pathValue.charCodeAt(t.index);return 48===e?(t.param=0,void t.index++):49===e?(t.param=1,void t.index++):void(t.err=Dt+": invalid Arc flag "+e)}function Xt(t){return t>=48&&t<=57}function Bt(t){var e,n=t.index,r=n,i=t.max,a=!1,s=!1,o=!1,u=!1;if(r>=i)t.err=Dt+": missing param "+t.pathValue[r];else if(43!==(e=t.pathValue.charCodeAt(r))&&45!==e||(e=++r=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0);)t.index++;var e}function zt(t){return t>=48&&t<=57||43===t||45===t||46===t}function Yt(t){var e,n,r,i,a=t.max;if(t.segmentStart=t.index,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:case 114:return!0}return!1}(e=t.pathValue.charCodeAt(t.index)))if(r=Ft[t.pathValue[t.index].toLowerCase()],t.index++,Zt(t),t.data=[],r){for(n=!1;;){for(i=r;i>0;i--){if(97!=(32|e)||3!==i&&4!==i?Bt(t):Rt(t),t.err.length)return;t.data.push(t.param),Zt(t),n=!1,t.index=t.max)break;if(!zt(t.pathValue.charCodeAt(t.index)))break}}Qt(t)}else Qt(t);else t.err=Dt+": "+t.pathValue[t.index]+" not a path command"}function Kt(t){return this.segments=[],this.pathValue=t,this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err="",this}function $t(t,e){if(Ut(n=t)&&n.every((function(t){return t[0]===t[0].toUpperCase()})))return Nt(t);var n;t=function(t,e){if(Ut(t))return Nt(t);var n=new Kt(t);for(Zt(n);n.index-1?{x1:2*t-n,y1:2*e-r}:{x1:t,y1:e}}(e.x1,e.y1,e.x2,e.y2,n),e.x1=i.x1,e.y1=i.y1,["C",i.x1,i.y1].concat(t.slice(1));case"T":return r=function(t,e,n,r,i){return"QT".indexOf(i)>-1?{qx:2*t-n,qy:2*e-r}:{qx:t,qy:e}}(e.x1,e.y1,e.qx,e.qy,n),e.qx=r.qx,e.qy=r.qy,["Q",e.qx,e.qy].concat(t.slice(1));case"Q":e.qx=t[1],e.qy=t[2]}return t}function Gt(t,e){if(function(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ft[e]===t.length-1&&/[ACLMQZ]/.test(t[0])}))}(t))return Nt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o="",u=(t=$t(t)).length,l=0;l1&&(n*=b=Math.sqrt(b),r*=b);var w=n*n,M=r*r,_=(a==s?-1:1)*Math.sqrt(Math.abs((w*M-w*x*x-M*m*m)/(w*x*x+M*m*m)));f=_*n*x/r+(t+o)/2,d=_*-r*m/n+(e+u)/2,p=Math.asin(((e-d)/r).toFixed(9)),h=Math.asin(((u-d)/r).toFixed(9)),p=th&&(p-=2*Math.PI),!s&&h>p&&(h-=2*Math.PI)}var C=h-p;if(Math.abs(C)>v){var T=h,S=o,I=u;h=p+v*(s&&h>p?1:-1),o=f+n*Math.cos(h),u=d+r*Math.sin(h),y=te(o,u,n,r,i,0,s,S,I,[h,T,f,d])}C=h-p;var A=Math.cos(p),E=Math.sin(p),k=Math.cos(h),O=Math.sin(h),L=Math.tan(C/4),P=4/3*n*L,V=4/3*r*L,q=[t,e],N=[t+P*E,e-V*A],j=[o+P*O,u-V*k],H=[o,u];return N[0]=2*q[0]-N[0],N[1]=2*q[1]-N[1],l?[N,j,H].concat(y):(y=[N,j,H].concat(y).join().split(",")).map((function(t,e){return e%2?Jt(y[e-1],t,g).y:Jt(t,y[e+1],g).x}))}function ee(t,e,n,r,i,a){var s=1/3,o=2/3;return[s*t+o*n,s*e+o*r,s*i+o*n,s*a+o*r,i,a]}function ne(t,e,n,r,i,a,s,o,u){var l=1-u;return{x:Math.pow(l,3)*t+3*Math.pow(l,2)*u*n+3*l*u*u*i+Math.pow(u,3)*s,y:Math.pow(l,3)*e+3*Math.pow(l,2)*u*r+3*l*u*u*a+Math.pow(u,3)*o}}function re(t,e,n){var r=t[0],i=t[1];return[r+(e[0]-r)*n,i+(e[1]-i)*n]}function ie(t,e,n,r){var i=.5,a=[t,e],s=[n,r],o=re(a,s,i),u=re(s,o,i),l=re(o,u,i),c=re(u,l,i),p=re(l,c,i),h=ne.apply(0,a.concat(o,l,p,i)),f=ne.apply(0,p.concat(c,u,s,0));return[h.x,h.y,f.x,f.y,n,r]}function ae(t,e){switch("TQ".indexOf(t[0])<0&&(e.qx=e.qy=null),t[0]){case"M":return e.x=t[1],e.y=t[2],t;case"A":return["C"].concat(te.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"Q":return e.qx=t[1],e.qy=t[2],["C"].concat(ee.apply(0,[e.x1,e.y1].concat(t.slice(1))));case"L":return["C"].concat(ie(e.x1,e.y1,t[1],t[2]));case"Z":return["C"].concat(ie(e.x1,e.y1,e.x,e.y))}return t}function se(t,e){if(function(t){return Ut(t)&&t.slice(1).every((function(t){return"C"===t[0]}))}(t))return Nt(t);for(var n,r,i={x1:0,y1:0,x2:0,y2:0,x:0,y:0,qx:null,qy:null},a=[],s="",o=(t=Gt(t)).length,u=0;u1?1:u<0?0:u)/2,c=0,p=0,h=0,f=0,d=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472];return[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816].map((function(u,v){p=ue(t,n,i,s,c=l*u+l),h=ue(e,r,a,o,c),f+=d[v]*Math.sqrt(p*p+h*h)})),l*f}function ce(t){var e=0;return se(t).map((function(t,n,r){e+="M"!==t[0]?le.apply(0,r[n-1].slice(-2).concat(t.slice(1))):0})),e}function pe(t,e){var n,r,i=0;return se(t).map((function(t,a,s){return r=a?s[a-1].slice(-2).concat(t.slice(1)):t.slice(1),n=a?le.apply(0,r):0,i+=n,0===a?{x:r[0],y:r[1]}:i>e&&e>i-n?ne.apply(0,r.concat(1-(i-e)/n)):null})).filter((function(t){return t})).slice(-1)[0]}function he(t,e,n,r,i,a,s,o){return 3*((o-e)*(n+i)-(s-t)*(r+a)+r*(t-i)-n*(e-a)+o*(i+t/3)-s*(a+e/3))/20}function fe(t){return function(t){var e=0,n=0,r=0,i=0,a=0;return se(t).map((function(t){var s;switch(t[0]){case"M":case"Z":return r="M"===t[0]?t[1]:r,i="M"===t[0]?t[2]:i,e=r,n=i,0;default:return a=he.apply(0,[e,n].concat(t.slice(1))),s=t.slice(-2),e=s[0],n=s[1],a}})).reduce((function(t,e){return t+e}),0)}(se(t))>=0}function de(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))}function ve(t){return t.reduce((function(e,n,r){return r?e+de(t[r-1],n):0}),0)}function ge(t,e){var n=Gt(t,0);return function(t){var e=[],n=[],r="",i=t.length,a=0;if(!t.length||"M"!==t[0][0])return!1;for(var s=0;s-1))return!1;e.push([n[1],n[2]])}return a=ve(e),!!i&&{ring:e,pathLength:a}}(n)||ye(n,e)}function ye(t,e){var n,r,i=se((r=oe(t),oe($t(r,0)).replace(/(m|M)/g,"|$1").split("|").map((function(t){return t.trim()})).filter((function(t){return t})))[0],4),a=ce(i),s=[],o=3;e&&!isNaN(e)&&+e>0&&(o=Math.max(o,Math.ceil(a/e)));for(var u=0;ue;)r=re(n,r,.5),t.splice(i+1,0,r)}function we(t,e){var n,r,i;if("string"==typeof t){var a=ge(t,e);t=a.ring,r=a.skipBisect,i=a.pathLength}else if(!Array.isArray(t))throw Dt;if((n=t.slice(0)).pathLength=i,!Me(n))throw Dt;return n.length>1&&de(n[0],n[n.length-1])<1e-9&&n.pop(),!r&&e&&!isNaN(e)&&+e>0&&be(n,e),n}function Me(t){return Array.isArray(t)&&t.every((function(t){return Array.isArray(t)&&2===t.length&&!isNaN(t[0])&&!isNaN(t[1])}))}function _e(t,e,n){var r=we(t,n=n||f.morphPrecision),i=we(e,n),a=r.length-i.length;return xe(r,a<0?-1*a:0),xe(i,a>0?a:0),me(r,i),[jt(r),jt(i)]}var Ce={prepareStart:function(t){return this.element.getAttribute("d")},prepareProperty:function(t,e){var n={},r=e instanceof SVGElement?e:/^\.|^\#/.test(e)?V(e):null,i=new RegExp("\\n","ig");return"object"==typeof e&&e.pathArray?e:(r&&/path|glyph/.test(r.tagName)?n.original=r.getAttribute("d").replace(i,""):r||"string"!=typeof e||(n.original=e.replace(i,"")),n)},onStart:function(e){!t[e]&&this.valuesEnd[e]&&(t[e]=function(t,e,n,r){var i=e.pathArray,a=n.pathArray,s=a.length;t.setAttribute("d",1===r?n.original:"M"+Vt(i,a,s,r).join("L")+"Z")})},crossCheck:function(t){if(this.valuesEnd[t]){var e=this.valuesStart[t].pathArray,n=this.valuesEnd[t].pathArray;if(!e||!n||e&&n&&e.length!==n.length){var r=_e(this.valuesStart[t].original,this.valuesEnd[t].original,this._morphPrecision?parseInt(this._morphPrecision):f.morphPrecision);this.valuesStart[t].pathArray=r[0],this.valuesEnd[t].pathArray=r[1]}}}},Te={component:"svgMorph",property:"path",defaultValue:[],Interpolate:Vt,defaultOptions:{morphPrecision:10,morphIndex:0},functions:Ce,Util:{addPoints:xe,bisect:be,normalizeRing:we,validRing:Me,getInterpolationPoints:_e,pathStringToRing:ge,distanceSquareRoot:de,midPoint:re,approximateRing:ye,rotateRing:me,pathToString:oe,pathToCurve:se,getPathLength:ce,getPointAtLength:pe,getDrawDirection:fe,roundPath:jt}};for(var Se in w.SVGMorph=Te,w){var Ie=w[Se];w[Se]=new F(Ie)}return{Animation:F,Components:w,Tween:j,fromTo:function(t,e,n,r){return r=r||{},new L.tween(V(t),e,n,r)},to:function(t,e,n){return(n=n||{}).resetStart=e,new L.tween(V(t),e,e,n)},TweenCollection:H,allFromTo:function(t,e,n,r){return r=r||{},new H(V(t,!0),e,n,r)},allTo:function(t,e,n){return(n=n||{}).resetStart=e,new H(V(t,!0),e,e,n)},Objects:x,Util:b,Easing:P,CubicBezier:O,Render:l,Interpolate:r,Process:k,Internals:T,Selector:V,Version:"2.0.16"}})); diff --git a/package.json b/package.json index 5aa459b..60a639a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kute.js", - "version": "2.0.15", + "version": "2.0.16", "description": "JavaScript animation engine of the future is called KUTE.js.", "main": "dist/kute.min.js", "module": "dist/kute.esm.js", @@ -57,16 +57,15 @@ "cubic-bezier-easing": "^1.0.2", "minifill": "^0.0.14", "shorter-js": "^0.1.4", - "d3-polygon": "^2.0.0", - "svg-path-commander": "^0.0.6" + "svg-path-commander": "0.0.9" }, "devDependencies": { "@rollup/plugin-buble": "^0.21.3", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^9.0.0", "npm-run-all": "^4.1.5", - "rollup": "^2.26.9", + "rollup": "^2.28.1", "rollup-plugin-cleanup": "^3.1.1", - "rollup-plugin-terser": "^7.0.1" + "rollup-plugin-terser": "^7.0.2" } } diff --git a/src/components/htmlAttributes.js b/src/components/htmlAttributes.js index d8d660c..d7800c2 100644 --- a/src/components/htmlAttributes.js +++ b/src/components/htmlAttributes.js @@ -18,28 +18,28 @@ function replaceUppercase (a) { return a.replace(/[A-Z]/g, "-$&").toLowerCase(); // Component Functions export function getAttr(tweenProp,value){ - const attrStartValues = {}; - for (const attr in value){ - const attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''); // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px' - const currentValue = this.element.getAttribute(attribute); + let attrStartValues = {}; + for (let attr in value){ + let attribute = replaceUppercase(attr).replace(/_+[a-z]+/,''), // get the value for 'fill-opacity' not fillOpacity, also 'width' not the internal 'width_px' + currentValue = this.element.getAttribute(attribute); attrStartValues[attribute] = svgColors.includes(attribute) ? (currentValue || 'rgba(0,0,0,0)') : (currentValue || (/opacity/i.test(attr) ? 1 : 0)); } return attrStartValues; } export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object) - const attributesObject = {}; - for ( const p in attrObj ) { - const prop = replaceUppercase(p); - const regex = /(%|[a-z]+)$/; - const currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); + let attributesObject = {}; + for ( let p in attrObj ) { + let prop = replaceUppercase(p), + regex = /(%|[a-z]+)$/, + currentValue = this.element.getAttribute(prop.replace(/_+[a-z]+/,'')); if ( !svgColors.includes(prop)) { if ( currentValue !== null && regex.test(currentValue) ) { // attributes set with unit suffixes - const unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u; - const suffix = /%/.test(unit) ? '_percent' : `_${unit}`; + let unit = trueDimension(currentValue).u || trueDimension(attrObj[p]).u, + suffix = /%/.test(unit) ? '_percent' : `_${unit}`; onStart[ComponentName][prop+suffix] = function(tp) { // most "unknown" attributes cannot register into onStart, so we manually add them if ( this.valuesEnd[tweenProp] && this.valuesEnd[tweenProp][tp] && !(tp in attributes) ) { attributes[tp] = (elem, p, a, b, v) => { - const _p = p.replace(suffix,''); + let _p = p.replace(suffix,''); elem.setAttribute(_p, ( (numbers(a.v,b.v,v)*1000>>0)/1000) + b.u ); } } @@ -62,7 +62,7 @@ export function prepareAttr(tweenProp,attrObj){ // attr (string),attrObj (object elem.setAttribute(oneAttr, colors(a,b,v)); } } - } + } attributesObject[prop] = trueColor(attrObj[p]) || defaultValues.htmlAttributes[p]; } } diff --git a/src/components/svgCubicMorph.js b/src/components/svgCubicMorph.js index 03049bd..bc6b2d4 100644 --- a/src/components/svgCubicMorph.js +++ b/src/components/svgCubicMorph.js @@ -9,24 +9,26 @@ import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js' import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js' import pathToString from 'svg-path-commander/src/convert/pathToString.js' import reverseCurve from 'svg-path-commander/src/process/reverseCurve.js' -import createPath from 'svg-path-commander/src/util/createPath.js' import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js' import clonePath from 'svg-path-commander/src/process/clonePath.js' import splitCubic from 'svg-path-commander/src/process/splitCubic.js' import splitPath from 'svg-path-commander/src/process/splitPath.js' +import getSegCubicLength from 'svg-path-commander/src/util/getSegCubicLength.js' +import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js' + // const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } // Component Util function getCurveArray(pathString){ - return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map((x,i,pathArray)=>{ - let curveToPath = i ? [['M'].concat(pathArray[i-1].slice(-2))].concat([x]) : [], - curveLength = i ? createPath(pathToString(clonePath(curveToPath))).getTotalLength() : 0, - subsegs = i ? (curveLength ? splitCubic( pathArray[i-1].slice(-2).concat(x.slice(1)) ) : [x,x]) : [x]; + return pathToCurve(splitPath(pathToString(pathToAbsolute(pathString)))[0]).map((segment,i,pathArray)=>{ + let segmentData = i && pathArray[i-1].slice(-2).concat(segment.slice(1)), + curveLength = i ? getSegCubicLength.apply(0, segmentData ) : 0, + subsegs = i ? (curveLength ? splitCubic( segmentData ) : [segment,segment]) : [segment]; // must be [segment,segment] return { - seg: x, - subsegs: subsegs, - length: curveLength + s: segment, + ss: subsegs, + l: curveLength } }) } @@ -36,19 +38,19 @@ function equalizeSegments(path1,path2,TL){ c2 = getCurveArray(path2), L1 = c1.length, L2 = c2.length, - l1 = c1.filter(x=>x.length).length, - l2 = c2.filter(x=>x.length).length, - m1 = c1.filter(x=>x.length).reduce((a,{length})=>a+length,0) / l1 || 0, - m2 = c2.filter(x=>x.length).reduce((a,{length})=>a+length,0) / l2 || 0, + l1 = c1.filter(x=>x.l).length, + l2 = c2.filter(x=>x.l).length, + m1 = c1.filter(x=>x.l).reduce((a,{l})=>a+l,0) / l1 || 0, + m2 = c2.filter(x=>x.l).reduce((a,{l})=>a+l,0) / l2 || 0, tl = TL || Math.max(L1,L2), mm = [m1,m2], dif = [tl-L1,tl-L2], - result = [c1,c2].map((x,i) => x.length === tl ? x.map(y=>y.seg) + canSplit = 0, + result = [c1,c2].map((x,i) => x.l === tl ? x.map(y=>y.s) : x.map((y,j) => { - let canSplit = j && dif[i] && y.length >= mm[i], - segResult = canSplit ? y.subsegs : [y.seg] + canSplit = j && dif[i] && y.l >= mm[i] dif[i] -= canSplit ? 1 : 0 - return segResult + return canSplit ? y.ss : [y.s] }).flat()) return result[0].length === result[1].length ? result : equalizeSegments(result[0],result[1],tl) @@ -73,30 +75,20 @@ function getRotations(a) { function getRotatedCurve(a,b) { let segCount = a.length - 1, - linePaths = [], lineLengths = [], + computedIndex = 0, + sumLensSqrd = 0, rotations = getRotations(a); rotations.map((r,i)=>{ - let sumLensSqrd = 0, - linePath = createPath('M0,0L0,0'), - linePt1, ll1, - linePt2, ll2, - linePathStr - - for (let j = 0; j < segCount; j++) { - linePt1 = a[(i + j) % segCount]; ll1 = linePt1.length - linePt2 = b[ j % segCount]; ll2 = linePt2.length - linePathStr = `M${linePt1[ll1-2]},${linePt1[ll1-1]}L${linePt2[ll2-2]},${linePt2[ll2-1]}` - linePath.setAttribute('d',linePathStr); - sumLensSqrd += Math.pow(linePath.getTotalLength(),2); - linePaths[j] = linePath; - } + a.slice(1).map((s,j) => { + sumLensSqrd += distanceSquareRoot(a[(i+j) % segCount].slice(-2),b[j % segCount].slice(-2)) + }) lineLengths[i] = sumLensSqrd sumLensSqrd = 0 }) - let computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)) + computedIndex = lineLengths.indexOf(Math.min.apply(null,lineLengths)) return rotations[computedIndex] } @@ -131,6 +123,7 @@ function crossCheckCubicMorph(tweenProp){ path2 = this.valuesEnd[tweenProp].original, curves = equalizeSegments(path1,path2), curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) ? reverseCurve(curves[0]) : clonePath(curves[0]) + this.valuesStart[tweenProp].curve = curve0; this.valuesEnd[tweenProp].curve = getRotatedCurve(curves[1],curve0) } @@ -156,7 +149,7 @@ const svgCubicMorph = { Util: { pathToCurve, pathToAbsolute, pathToString, parsePathString, getRotatedCurve, getRotations, equalizeSegments, - reverseCurve, createPath, clonePath, getDrawDirection, + reverseCurve, clonePath, getDrawDirection, splitCubic, getCurveArray } } diff --git a/src/components/svgDraw.js b/src/components/svgDraw.js index f5760a9..34e7ae0 100644 --- a/src/components/svgDraw.js +++ b/src/components/svgDraw.js @@ -66,15 +66,15 @@ function getEllipseLength(el) { // returns the length of an ellipse } function getTotalLength(el) { // returns the result of any of the below functions - if (/rect/.test(el.tagName)) { + if ('rect'===el.tagName) { return getRectLength(el); - } else if (/circle/.test(el.tagName)) { + } else if ('circle'===el.tagName) { return getCircleLength(el); - } else if (/ellipse/.test(el.tagName)) { + } else if ('ellipse'===el.tagName) { return getEllipseLength(el); - } else if (/polygon|polyline/.test(el.tagName)) { + } else if (['polygon,polyline'].indexOf(el.tagName)>-1) { return getPolyLength(el); - } else if (/line/.test(el.tagName)) { + } else if ('line'===el.tagName) { return getLineLength(el); } } diff --git a/src/components/svgMorph.js b/src/components/svgMorph.js index 0f692e0..97c491a 100644 --- a/src/components/svgMorph.js +++ b/src/components/svgMorph.js @@ -4,14 +4,18 @@ import Components from '../objects/components.js' import coords from '../interpolation/coords.js' import {onStartSVGMorph} from './svgMorphBase.js' -import pathToAbsolute from 'svg-path-commander/src/convert/pathToAbsolute.js' +import pathToCurve from 'svg-path-commander/src/convert/pathToCurve.js' import pathToString from 'svg-path-commander/src/convert/pathToString.js' +import normalizePath from 'svg-path-commander/src/process/normalizePath.js' import splitPath from 'svg-path-commander/src/process/splitPath.js' +import roundPath from 'svg-path-commander/src/process/roundPath.js' import invalidPathValue from 'svg-path-commander/src/util/invalidPathValue.js' -import createPath from 'svg-path-commander/src/util/createPath.js' - -import polygonArea from 'd3-polygon/src/area.js' -import polygonLength from 'd3-polygon/src/length.js' +import getPathLength from 'svg-path-commander/src/util/getPathLength.js' +import getPointAtLength from 'svg-path-commander/src/util/getPointAtLength.js' +import getDrawDirection from 'svg-path-commander/src/util/getDrawDirection.js' +import epsilon from 'svg-path-commander/src/math/epsilon.js' +import midPoint from 'svg-path-commander/src/math/midPoint.js' +import distanceSquareRoot from 'svg-path-commander/src/math/distanceSquareRoot.js' // const SVGMorph = { property : 'path', defaultValue: [], interpolators: {numbers,coords} }, functions = { prepareStart, prepareProperty, onStart, crossCheck } @@ -22,73 +26,65 @@ import polygonLength from 'd3-polygon/src/length.js' // original script flubber // https://github.com/veltman/flubber -function isFiniteNumber(number) { - return typeof number === "number" && isFinite(number); -} -function distanceSquareRoot(a, b) { - return Math.sqrt( - (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) - ); -} -function pointAlong(a, b, pct) { - return [a[0] + (b[0] - a[0]) * pct, a[1] + (b[1] - a[1]) * pct]; -} -function samePoint(a, b) { - return distanceSquareRoot(a, b) < 1e-9; +function polygonLength(ring){ + return ring.reduce((length, point, i) => + i ? length + distanceSquareRoot(ring[i-1],point) : 0, 0 ) } + function pathStringToRing(str, maxSegmentLength) { - let parsed = pathToAbsolute(str); + let parsed = normalizePath(str,0) return exactRing(parsed) || approximateRing(parsed, maxSegmentLength); } -function exactRing(segments) { - let ring = []; +function exactRing(pathArray) { + let ring = [], + segment = [], pathCommand = '', + pathlen = pathArray.length, + pathLength = 0; - if (!segments.length || segments[0][0] !== "M") { + if (!pathArray.length || pathArray[0][0] !== "M") { return false; } - for (let i = 0; i < segments.length; i++) { - let [command, x, y] = segments[i]; - if ((command === "M" && i) || command === "Z") { + for (let i = 0; i < pathlen; i++) { + segment = pathArray[i] + pathCommand = segment[0] + + if (pathCommand === "M" && i || pathCommand === "Z") { break; // !! - } else if (command === "M" || command === "L") { - ring.push([x, y]); - } else if (command === "H") { - ring.push([x, ring[ring.length - 1][1]]); - } else if (command === "V") { - ring.push([ring[ring.length - 1][0], x]); + } else if ('ML'.indexOf( pathCommand) > -1) { + ring.push([segment[1], segment[2]]); } else { return false; } } - return ring.length ? { ring } : false; + pathLength = polygonLength(ring) + + return pathlen ? { ring, pathLength } : false; } + function approximateRing(parsed, maxSegmentLength) { - let ringPath = splitPath(pathToString(parsed))[0], - ring = [], len, testPath, numPoints = 3; + let ringPath = splitPath(pathToString(parsed))[0], + curvePath = pathToCurve(ringPath,4), + pathLength = getPathLength(curvePath), + ring = [], numPoints = 3, point; - if (!ringPath) { - throw (invalidPathValue); + if ( maxSegmentLength && !isNaN(maxSegmentLength) && +maxSegmentLength > 0 ) { + numPoints = Math.max(numPoints, Math.ceil(pathLength / maxSegmentLength)); } - testPath = createPath(ringPath); - len = testPath.getTotalLength(); - - if ( - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { - numPoints = Math.max(numPoints, Math.ceil(len / maxSegmentLength)); + for (let i = 0; i < numPoints; i++) { + point = getPointAtLength(curvePath,pathLength * i / numPoints) + ring.push([point.x, point.y]); } - for (let i = 0; i < numPoints; i++) { - let p = testPath.getPointAtLength((len * i) / numPoints); - ring.push([p.x, p.y]); + // Make all rings clockwise + if (!getDrawDirection(curvePath)) { + ring.reverse(); } return { + pathLength, ring, skipBisect: true }; @@ -116,16 +112,20 @@ function rotateRing(ring, vs) { } } function addPoints(ring, numPoints) { - const desiredLength = ring.length + numPoints, - step = polygonLength(ring) / numPoints; + let desiredLength = ring.length + numPoints, + // step = ring.pathLength / numPoints; + step = polygonLength(ring) / numPoints; - let i = 0, cursor = 0, insertAt = step / 2; + let i = 0, cursor = 0, insertAt = step / 2, a, b, segment; while (ring.length < desiredLength) { - let a = ring[i], b = ring[(i + 1) % ring.length], segment = distanceSquareRoot(a, b); + a = ring[i] + b = ring[(i + 1) % ring.length] + // console.log(step,a,b) + segment = distanceSquareRoot(a, b) if (insertAt <= cursor + segment) { - ring.splice( i + 1, 0, segment ? pointAlong(a, b, (insertAt - cursor) / segment) : a.slice(0) ); + ring.splice( i + 1, 0, segment ? midPoint(a, b, (insertAt - cursor) / segment) : a.slice(0) ); insertAt += step; continue; } @@ -135,67 +135,52 @@ function addPoints(ring, numPoints) { } } function bisect(ring, maxSegmentLength = Infinity) { + let a = [], b = [] for (let i = 0; i < ring.length; i++) { - let a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; + a = ring[i], b = i === ring.length - 1 ? ring[0] : ring[i + 1]; // Could splice the whole set for a segment instead, but a bit messy while (distanceSquareRoot(a, b) > maxSegmentLength) { - b = pointAlong(a, b, 0.5); + b = midPoint(a, b, 0.5); ring.splice(i + 1, 0, b); } } } function normalizeRing(ring, maxSegmentLength) { - let points, area, skipBisect; + let points, skipBisect, pathLength; if (typeof ring === "string") { - let converted = pathStringToRing(ring, maxSegmentLength); - ring = converted.ring; - skipBisect = converted.skipBisect; + let converted = pathStringToRing(ring, maxSegmentLength) + ring = converted.ring + skipBisect = converted.skipBisect + pathLength = converted.pathLength } else if (!Array.isArray(ring)) { - throw (invalidPathValue); + throw (invalidPathValue) } - - points = ring.slice(0); + + points = ring.slice(0) + points.pathLength = pathLength if (!validRing(points)) { - throw (invalidPathValue); + throw (invalidPathValue) } // TODO skip this test to avoid scale issues? - // Chosen epsilon (1e-6) is problematic for small coordinate range - if (points.length > 1 && samePoint(points[0], points[points.length - 1])) { - points.pop(); + // 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() } - area = polygonArea(points); - - // Make all rings clockwise - if (area > 0) { - points.reverse(); + if ( !skipBisect && maxSegmentLength && !isNaN(maxSegmentLength) && (+maxSegmentLength) > 0 ) { + bisect(points, maxSegmentLength) } - if ( - !skipBisect && - maxSegmentLength && - isFiniteNumber(maxSegmentLength) && - maxSegmentLength > 0 - ) { - bisect(points, maxSegmentLength); - } - - return points; + return points } function validRing(ring) { - return ring.every(function(point) { - return ( - Array.isArray(point) && - point.length >= 2 && - isFiniteNumber(point[0]) && - isFiniteNumber(point[1]) - ); - }); + return Array.isArray(ring) && ring.every( point => + Array.isArray(point) && point.length === 2 && !isNaN(point[0]) && !isNaN(point[1])) } function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { @@ -203,12 +188,13 @@ function getInterpolationPoints(pathArray1, pathArray2, morphPrecision) { let fromRing = normalizeRing(pathArray1, morphPrecision), toRing = normalizeRing(pathArray2, morphPrecision), diff = fromRing.length - toRing.length; - + addPoints(fromRing, diff < 0 ? diff * -1 : 0); addPoints(toRing, diff > 0 ? diff : 0); - rotateRing(fromRing, toRing); - return [fromRing,toRing] + rotateRing(fromRing,toRing); + + return [roundPath(fromRing),roundPath(toRing)] } @@ -242,7 +228,6 @@ function crossCheckSVGMorph(prop){ // process morphPrecision morphPrecision = this._morphPrecision ? parseInt(this._morphPrecision) : defaultOptions.morphPrecision, paths = getInterpolationPoints(p1,p2,morphPrecision); - this.valuesStart[prop].pathArray = paths[0]; this.valuesEnd[prop].pathArray = paths[1]; } @@ -270,10 +255,10 @@ const svgMorph = { Util: { addPoints,bisect,normalizeRing,validRing, // component getInterpolationPoints,pathStringToRing, - isFiniteNumber,distanceSquareRoot,pointAlong,samePoint, - exactRing,approximateRing,createPath,rotateRing, - pathToAbsolute,pathToString, // svg-path-commander - polygonLength,polygonArea // d3-polygon + distanceSquareRoot,midPoint, + approximateRing,rotateRing, + pathToString,pathToCurve,// svg-path-commander + getPathLength,getPointAtLength,getDrawDirection,roundPath } } diff --git a/src/index-base.js b/src/index-base.js index bdc2d89..c26bdc1 100644 --- a/src/index-base.js +++ b/src/index-base.js @@ -10,7 +10,7 @@ import Selector from './util/selector.js' import Animation from './animation/animationBase.js' // TweenConstructor -import TweenBase from './tween/tweenBase.js' +import Tween from './tween/tweenBase.js' // Interface only fromTo import fromTo from './interface/fromTo.js' @@ -36,7 +36,7 @@ export default { // Move }, - TweenBase, + Tween, fromTo, Objects, diff --git a/src/index-extra.js b/src/index-extra.js index 9f3a0f0..e38e27b 100644 --- a/src/index-extra.js +++ b/src/index-extra.js @@ -11,7 +11,7 @@ import Easing from './easing/easing-bezier.js' import Selector from './util/selector.js' // TweenConstructor -import TweenExtra from './tween/tweenExtra.js' +import Tween from './tween/tweenExtra.js' import TweenCollection from './tween/tweenCollection.js' import ProgressBar from './util/progressBar.js' // interface @@ -28,8 +28,8 @@ import BorderRadius from './components/borderRadius.js' import BoxModel from './components/boxModel.js' import ClipProperty from './components/clipProperty.js' import ColorProperties from './components/colorProperties.js' -import HTMLAttributes from './components/htmlAttributes.js' import FilterEffects from './components/filterEffects' +import HTMLAttributes from './components/htmlAttributes.js' import OpacityProperty from './components/opacityProperty.js' import SVGDraw from './components/svgDraw.js' import SVGCubicMorph from './components/svgCubicMorph.js' @@ -38,7 +38,7 @@ import ScrollProperty from './components/scrollProperty.js' import ShadowProperties from './components/shadowProperties.js' import TextProperties from './components/textProperties.js' import TextWriteProperties from './components/textWrite.js' -import matrixTransform from './components/transformMatrix.js' +import MatrixTransform from './components/transformMatrix.js' for (let component in Components) { let compOps = Components[component] @@ -50,7 +50,7 @@ export default { Components, // Tween Interface - TweenExtra, + Tween, fromTo, to, // Tween Collection diff --git a/src/index.js b/src/index.js index 40865a3..7f60515 100644 --- a/src/index.js +++ b/src/index.js @@ -23,15 +23,24 @@ import allFromTo from './interface/allFromTo.js' import Animation from './animation/animation.js' // components -import EssentialBoxModel from './components/boxModelEssential.js' -import ColorsProperties from './components/colorProperties.js' -import HTMLAttributes from './components/htmlAttributes.js' -import OpacityProperty from './components/opacityProperty.js' -import TextWrite from './components/textWrite.js' -import TransformFunctions from './components/transformFunctions.js' -// import TransformFunctions from './components/transformLegacy.js' -import SVGDraw from './components/svgDraw.js' -import SVGMorph from './components/svgMorph.js' +// import EssentialBoxModel from './components/boxModelEssential.js' +// import ColorsProperties from './components/colorProperties.js' +// import HTMLAttributes from './components/htmlAttributes.js' +// import OpacityProperty from './components/opacityProperty.js' +// import TextWrite from './components/textWrite.js' +// import TransformFunctions from './components/transformFunctions.js' +// // import TransformFunctions from './components/transformLegacy.js' +// import SVGDraw from './components/svgDraw.js' +// import SVGMorph from './components/svgMorph.js' +import './components/boxModelEssential.js' +import './components/colorProperties.js' +import './components/htmlAttributes.js' +import './components/opacityProperty.js' +import './components/textWrite.js' +import './components/transformFunctions.js' +// import './components/transformLegacy.js' +import './components/svgDraw.js' +import './components/svgMorph.js' // init components for (let component in Components) { diff --git a/src/process/prepareObject.js b/src/process/prepareObject.js index 8c055b9..b1615a0 100644 --- a/src/process/prepareObject.js +++ b/src/process/prepareObject.js @@ -4,15 +4,15 @@ import defaultValues from '../objects/defaultValues.js' // prepareObject - returns all processed valuesStart / valuesEnd export default function (obj, fn) { // this, props object, type: start/end - const propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd + let propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd - for ( const component in prepareProperty ) { + for ( let component in prepareProperty ) { let prepareComponent = prepareProperty[component], supportComponent = supportedProperties[component] - for ( const tweenCategory in prepareComponent ) { + for ( let tweenCategory in prepareComponent ) { let transformObject = {} - for (const tweenProp in obj) { + for (let tweenProp in obj) { if ( defaultValues[tweenProp] && prepareComponent[tweenProp] ) { // scroll, opacity, other components propertiesObject[tweenProp] = prepareComponent[tweenProp].call(this,tweenProp,obj[tweenProp]);