Major change:

* fixing SVG transforms for good https://github.com/thednp/kute.js/issues/33
* major changes to the tween objects https://github.com/thednp/kute.js/issues/39
* back to Infinity repeat https://github.com/thednp/kute.js/issues/43
* all round performance improvements
This commit is contained in:
thednp 2016-12-11 03:48:37 +02:00
parent 308ee60bf5
commit fc75dd130f
27 changed files with 358 additions and 317 deletions

View file

@ -1,5 +1,7 @@
# KUTE.js
A minimal native Javascript animation engine with jQuery plugin and 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 flexibility, performance and size (core engine is 15.8k min and 5.6k gzipped).
A fully fledged native Javascript animation engine 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 (core engine is 17k min and 5.5k gzipped). Along with a simple jQuery plugin, KUTE.js packs plugins for presentation attibutes, SVG transform, draw stroke and path morph, text string write up or number countdowns, plus additional CSS properties like colors, border-radius or typographic properties.
Because of it's modularity, KUTE.js makes it super easy to extend or override functionality, making it unique among Javascript animation engines.
# Demo / CDN
For documentation, examples and other cool tips, check the <a href="http://thednp.github.io/kute.js/">demo</a>. Thanks to jsdelivr, we have a CDN link <a target="_blank" href="http://www.jsdelivr.com/#!kute.js">here</a>. We also have cdnjs link <a href="https://cdnjs.com/libraries/kute.js" target="_blank">right here</a>. Sweet!
@ -17,17 +19,16 @@ For documentation, examples and other cool tips, check the <a href="http://thedn
# SVG Plugin - [visit page](http://thednp.github.io/kute.js/svg.html)
* morphs SVGs with the `path` tween property, updating the `d` attribute of `<path>` or `<glyph>` elements
* cross-browser SVG `transform` via the `svgTransform` property and the `transform` presentation attribute
* draws SVG stroke with the `draw` tween property for most SVG elements
* SVG related color CSS properties such as: `fill`, `stroke`, `stopColor`
* other SVG CSS properties: `strokeWidth`, `stopOpacity`
* cross-browser SVG `transform` via the `svgTransform` property and the `transform` presentation attribute, this feature also helps stacking transform functions on chained tweens
* draws SVG stroke with the `draw` tween property for most SVG elements: `<path>`, `<glyph>`, `<polygon>` or `<polyline>`, `<ellipse>` or `<circle>`, `<rect>`
# CSS Plugin - [visit page](http://thednp.github.io/kute.js/css.html)
* all box model properties: `margin`, `padding`, with all their variations like `marginTop`, all variations for `width` or `height` like `maxHeight` or `minWidth`, `outlineWidth`, `borderWidth` with all side variations, except short-hand notations
* `borderRadius` properties radius
* `borderRadius` properties and all side variations, shorthand notations and early implementations are not supported
* color properties: `outlineColor`, `borderColor` with all side variations except shorthands, etc
* `clip` property only for `rect` type of values
* text properties: `fontSize`, `lineHeight`, `lettersSpacing` and `wordSpacing`
* `backgroundPosition` property with the ability to understand strings like `top left` and such
* typographic properties: `fontSize`, `lineHeight`, `lettersSpacing` and `wordSpacing`
# Text Plugin - [visit page](http://thednp.github.io/kute.js/text.html)
* animated number increments/decreases
@ -38,10 +39,10 @@ For documentation, examples and other cool tips, check the <a href="http://thedn
* animates any other non-suffixed numeric presentation attribute
* animates `fill`, `stroke` and `stop-color` color properties
* handles attributes namespaces properly with `stroke-opacity` or `strokeOpacity`
* properly handles the suffixes for you
* properly handles the suffixes for you and depends very much on the current values then values you input
# Easing Functions - [visit page](http://thednp.github.io/kute.js/easing.html)
**NOTE:** Starting with KUTE.js v 1.6.0 the Physics and Cubic Bezier Functions are removed from the distribution folder and from CDN repositories, but you can find them in the [Experiments repository on Github](https://github.com/thednp/kute.js/tree/experiments).</p>
**NOTE:** Starting with KUTE.js v 1.6.0 the Physics and Cubic Bezier Functions are removed from the distribution folder and from CDN repositories, but you can find them in the [Experiments repository on Github](https://github.com/thednp/kute.js/tree/experiments). The reasons for that is to make it easy to maintain what's more important: core code quality and the ability to create custom builds.</p>
* optimized dynamics easing functions
* optimized cubic-bezier easing functions
@ -49,7 +50,7 @@ For documentation, examples and other cool tips, check the <a href="http://thedn
# jQuery Plugin
This aims to make the KUTE.js script work native within other jQuery apps but it's not always really needed as we will see in the second subchapter here. Since the demos don't insist on this particular plugin, we'll write some basics [right here](https://github.com/thednp/kute.js#using-the-jquery-plugin).
The plugin is just a few bits of code to bridge all of the the awesome `kute.js` methods to your jQuery apps. The plugin can be found in the [/master](https://github.com/thednp/kute.js/blob/master/kute-jquery.js) folder.
The plugin is just a few bits of code to bridge all of the `KUTE.js` methods to your jQuery apps. The plugin can be found in the [/master](https://github.com/thednp/kute.js/blob/master/kute-jquery.js) folder, CDN repositories and npm packages.
# NPM/Bower
You can install this through NPM or bower respectively:
@ -84,7 +85,8 @@ define([
"kute.js/kute-attr.js", // optional for animating presentation attributes
"kute.js/kute-text.js" // optional for string write and number incrementing animations
], function(KUTE){
// ...
// your stuff happens here, for instance
// KUTE.fromTo('some-selector',{translateX:150}).start();
});
```
@ -95,8 +97,7 @@ At a glance, you can write one line and you're done.
KUTE.fromTo('selector', fromValues, toValues, options).start();
//with jQuery plugin
var tween = $('selector').fromTo(fromValues, toValues, options);
$(tween).KUTE('start');
$('selector').fromTo(fromValues, toValues, options).start();
```
# Advanced Usage
@ -113,10 +114,10 @@ KUTE.fromTo(el,
// callbacks
start: functionOne, // run function when tween starts
complete: functionTwo, // run function when tween animation is finished
update: functionThree // run function while tween running
stop: functionThree // run function when tween stopped
pause: functionThree // run function when tween paused
resume: functionThree // run function when resuming tween
update: functionFour // run function while tween running
stop: functionFive // run function when tween stopped
pause: functionSix // run function when tween paused
resume: functionSeven // run function when resuming tween
}
).start(); // this is to start animation right away
```
@ -125,7 +126,7 @@ KUTE.fromTo(el,
Here's a KUTE.js jQuery Plugin example that showcases most common usage in future apps:
```javascript
// first we define the object(s)
var tween = $('selector').fromTo( // apply fromTo() method to selector
$('selector').fromTo( // apply fromTo() method to selector
{ translate: 0, opacity: 1 }, // fromValues
{ translate: 150, opacity: 0 }, // toValues
@ -136,16 +137,14 @@ var tween = $('selector').fromTo( // apply fromTo() method to selector
//callbacks
start: functionOne, // run function when tween starts
complete: functionTwo, // run function when tween animation is finished
update: functionThree // run function while tween running
stop: functionThree // run function when tween stopped
pause: functionThree // run function when tween paused
resume: functionThree // run function when resuming tween
update: functionFour // run function while tween running
stop: functionFive // run function when tween stopped
pause: functionSix // run function when tween paused
resume: functionSeven // run function when resuming tween
}
);
// then we apply the tween control methods, like start
tween.start();
).start(); // then we apply the tween control methods, like start
```
Starting with KUTE.js 1.5.7, the jQuery Plugin got lighter and uses the proper method automatically based on how many elements are returned from selector. If one element the proper single object method is used `fromTo()` or `to()` but if more than one elements are returned it will use `allFromTo()` or `allTo()`.
## Alternative usage in jQuery powered applications
@ -167,7 +166,6 @@ var tween = KUTE.allFromTo($('selector'), fromValues, toValues, options);
tween.start();
```
# How it works
* it computes all the values before starting the animation, then caches them to avoid layout thrashing that occur during animation
* handles all kinds of `transform` properties and makes sure to always use the same order of the `transform` properties (`translate`, `rotate`, `skew`, `scale`)
@ -181,8 +179,8 @@ tween.start();
* allows you to add many callbacks: `start`, `update`, `complete`, `pause`, `stop`, and they can be set as tween options
* since `translate3D` is best for movement animation performance, `kute.js` will always use it
* accepts "nice & easy string" easing functions, like `linear` or `easingExponentialOut` (removes the use of the evil `eval`, making development safer, easier and closer to standards :)
* uses all 31 Robert Penner's easing functions, as well as bezier and physics easing functions
* handles browser prefixes for you for `transform`, `perspective`, `perspective-origin`, `border-radius` and `requestAnimationFrame`
* uses all 31 Robert Penner's easing functions, as well as any other custom functions such as bezier and physics based easing functions
* handles browser prefixes for you for `transform`, `perspective`, `perspective-origin` and `requestAnimationFrame`
* all this is possible with a core script of less than 20k size!
# Browser Support

View file

@ -1,6 +1,6 @@
{
"name": "KUTE.js",
"version": "1.5.99",
"version": "1.6.0",
"homepage": "http://thednp.github.io/kute.js",
"authors": [
"thednp"

View file

@ -147,7 +147,7 @@
<h2>KUTE.js Project</h2>
<p>KUTE.js continues what was started with <strong>jQueryTween</strong> (removed) and the main goal is to improve usability, compatibility, code quality and performance. KUTE.js includes a jQuery plugin to help you easily implement it in your jQuery applications, and also packs a set of tools such as bezier and physics based easing functions, all elegantly packed for convenience and distributed via CDN.</p>
<p>It all started with a fork of the popular <a href="https://github.com/tweenjs/tween.js" target="_blank">tween.js</a> and ended up having a KUTE.js version 0.9.5 that's almost as good as the boss, <a href="https://greensock.com" target="_blank">GSAP</a>, at least in terms of performance and browser support. TweenMax have been an outstanding source of wonderful coding practices, and a very tough competitor.</p>
<p>It all started with a fork of the popular <a href="https://github.com/tweenjs/tween.js" target="_blank">tween.js</a> and ended up having a KUTE.js version 0.9.5 that's very fast, memory efficient and super easy to use.</p>
<p>In the hystory of the making there were consistent contributions of <a href="https://github.com/dalisoft" target="_blank">Dav</a> aka @dalisoft for features such as play &amp; pause, <a href="text.html">Text Plugin</a>, as well as for performance related issues. Generally I would stress that the code is a joint work of me and Dav. Big thanks Dav, well done.</p>
<p>Also I would like to thank <a href="http://ingwie.me/" target="_blank">Ingwie Phoenix</a> for the npm/Bower and UMD implementations.</p>

View file

@ -52,7 +52,7 @@ function random(min, max) {
// the variables
var container = document.getElementById('container');
// vendor prefix handle
// vendor prefix handle for Tween.js
var transformProperty = KUTE.property('transform'), tws = [];

View file

@ -94,24 +94,52 @@ var draw5 = KUTE.allFromTo(drawEls,{draw:'0% 100%'}, {draw:'50% 50%'}, {duration
draw1.chain(draw2); draw2.chain(draw3); draw3.chain(draw4); draw4.chain(draw5);
drawBtn.addEventListener('click', function(){
!draw1.playing && !draw2.playing && !draw3.playing && !draw4.playing && !draw5.playing && draw1.start();
!draw1.tweens[0].playing && !draw1.tweens[1].playing && !draw1.tweens[2].playing && !draw1.tweens[3].playing && !draw1.tweens[4].playing
&& !draw2.tweens[0].playing && !draw2.tweens[1].playing && !draw2.tweens[2].playing && !draw2.tweens[3].playing && !draw2.tweens[4].playing
&& !draw3.tweens[0].playing && !draw3.tweens[1].playing && !draw3.tweens[2].playing && !draw3.tweens[3].playing && !draw3.tweens[4].playing
&& !draw4.tweens[0].playing && !draw4.tweens[1].playing && !draw4.tweens[2].playing && !draw4.tweens[3].playing && !draw4.tweens[4].playing
&& !draw5.tweens[0].playing && !draw5.tweens[1].playing && !draw5.tweens[2].playing && !draw5.tweens[3].playing && !draw5.tweens[4].playing
&& draw1.start();
}, false);
// // svgTransform examples
// svgTransform examples
// rotation around shape center point
var svgRotate = document.getElementById('svgRotate');
var rotateBtn = document.getElementById('rotateBtn');
var svgr1 = svgRotate.getElementsByTagName('path')[0];
var svgr2 = svgRotate.getElementsByTagName('path')[1];
var svgTween11 = KUTE.to(svgr1, { rotate: 360 }, {transformOrigin: '50% 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween12 = KUTE.to(svgr2, { svgTransform: { translate: 580, rotate: 360 } }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween11 = KUTE.to(svgr1, { rotate: 360 }, { transformOrigin: '50% 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween12 = KUTE.to(svgr2, { svgTransform: { translate: 580, rotate: 360 } }, { yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
rotateBtn.addEventListener('click', function(){
!svgTween11.playing && svgTween11.start();
!svgTween12.playing && svgTween12.start();
}, false);
// rotation around shape's parent center point
var svgRotate1 = document.getElementById('svgRotate1');
var rotateBtn1 = document.getElementById('rotateBtn1');
var svgr11 = svgRotate1.getElementsByTagName('path')[0];
var svgr21 = svgRotate1.getElementsByTagName('path')[1];
var bb = svgr21.getBBox();
var translation = [580, 0];
var svgBB = svgr21.ownerSVGElement.getBBox();
var svgOriginX = (svgBB.width * 50 / 100) - translation[0];
var svgOriginY = (svgBB.height * 50 / 100)- translation[1];
var svgTween111 = KUTE.to(svgr11, { rotate: 360 }, { transformOrigin: (svgBB.width * 50 / 100) + 'px 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween121 = KUTE.to(svgr21, { svgTransform: { translate: translation, rotate: 360 } }, { transformOrigin: [svgOriginX, svgOriginY], yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
rotateBtn1.addEventListener('click', function(){
!svgTween111.playing && svgTween111.start();
!svgTween121.playing && svgTween121.start();
}, false);
// translate
var svgTranslate = document.getElementById('svgTranslate');
var translateBtn = document.getElementById('translateBtn');
var svgt1 = svgTranslate.getElementsByTagName('path')[0];
@ -124,29 +152,18 @@ translateBtn.addEventListener('click', function(){
!svgTween22.playing && svgTween22.start();
}, false);
// skews in chain
var svgSkew = document.getElementById('svgSkew');
var skewBtn = document.getElementById('skewBtn');
var svgsk1 = svgSkew.getElementsByTagName('path')[0];
var svgsk2 = svgSkew.getElementsByTagName('path')[1];
var svgTween31 = KUTE.to(svgsk1, { skewX: -15 }, {transformOrigin: '0px 0px 0px',
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween311 = KUTE.to(svgsk1, { skewY: 15 }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween313 = KUTE.to(svgsk1, { skewX: 0, skewY: 0 }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween31 = KUTE.to(svgsk1, { skewX: -15 }, {transformOrigin: '50% 50% 0px', duration: 1500, easing: "easingCubicInOut"});
var svgTween311 = KUTE.to(svgsk1, { skewY: 15 }, {transformOrigin: '50% 50% 0px', duration: 2500, easing: "easingCubicInOut"});
var svgTween313 = KUTE.to(svgsk1, { skewX: 0, skewY: 0 }, {transformOrigin: '50% 50% 0px', duration: 1500, easing: "easingCubicInOut"});
var svgTween32 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewX: -15 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween322 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 15 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween323 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 0, skewX: 0 } }, {
// yoyo: true, repeat: 1,
duration: 1500, easing: "easingCubicOut"});
var svgTween32 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewX: -15 } }, { transformOrigin: '50% 50%', duration: 1500, easing: "easingCubicInOut"});
var svgTween322 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 15 } }, { transformOrigin: '50% 50%', duration: 2500, easing: "easingCubicInOut"});
var svgTween323 = KUTE.to(svgsk2, {svgTransform: { translate: 580, skewY: 0, skewX: 0 } }, { transformOrigin: '50% 50%', duration: 1500, easing: "easingCubicInOut"});
svgTween31.chain(svgTween311);
svgTween311.chain(svgTween313);
@ -159,6 +176,7 @@ skewBtn.addEventListener('click', function(){
!svgTween32.playing && !svgTween322.playing && !svgTween323.playing && svgTween32.start();
}, false);
// scale
var svgScale = document.getElementById('svgScale');
var scaleBtn = document.getElementById('scaleBtn');
var svgs1 = svgScale.getElementsByTagName('path')[0];
@ -167,36 +185,33 @@ var svgTween41 = KUTE.to(svgs1, { scale: 1.5 }, {transformOrigin: '50% 50%', yoy
var svgTween42 = KUTE.to(svgs2, {svgTransform: {
translate: 580,
scale: 0.5,
} }, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
} }, {transformOrigin: '50% 50%', yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
scaleBtn.addEventListener('click', function(){
!svgTween41.playing && svgTween41.start();
!svgTween42.playing && svgTween42.start();
}, false);
// mixed transforms
var svgMixed = document.getElementById('svgMixed');
var mixedBtn = document.getElementById('mixedBtn');
var svgm1 = svgMixed.getElementsByTagName('path')[0];
var svgm2 = svgMixed.getElementsByTagName('path')[1];
var svgTween51 = KUTE.to(svgm1, { // a regular transform without svg plugin
// svgTransform: {
var svgTween51 = KUTE.to(svgm1, { // a regular CSS3 transform without svg plugin, works in modern browsers only, EXCEPT IE/Edge
translate: 250,
rotate: 360,
skewX: -25,
// skewY: 25,
scale: 1.5,
// }
rotate: 320,
skewX: -15
}, {transformOrigin: "50% 50%", yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
var svgTween52 = KUTE.to(svgm2, {
svgTransform: {
translate: 580+250,
translate: 830,
scale: 1.5,
rotate: 360,
skewX: -25,
// skewY: 25,
}
}, {yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
rotate: 320,
skewX: -15
}
}, {transformOrigin: "50% 50%", yoyo: true, repeat: 1, duration: 1500, easing: "easingCubicOut"});
mixedBtn.addEventListener('click', function(){
!svgTween51.playing && svgTween51.start();

View file

@ -98,10 +98,10 @@
<p>These options only affect animation involving any 3D property from CSS3 <code>transform</code> and have no effect on other CSS properties. While you can set <code>perspective</code> or <code>perspective origin</code> via CSS, these options are here to help, especially with full browser support and preffix free handling.</p>
<ul>
<li><kbd>perspective: 500</kbd> option allows you to set a 3D transformation <code>perspective</code> for a given HTML element. No default value.</li>
<li><kbd>perspectiveOrigin: "50% 50%"</kbd> option allows you to set a <code>perspectiveOrigin</code> for a given HTML. This option has no default value and only accepts valid CSS values according to it's specs.</li>
<li><kbd>perspectiveOrigin: "50% 50%"</kbd> option allows you to set a <code>perspectiveOrigin</code> for a given HTML/SVG element. This option has no default value and only accepts valid CSS values according to it's specs.</li>
<li><kbd>parentPerspective: 500</kbd> option allows you to set a 3D <code>perspective</code> for the <strong>parent</strong> of the HTML element subject to the transform animation.</li>
<li><kbd>parentPerspectiveOrigin: "50% 50%"</kbd> option allows you to set a <code>perspectiveOrigin</code> for the parent of the HTML element subject to the transform animation. Also like the above similar options, this options only accepts valid CSS values.</li>
<li><kbd>transformOrigin: "50% 50%"</kbd> option allows you to set a <code>transformOrigin</code> for the HTML element subject to the transform animation. Also this options only accepts valid CSS values.</li>
<li><kbd>transformOrigin: "50% 50%"</kbd> option allows you to set a <code>transformOrigin</code> for the HTML element subject for the transform animation. Starting KUTE.js 1.6.0 this option also aplies to SVG transforms featured with the SVG Plugin. This options only accepts valid CSS values for CSS3 transforms, but keep in mind that for both CSS3 transform and SVG transform attribute KUTE.js will always think of "50% 50%" as the default value, even if most browser's default value for SVG transform origin is "0px 0px 0px" and the reason is simply consistency all round. When applied to a <kbd class="bg-olive">svgTransform</kbd> property, it can also accept array values: <code>transformOrigin: [250,250]</code>.</li>
</ul>
<h3>SVG Plugin Options</h3>

View file

@ -101,9 +101,9 @@
<button class="btn btn-success" id="start" type="button" style="margin-bottom: 15px">Start</button>
</div>
<!--[if IE]><p class="text-danger">The test page is not intended for legacy browsers.</p><![endif]-->
<!--[if IE]><p class="text-danger">The test page is not intended for Internet Explorer or legacy browsers.</p><![endif]-->
<!--[if !IE ]><!-->
<p>These tests are only for modern browsers. In Google Chrome you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p>These tests are only for modern browsers. In Webkit browsers like Google Chrome and Opera you can enable the FPS metter in developer tools, <a href="https://developer.chrome.com/devtools/docs/rendering-settings" target="_blank">here's how</a>.</p>
<p class="text-note">Please know that a local copy of this page will outperform the live site demo on Google Chrome, the reason is unknown.</p>
<!--<![endif]-->
@ -125,6 +125,7 @@
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js"></script>
<script src="./assets/js/tween.min.js"></script>
<script src="./src/kute.min.js"></script>
<!--<script src="./../kute.js"></script>-->
<script src="./assets/js/perf.js"></script>
<!--<![endif]-->
</body>

View file

@ -113,14 +113,16 @@
<p>The <a href="svg.html">SVG Plugin</a> features cross browser 2D transform animations via the <kbd class="bg-olive">svgTransform</kbd> tween property and the <code>transform</code> presentation attribute, similar in functionality as the Attributes Plugin.</p>
<ul>
<li><kbd class="bg-olive">translate</kbd> sub-property applies horizontal and / or vertical translation. EG. <code>translate:150</code> to translate a shape 150px to the right or <code>translate:[-150,200]</code> to move the element to the left by 150px and to bottom by 200px. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">rotate</kbd> sub-property applies rotation to a shape on the Z axis. Eg. <code>rotate:150</code> will rotate a shape clockwise by 150 degrees or <code>rotate: [45,25,25]</code> to rotate the shape by 45 degrees around the <i>[25,25]</i> coordinate of the parent <code>&lt;svg></code>. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">rotate</kbd> sub-property applies rotation to a shape on the Z axis. Eg. <code>rotate:150</code> will rotate a shape clockwise by 150 degrees around it's own center or around the <code>transformOrigin: '450 450'</code> set tween option coordinate of the parent element. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewX</kbd> sub-property used to apply a skew transformation on the X axis. Eg. <code>skewX:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">skewY</kbd> sub-property used to apply a skew transformation on the Y axis. Eg. <code>skewY:25</code> will skew a shape by 25 degrees. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">scale</kbd> sub-property used to apply a single value size transformation. When using this sub-property, the <kbd class="bg-olive">translate</kbd> will be automatically adjusted to make sure the animation looks as you would expect it from a regular HTML5 element. Eg. <code>scale:0.5</code> will scale down a shape to half of it's initial size. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-olive">scale</kbd> sub-property used to apply a single value size transformation. Eg. <code>scale:0.5</code> will scale a shape to half of it's initial size. <kbd class="bg-lime">IE9+</kbd></li>
<li><kbd class="bg-red">matrix</kbd> sub-property is not supported.</li>
</ul>
<p>As a quick note, the translation is normalized and computed in a way to handle the <code>transformOrigin</code> tween option in all cases, not just for rotations, but also scaling or skews.</p>
<h3>SVG Properties</h3>
<p>The <a href="svg.html">SVG Plugin</a> can animate the <code>d</code> attribute of a given <code>&lt;path&gt;</code> or <code>&lt;glyph&gt;</code> element with the tween property called <kbd class="bg-olive">path</kbd>. The animation effect is widelly known as morph SVG and implemented in various scripts, but the KUTE.js implementation is similar to <a href="http://bl.ocks.org/mbostock/3081153" target="_blank">the D3.js examples</a> for wider usability.</p>
<p>The <a href="svg.html">SVG Plugin</a> can animate the <code>d</code> attribute of a given <code>&lt;path&gt;</code> or <code>&lt;glyph&gt;</code> element with the tween property called <kbd class="bg-olive">path</kbd>. The animation effect is widelly known as morph SVG and implemented in various scripts, but the KUTE.js implementation is similar to <a href="http://bl.ocks.org/mbostock/3081153" target="_blank">the D3.js examples</a> for wider usability and the ability to optimize the visual and performance of the morph, all with the help of special tween options and utilities.</p>
<p>Further more, the SVG Plugin can animate the stroke in a way that you probably know as <code>drawSVG</code>. KUTE.js implements it as <kbd class="bg-olive">draw</kbd> tween property that deals with the well known CSS properties: <kbd>strokeDasharray</kbd> and <kbd>strokeDashoffset</kbd>.

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | Attributes Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | Attributes Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("Attributes Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";var e,r="undefined"!=typeof global?global:window,n=t,i=n.dom,u=n.prepareStart,o=n.parseProperty,a=n.truC,s=n.truD,f=(n.crossCheck,r.Interpolate.unit,r.Interpolate.number),l=r.Interpolate.color,c=function(t,e){return t.getAttribute(e)},p=["fill","stroke","stop-color"],v=function(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()};return u.attr=function(t,e){var r={};for(var n in e){var i=v(n).replace(/_+[a-z]+/,""),u=c(this.element,i);r[i]=p.indexOf(i)!==-1?u||"rgba(0,0,0,0)":u||(/opacity/i.test(n)?1:0)}return r},o.attr=function(t,r){"attr"in i||(i.attr=function(t,e,r,n,u){for(var o in n)i.attributes[o](t,o,r[o],n[o],u)},e=i.attributes={});var n={};for(var u in r){var o=v(u),b=/(%|[a-z]+)$/,d=c(this.element,o.replace(/_+[a-z]+/,""));if(p.indexOf(o)===-1)if(null!==d&&b.test(d)){var y=s(d).u||s(r[u]).u,A=/%/.test(y)?"_percent":"_"+y;o+A in e||(/%/.test(y)?e[o+A]=function(t,e,r,n,i){var u=u||e.replace(A,"");t.setAttribute(u,(100*f(r.v,n.v,i)>>0)/100+n.u)}:e[o+A]=function(t,e,r,n,i){var u=u||e.replace(A,"");t.setAttribute(u,(f(r.v,n.v,i)>>0)+n.u)}),n[o+A]=s(r[u])}else b.test(r[u])&&null!==d&&(null===d||b.test(d))||(o in e||(/opacity/i.test(u)?e[o]=function(t,e,r,n,i){t.setAttribute(e,(100*f(r,n,i)>>0)/100)}:e[o]=function(t,e,r,n,i){t.setAttribute(e,(10*f(r,n,i)>>0)/10)}),n[o]=parseFloat(r[u]));else o in e||(e[o]=function(t,e,n,i,u){t.setAttribute(e,l(n,i,u,r.keepHex))}),n[o]=a(r[u])}return n},this});

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | CSS Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | CSS Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("CSS Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";for(var e="undefined"!=typeof global?global:window,r=t,n=r.dom,i=r.parseProperty,o=r.prepareStart,u=r.property,d=r.getCurrentStyle,a=r.truD,l=r.truC,f=e.Interpolate.number,c=(e.Interpolate.unit,e.Interpolate.color),g=["borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],p=["right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],s=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],h=["fontSize","lineHeight","letterSpacing","wordSpacing"],m=["clip"],b=["backgroundPosition"],v=p.concat(h),y=s.concat(p,h),R=g.concat(m,s,p,h,b),x=R.length,C=C||{},T=0;T<x;T++)g.indexOf(R[T])!==-1?C[R[T]]="rgba(0,0,0,0)":y.indexOf(R[T])!==-1?C[R[T]]=0:b.indexOf(R[T])!==-1?C[R[T]]=[50,50]:"clip"===R[T]&&(C[R[T]]=[0,0,0,0]);for(var T=0,W=g.length;T<W;T++)i[g[T]]=function(t,e){return t in n||(n[t]=function(t,e,r,n,i,o){t.style[e]=c(r,n,i,o.keepHex)}),l(e)},o[g[T]]=function(t){return d(this.element,t)||C[t]};for(var T=0,W=v.length;T<W;T++)i[v[T]]=function(t,e){return t in n||(p.indexOf(t)>-1?n[t]=function(t,e,r,n,i){t.style[e]=(i>.98||i<.02?(100*f(r.v,n.v,i)>>0)/100:f(r.v,n.v,i)>>0)+n.u}:n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r.v,n.v,i)>>0)/100+n.u}),a(e)},o[v[T]]=function(t,e){return d(this.element,t)||C[t]};for(var T=0,W=s.length;T<W;T++)i[s[T]]=function(t,e){return t in n||(n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r.v,n.v,i)>>0)/100+n.u}),a(e)},o[s[T]]=function(t,e){var r=t===s[0]?s[1]:t;return r=u(r),d(this.element,r)||C[t]};return i.clip=function(t,e){if(t in n||(n[t]=function(t,e,r,n,i){var o=0,u=[];for(o;o<4;o++){var d=r[o].v,a=n[o].v,l=n[o].u||"px";u[o]=(100*f(d,a,i)>>0)/100+l}t.style[e]="rect("+u+")"}),e instanceof Array)return[a(e[0]),a(e[1]),a(e[2]),a(e[3])];var r=e.replace(/rect|\(|\)/g,"");return r=/\,/g.test(r)?r.split(/\,/g):r.split(/\s/g),[a(r[0]),a(r[1]),a(r[2]),a(r[3])]},o.clip=function(t,e){var r=d(this.element,t),n=d(this.element,"width"),i=d(this.element,"height");return/rect/.test(r)?r:[0,n,i,0]},i.backgroundPosition=function(t,e){if(t in n||(n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r[0],n[0],i)>>0)/100+"% "+(100*f(r[1],n[1],i)>>0)/100+"%"}),e instanceof Array){var r=a(e[0]).v,i=a(e[1]).v;return[NaN!==r?r:50,NaN!==i?i:50]}var o=e.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);return o=o.split(/(\,|\s)/g),o=2===o.length?o:[o[0],50],[a(o[0]).v,a(o[1]).v]},o.backgroundPosition=function(t,e){return d(this.element,t)||C[t]},this});

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | jQuery Plugin | MIT-License
!function(e,t){if("function"==typeof define&&define.amd)define(["./kute.js","jquery"],function(e,n){return t(n,e),e});else if("object"==typeof module&&"function"==typeof require){var n=require("./kute.js"),r=require("jquery");module.exports=t(r,n)}else{if("undefined"==typeof e.KUTE||"undefined"==typeof e.$&&"undefined"==typeof e.jQuery)throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery");var r=e.jQuery||e.$,n=e.KUTE;r.fn.KUTE=t(r,n)}}(this,function(e,t){"use strict";return e.fn.fromTo=function(e,n,r){var i=this.length>1?this:this[0],o=this.length>1?"allFromTo":"fromTo";return t[o](i,e,n,r)},e.fn.to=function(e,n){var r=this.length>1?this:this[0],i=this.length>1?"allTo":"to";return t[i](r,e,n)},this});
// KUTE.js v1.6.0 | © dnp_theme | jQuery Plugin | MIT-License
!function(e,t){if("function"==typeof define&&define.amd)define(["./kute.js","jquery"],function(e,n){return t(n,e),e});else if("object"==typeof module&&"function"==typeof require){var n=require("./kute.js"),r=require("jquery");module.exports=t(r,n)}else{if("undefined"==typeof e.KUTE||"undefined"==typeof e.$&&"undefined"==typeof e.jQuery)throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery");var r=e.jQuery||e.$,n=e.KUTE;t(r,n)}}(this,function(e,t){"use strict";return e.fn.fromTo=function(e,n,r){var i=this.length>1?this:this[0],o=this.length>1?"allFromTo":"fromTo";return t[o](i,e,n,r)},e.fn.to=function(e,n){var r=this.length>1?this:this[0],i=this.length>1?"allTo":"to";return t[i](r,e,n)},this});

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | Text Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | Text Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("Text-Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";var e="undefined"!=typeof global?global:window,n=t,r=n.dom,i=n.prepareStart,s=n.parseProperty,u=e.Interpolate.number,o=String("abcdefghijklmnopqrstuvwxyz").split(""),a=String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""),l=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),p=String("0123456789").split(""),f=o.concat(a,p),h=(f.concat(l),Math.random),c=Math.min;return i.text=i.number=function(t,e){return this.element.innerHTML},s.text=function(t,e){return"text"in r||(r.text=function(t,e,n,r,i,s){var u=u||"alpha"===s.textChars?o:"upper"===s.textChars?a:"numeric"===s.textChars?p:"alphanumeric"===s.textChars?f:"symbols"===s.textChars?l:s.textChars?s.textChars.split(""):o,g=u.length,m=u[h()*g>>0],b="",d="",x=n.substring(0),y=r.substring(0);b=""!==n?x.substring(x.length,c(i*x.length,x.length)>>0):"",d=y.substring(0,c(i*y.length,y.length)>>0),t.innerHTML=i<1?d+m+b:r}),e},s.number=function(t,e,n){return"number"in r||(r.number=function(t,e,n,r,i){t.innerHTML=u(n,r,i)>>0}),parseInt(e)||0},this});

File diff suppressed because one or more lines are too long

View file

@ -31,7 +31,7 @@
<!-- Polyfill -->
<script src="./assets/js/minifill.js"> </script>
<!-- legacy browsers support via polyfill
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=default,getComputedStyle|gated"> </script> -->
<script src="https://cdn.polyfill.io/v3/polyfill.js?features=default,getComputedStyle|gated"> </script> -->
<!--[if IE]>
<script src="https://cdn.jsdelivr.net/minifill/0.0.2/minifill.min.js"> </script>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
@ -263,7 +263,7 @@ var morph4 = KUTE.fromTo('#startpath2', { path: '#startpath2' }, {
<a id="compliMorphBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>While there are other tools such as <a href="http://alexk111.github.io/SVG-Morpheus/" target="_blank">SVGMorpheus</a> to enable this kind of multi-path morph, they lack in options to improve the visual and performance. The demos look acceptable in most cases, but the SVGs were manually prepared/optimized which makes it pretty much unusable on a broader scope. The SVG Plugin for KUTE.js uses approximatelly the same algorithm as D3.js for determining the coordinates for tween, it's super light, it's a better solution.</p>
<p>So you have many options to improve the visual and performance for your complex animation ideas. The SVG Plugin for KUTE.js uses approximatelly the same algorithm as D3.js for determining the coordinates for tween, it's super light, it's a lighter script, it might be a better solution for your applications.</p>
<h4>Recommendations</h4>
<ul>
@ -300,27 +300,28 @@ var tween3 = KUTE.fromTo('selector1',{draw:'0% 100%'}, {draw:'50% 50%'});
<a id="drawBtn" class="btn btn-blue" href="javascript:void(0)">Start</a>
</div>
</div>
<p>Remember: the <code>draw</code> property also accepts absolute values, eg. <code>draw: '0 150'</code>; the <code>.to()</code> method takes <code>0% 100%</code> as start value for your tweens when <code>stroke-dasharray</code> and <code>stroke-dashoffset</code> are not set.</p>
<p>Remember: the <code class="bg-indigo">draw</code> property also accepts absolute values, eg. <code>draw: '0 150'</code>; the <code>.to()</code> method takes <code>0% 100%</code> as start value for your tweens when <code>stroke-dasharray</code> and <code>stroke-dashoffset</code> are not set.</p>
<h3>SVG Transforms</h3>
<p>Starting with KUTE.js 1.5.2, the SVG Plugin features a new tween property for cross browser SVG transforms, but was coded as a separate set of methods for SVG only, to keep performance tight and solve most browser inconsistencies. A very simple roadmap was described <a href="https://github.com/thednp/kute.js/issues/31" target="_blank">here</a>; in brief we needed to find a way to enable SVG transforms in a <a href="https://css-tricks.com/transforms-on-svg-elements/" target="_blank">reliable and cross-browser</a> supported fashion.</p>
<p>With KUTE.js 1.6.0 the SVG transform is a bigger part of the SVG Plugin for two reasons: first is the ability to use the <code>transformOrigin</code> just like for CSS3 transforms and secondly the unique way to normalize translation to work with the transform origin in a way that the animation is just as consistent as for CSS3 transforms on non-SVG elements. Also the value processing is consistent with the <a href="https://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace">working draft</a>.</p>
<p>While you can still use regular <a href="examples.html">CSS3 transforms</a> for SVGs on browsers like Google Chrome, Opera and others, Firefox struggles big time with the percentage based <code>transform-origin</code> values and ALL Internet Explorer versions have no implementation for CSS3 transforms on SVG elements.</p>
<p>KUTE.js SVG Plugin comes with a better way to animate transforms on SVGs shapes reliably on all browsers, by the use of the <code>transform</code> presentation attribute and the <code class="bg-indigo">svgTransform</code> tween property with a special notation:</p>
<h3>SVG Transforms</h3>
<p>Starting with KUTE.js 1.5.2, the SVG Plugin features a new tween property for cross browser SVG transforms, but was coded as a separate set of methods for SVG only, to keep performance tight. A very simple roadmap was described <a href="https://github.com/thednp/kute.js/issues/31" target="_blank">here</a>; in brief we needed to find a way to enable transforms for SVG in a <a href="https://css-tricks.com/transforms-on-svg-elements/" target="_blank">reliable and cross-browser</a> supported fashion.</p>
<p>While you can still use regular <a href="examples.html">CSS3 transforms</a> for SVGs on browsers like Google Chrome and Firefox, to animate SVG shapes on all browsers, we use the <code>transform</code> presentation attribute and the <code class="bg-indigo">svgTransform</code> tween property with a special notation:</p>
<pre><code class="language-javascript">// regular CSS3 transforms apply to SVG elements, but not working in IE and some older Opera versions
var tween1 = KUTE.to('shape', { translate: [150,100], rotate: 45, skewX: 15, skewY: 20, scale: 1.5 }, {transformOrigin: "50% 50%"});
<pre><code class="language-javascript">// using the svgTransform property works in all SVG enabled browsers
var tween2 = KUTE.to('shape', {svgTransform: { translate: [150,100], rotate: 45, skewX: 15, skewY: 20, scale: 1.5 }});
// using the svgTransform property, working in all browsers
// the Y translation as well as rotate transform-origin are provided
var tween2 = KUTE.to('shape', {svgTransform: { translate: [120,100], rotate: [45,0,0], skewX: 15, skewY: 20, scale: 1.2 }});
// OR using shorthand notations
// we understand the Y translation is 0 and the rotation transform-origin is 50% 50%,
// the center of the shape and not the parent SVG's center
var tween2 = KUTE.to('shape', {svgTransform: { translate: 120, rotate: 45, scale: 1.2 }});
// regular CSS3 transforms apply to SVG elements but not all browsers fully/partially supported
var tween1 = KUTE.to('shape', { translate: [150,100], rotate: 45, skewX: 15, skewY: 20, scale: 1.5 }, { transformOrigin: '50% 50%' });
</code></pre>
<p>As you can see we have some familiar notation as well as new notation. One thing to know is that this feature may not support and wasn't tested for SVG specific chained/nested transformations. Perhaps the most important thing to remember is the fact that SVG tranformations always use SVG coordinates system, and the <code>transform</code> attribute requires no degree or pixel as measurement units. Let's break it down.</p>
<p>As you can see we have some familiar notation, but an important notice here is that <code class="bg-indigo">svgTransform</code> tween property treat all SVG transform functions as if you are using the <code>50% 50%</code> of the shape box at all times by default, even if the default value is "0px 0px 0px" on SVGs in most browsers.</p>
<p>Perhaps the most important thing to remember is the fact that SVG tranformations always use SVG coordinates system, and the <code>transform</code> attribute accepts no measurement units such as degrees or pixels. For these reasons the <code>transformOrigin</code> tween option can also accept array values just in case you need coordinates relative to the parent <code>&lt;svg></code> element. Also values like <i>top left</i> values will work.</p>
<p>In the following examples we showcase the animation of CSS3 transform applied to SVG shapes (LEFT) as well as <code class="bg-indigo">svgTransform</code> based animations (RIGHT). I highly encourage you to test all of them in all browsers, and as a word ahead, animations in Webkit browsers will look identical, while others are inconsistent or not responding to DOM changes. Let's break it down to pieces.</p>
<h4>SVG Rotation</h4>
<p>In our first example we'll have a look at rotations. For instance setting <code>rotate: [45,0,0]</code>, the first value is the angle to which the shape will rotate to and the other two values are coordinates for the <code>transform-origin</code>. When <code>rotate: 45</code> notation is used, the script will calculate the coordinates of the shape's central point, as if your <code>transform-origin</code> default value is <i>50% 50%</i>, something you would expect from regular HTML elements. However keep in mind that the <code>transform-origin</code> coordinates are relative to the parent <code>&lt;svg></code> element. Let's have a look at a quick demo:</p>
<p>Our first chapter of the SVG transform is all about rotations, perhaps the most important part here. As of with KUTE.js 1.6.0 the <code class="bg-indigo">svgTransform</code> will only accept single value for the angle value <code>rotate: 45</code>, the rotation will go around the shape's center point by default, again, contrary to the browsers' default value and you can set a <code>transformOrigin</code> tween option to override the behavior.</p>
<p>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:</p>
<div class="featurettes">
<svg id="svgRotate" class="example-box-model example-box" style="width:320px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1085 513">
<path class="bg-olive" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
@ -331,41 +332,41 @@ var tween2 = KUTE.to('shape', {svgTransform: { translate: 120, rotate: 45, scale
<a id="rotateBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween uses the CSS3 transform notation and the animation clearly shows the shape rotating around it's center coordinate, as we've set <code>transformOrigin</code> option to <i>50% 50%</i>, but this animation doesn't work in all browsers. The second tween uses the <code>rotate: 360</code> notation and the animation shows the shape rotating around it's own central point, an animation that DO WORK in all SVG enabled browsers.</p>
<p>When for CSS3 transforms we could have used values such as <i>center bottom</i> as <code>transform-origin</code> (also not supported in all modern browsers), the entire processing was basically in/by the browser, however when it comes to SVG we need to make use of the SVG API functions to determine the proper value. But stay cool, here comes <code>.getBBox()</code> to the rescue! Here's how to rotate an element around it's <i>25% 75%</i> coordinate:</p>
<p>The first tween uses the CSS3 transform notation and the animation clearly shows the shape rotating around it's center coordinate, as we've set <code>transformOrigin</code> option to <i>50% 50%</i>, but this animation doesn't work in IE browsers, while in Firefox is inconsistent with the SVG coordinate system. The second tween uses the <code>rotate: 360</code> notation and the animation shows the shape rotating around it's own central point and without any option, an animation that DO WORK in all SVG enabled browsers.</p>
<p>When for CSS3 transforms we could have used values such as <i>center bottom</i> as <code>transform-origin</code> (also not supported in all modern browsers for SVGs), the entire processing was basically in/by the browser, however when it comes to SVGs the plugin here will compute the <code>transformOrigin</code> tween setting value accordingly to use a shape's <code>.getBBox()</code> value to determine for instance the coordinates for <i>25% 75%</i> position for instance or <i>center top</i>.</p>
<pre><code class="language-javascript">// rotate around element's "25% 75%"" coordinate as transform-origin
// get the bounding box
// returns an object like {x:0, y:20, width:200, height: 200} for any type of SVG shape
// x is the distance from top, y is the distance from left, width and height are just that
var bb = element.getBBox();
// determine the X point of transform-origin for 25%
var shapeOriginX = bb.x + (25 * bb.width / 100);
// determine the Y point of transform-origin for 75%
var shapeOriginY = bb.y + (75 * bb.height / 100);
// set your rotation tween with "25% 75%" transform-origin
var rotationTween = KUTE.to(element, {svgTransform: {rotate: [45, shapeOriginX, shapeOriginY]}});
</code></pre>
<p>Or you can rotate an element around the parent's <code>&lt;svg></code> <i>50% 50%</i> coordinate:</p>
<p>In other cases you may want to rotate shapes around the center point of the parent <code>&lt;svg></code> or <code>&lt;g></code> element, and we use it's <code>.getBBox()</code> to determine the <i>50% 50%</i> coordinate, so here's how to deal with it:</p>
<pre><code class="language-javascript">// rotate around parent svg's "50% 50%" coordinate as transform-origin
// get the bounding box
// get the bounding box of the parent element
var svgBB = element.ownerSVGElement.getBBox(); // returns same object but it's for the parent &lt;svg> element
// we need to know the current translate position of the element [x,y]
// in our case is:
var translation = [580,0];
// determine the X point of transform-origin for 50%
var svgOriginX = svgBB.x + (50 * svgBB.width / 100);
var svgOriginX = svgBB.width * 50 / 100 - translation[0];
// determine the Y point of transform-origin for 50%
var svgOriginY = svgBB.y + (50 * svgBB.height / 100);
var svgOriginY = svgBB.height * 50 / 100 - translation[1];
// set your rotation tween with "50% 50%" transform-origin of the parent &lt;svg> element
var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, svgOriginY]}});
var rotationTween = KUTE.to(element, {svgTransform: {rotate: 150}}, { transformOrigin: [svgOriginX, svgOriginY]} );
</code></pre>
<div class="featurettes">
<svg id="svgRotate1" class="example-box-model example-box" style="width:320px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1085 513">
<path class="bg-olive" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
<path class="bg-blue" transform="translate(580)" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
</svg>
<div class="example-buttons">
<a id="rotateBtn1" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>This is the only example we have adapted the transform-origin for the CSS3 transform rotation so that both animations look consistent in all browsers, and if you are interested in learning about this fix, similar to the above, just we are adding "px" to the calculated value, so make sure to check <a href="./assets/js/svg.js">svg.js</a> file.</p>
<h4>SVG Translation</h4>
<p>In this example we'll have a look at translations, so when setting <code>translate: [150,0]</code>, 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 <code>translate: 150</code> 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:</p>
<div class="featurettes">
@ -392,8 +393,7 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, s
<a id="skewBtn" class="btn btn-red" href="javascript:void(0)">Start</a>
</div>
</div>
<p>The first tween skews the shape on both X and Y axis in a chain via regular CSS3 transforms and the second tween skews the shape on X and Y axis via the <code class="bg-indigo">svgTransform</code> tween property. The example also showcases the fact that chain transformations for SVGs via <code>transform</code> attribute works just as for the CSS3 transformations and you really have to check the example code here to learn how to master this technique.</p>
<p>For this particular example we've set <code>transformOrigin</code> option to "0px 0px" for the first shape (the default value for SVGs' <i>transform-origin</i> on most browsers) because we cannot set anything similar for the skews of the <code>transform</code> attribute for the second shape. Generally skews are hard to handle for SVGs because they are independent of any <i>transform-origin</i>. We can only compensate with translation, <a href="http://stackoverflow.com/questions/39191054/how-to-compensate-translate-when-skewx-and-skewy-are-used-on-svg">a very complicated story</a>.</p>
<p>The first tween skews the shape on both X and Y axis in a chain via regular CSS3 transforms and the second tween skews the shape on X and Y axis via the <code class="bg-indigo">svgTransform</code> tween property. You will notice translation kicking in to set the transform origin and the example also showcases the fact that chain transformations for SVGs via <code>transform</code> attribute works just as for the CSS3 transformations.</p>
<h4>SVG Scaling</h4>
<p>Another transform example for SVGs is the scale. Unlike translations, for scale animation the plugin only accepts single value like <code>scale: 1.5</code>, for both X (horizontal) axis and Y (vertical) axis, to keep it simple and even if SVGs do support <code>scale(X,Y)</code>. 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:</p>
@ -410,7 +410,7 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, s
<p>The first tween scales the shape at <code>scale: 1.5</code> via regular CSS3 transforms, and the second tween scales down the shape at <code>scale: 0.5</code> value via <code class="bg-indigo">svgTransform</code>. If you inspect the elements, you will notice for the second shape translation is involved, and this is to keep <code>transform-origin</code> at an expected <i>50% 50%</i> value. A similar case as with the skews.</p>
<h4>SVG Mixed Transforms</h4>
<p>Our last transform example for SVGs is the mixed transformation. Similar with scale animation the plugin will try to adjust the rotation <code>transform-origin</code> 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:</p>
<p>Our last transform example for SVGs is the mixed transformation. Just like for the other examples the plugin will try to adjust the rotation <code>transform-origin</code> 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:</p>
<div class="featurettes">
<svg id="svgMixed" class="example-box-model example-box" style="width: 320px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1085 513" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<path class="bg-green" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
@ -422,10 +422,10 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, s
</div>
</div>
<p>Both shapes are scaled at <code>scale: 1.5</code>, translated to <code>translate: 250</code> and skewed at <code>skewX: -15</code>. 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 <code>transform-origin</code> at an expected <i>50% 50%</i> value. This means that the plugin will also compensate rotation transform origin when skews are used, so that both CSS3 transform property and SVG transform attribute have an identical animation.</p>
<h4>Recommendations for SVG Transforms</h4>
<ul>
<li>The SVG Plugin coming with KUTE.js version 1.5.3 is trying to make sure animations don't go out of control, and <b>always uses same order of transform functions</b>: <code>translate</code>, <code>scale</code>, <code>rotate</code>, <code>skewX</code> and <code>skewY</code>. All this to make sure the animation looks like we would expect from regular HTML elements transformations. Maybe future versions will feature <code>.matrix()</code> transformations to handle all possible transform function combinations, but I'm going to need help with implementation and testing.</li>
<li>The SVG Plugin coming with KUTE.js version 1.6.0 is successfuly handling all possible combinations of transform functions, and <b>always uses same order of transform functions</b>: <code>translate</code>, <code>rotate</code>, <code>skewX</code>, <code>skewY</code> and <code>scale</code> to keep animation consistent and with same aspect as for CSS3 transforms on non-SVG elements. Keep in mind that the SVG transforms will use the center of a shape as transform origin by default.</li>
<li>Keep in mind the adjustments required for rotations, remember the <code>.getBBox()</code> method, it's really useful to set custom <code>transform-origin</code>.</li>
<li>By default browsers use <code>overflow: hidden</code> for <code>&lt;svg></code> so child elements are partialy/completely hidden while animating. You might want to set <code>overflow: visible</code> or some browser specific tricks if that is the case.</li>
<li>When using <code>viewBox="0 0 500 500"</code> attribute for <code>&lt;svg></code> and no <code>width</code> and/or <code>height</code> attribute(s), means that you expect the SVG to be scalable and most Internet Explorer versions simply don't work. You might want to <a href="https://css-tricks.com/scale-svg/" target="_blank">check this tutorial</a>.</li>
@ -436,11 +436,13 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, s
</ul>
<p>The SVG Plugin can be combined with the <a href="attr.html">Attributes Plugin</a> to enable even more advanced/complex animations for SVG elements.</p>
<h3>Future Plans</h3>
<p>Since SVG morph scripting works only with <code>path</code> or <code>glyph</code> elements, I'm also considering a very light <code>convertToPath</code> feature, but there are some <a href="https://github.com/Waest/SVGPathConverter" target="_blank">already out there</a>.</p>
</div>
<h3>SVG Plugin Tips</h3>
<ul>
<li>The SVG Plugin can be combined with the <a href="attr.html">Attributes Plugin</a> to enable even more advanced/complex animations for SVG elements.</li>
<li>Since SVG morph scripting works only with <code>path</code> or <code>glyph</code> elements, you might need a <code>convertToPath</code> feature, so <a href="https://github.com/Waest/SVGPathConverter" target="_blank">check this out</a>.</li>
</ul>
</div>
<ul id="share" class="nav">
<li>Share </li>
@ -471,7 +473,8 @@ var rotationTween = KUTE.to(element, {svgTransform: {rotate: [150, svgOriginX, s
<!--<script src="http://cdn.jsdelivr.net/kute.js/1.6.0/kute.min.js"></script> KUTE CDN -->
<script src="./src/kute.min.js"></script> <!-- some stuff -->
<script src="./src/kute-attr.min.js"></script> <!-- some stuff -->
<script src="./src/kute-svg.min.js"></script> <!-- some stuff -->
<!--<script src="./src/kute-svg.min.js"></script> some stuff -->
<script src="./../kute-svg.js"></script> <!-- some stuff -->
<script src="./assets/js/scripts.js"></script> <!-- global scripts stuff -->
<script src="./assets/js/svg.js"></script> <!-- css plugin stuff -->
</body>

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | Attributes Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | Attributes Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("Attributes Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";var e,r="undefined"!=typeof global?global:window,n=t,i=n.dom,u=n.prepareStart,o=n.parseProperty,a=n.truC,s=n.truD,f=(n.crossCheck,r.Interpolate.unit,r.Interpolate.number),l=r.Interpolate.color,c=function(t,e){return t.getAttribute(e)},p=["fill","stroke","stop-color"],v=function(t){return t.replace(/[A-Z]/g,"-$&").toLowerCase()};return u.attr=function(t,e){var r={};for(var n in e){var i=v(n).replace(/_+[a-z]+/,""),u=c(this.element,i);r[i]=p.indexOf(i)!==-1?u||"rgba(0,0,0,0)":u||(/opacity/i.test(n)?1:0)}return r},o.attr=function(t,r){"attr"in i||(i.attr=function(t,e,r,n,u){for(var o in n)i.attributes[o](t,o,r[o],n[o],u)},e=i.attributes={});var n={};for(var u in r){var o=v(u),b=/(%|[a-z]+)$/,d=c(this.element,o.replace(/_+[a-z]+/,""));if(p.indexOf(o)===-1)if(null!==d&&b.test(d)){var y=s(d).u||s(r[u]).u,A=/%/.test(y)?"_percent":"_"+y;o+A in e||(/%/.test(y)?e[o+A]=function(t,e,r,n,i){var u=u||e.replace(A,"");t.setAttribute(u,(100*f(r.v,n.v,i)>>0)/100+n.u)}:e[o+A]=function(t,e,r,n,i){var u=u||e.replace(A,"");t.setAttribute(u,(f(r.v,n.v,i)>>0)+n.u)}),n[o+A]=s(r[u])}else b.test(r[u])&&null!==d&&(null===d||b.test(d))||(o in e||(/opacity/i.test(u)?e[o]=function(t,e,r,n,i){t.setAttribute(e,(100*f(r,n,i)>>0)/100)}:e[o]=function(t,e,r,n,i){t.setAttribute(e,(10*f(r,n,i)>>0)/10)}),n[o]=parseFloat(r[u]));else o in e||(e[o]=function(t,e,n,i,u){t.setAttribute(e,l(n,i,u,r.keepHex))}),n[o]=a(r[u])}return n},this});

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | CSS Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | CSS Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("CSS Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";for(var e="undefined"!=typeof global?global:window,r=t,n=r.dom,i=r.parseProperty,o=r.prepareStart,u=r.property,d=r.getCurrentStyle,a=r.truD,l=r.truC,f=e.Interpolate.number,c=(e.Interpolate.unit,e.Interpolate.color),g=["borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],p=["right","bottom","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","outlineWidth"],s=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],h=["fontSize","lineHeight","letterSpacing","wordSpacing"],m=["clip"],b=["backgroundPosition"],v=p.concat(h),y=s.concat(p,h),R=g.concat(m,s,p,h,b),x=R.length,C=C||{},T=0;T<x;T++)g.indexOf(R[T])!==-1?C[R[T]]="rgba(0,0,0,0)":y.indexOf(R[T])!==-1?C[R[T]]=0:b.indexOf(R[T])!==-1?C[R[T]]=[50,50]:"clip"===R[T]&&(C[R[T]]=[0,0,0,0]);for(var T=0,W=g.length;T<W;T++)i[g[T]]=function(t,e){return t in n||(n[t]=function(t,e,r,n,i,o){t.style[e]=c(r,n,i,o.keepHex)}),l(e)},o[g[T]]=function(t){return d(this.element,t)||C[t]};for(var T=0,W=v.length;T<W;T++)i[v[T]]=function(t,e){return t in n||(p.indexOf(t)>-1?n[t]=function(t,e,r,n,i){t.style[e]=(i>.98||i<.02?(100*f(r.v,n.v,i)>>0)/100:f(r.v,n.v,i)>>0)+n.u}:n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r.v,n.v,i)>>0)/100+n.u}),a(e)},o[v[T]]=function(t,e){return d(this.element,t)||C[t]};for(var T=0,W=s.length;T<W;T++)i[s[T]]=function(t,e){return t in n||(n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r.v,n.v,i)>>0)/100+n.u}),a(e)},o[s[T]]=function(t,e){var r=t===s[0]?s[1]:t;return r=u(r),d(this.element,r)||C[t]};return i.clip=function(t,e){if(t in n||(n[t]=function(t,e,r,n,i){var o=0,u=[];for(o;o<4;o++){var d=r[o].v,a=n[o].v,l=n[o].u||"px";u[o]=(100*f(d,a,i)>>0)/100+l}t.style[e]="rect("+u+")"}),e instanceof Array)return[a(e[0]),a(e[1]),a(e[2]),a(e[3])];var r=e.replace(/rect|\(|\)/g,"");return r=/\,/g.test(r)?r.split(/\,/g):r.split(/\s/g),[a(r[0]),a(r[1]),a(r[2]),a(r[3])]},o.clip=function(t,e){var r=d(this.element,t),n=d(this.element,"width"),i=d(this.element,"height");return/rect/.test(r)?r:[0,n,i,0]},i.backgroundPosition=function(t,e){if(t in n||(n[t]=function(t,e,r,n,i){t.style[e]=(100*f(r[0],n[0],i)>>0)/100+"% "+(100*f(r[1],n[1],i)>>0)/100+"%"}),e instanceof Array){var r=a(e[0]).v,i=a(e[1]).v;return[NaN!==r?r:50,NaN!==i?i:50]}var o=e.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/g,50);return o=o.split(/(\,|\s)/g),o=2===o.length?o:[o[0],50],[a(o[0]).v,a(o[1]).v]},o.backgroundPosition=function(t,e){return d(this.element,t)||C[t]},this});

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | jQuery Plugin | MIT-License
!function(e,t){if("function"==typeof define&&define.amd)define(["./kute.js","jquery"],function(e,n){return t(n,e),e});else if("object"==typeof module&&"function"==typeof require){var n=require("./kute.js"),r=require("jquery");module.exports=t(r,n)}else{if("undefined"==typeof e.KUTE||"undefined"==typeof e.$&&"undefined"==typeof e.jQuery)throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery");var r=e.jQuery||e.$,n=e.KUTE;r.fn.KUTE=t(r,n)}}(this,function(e,t){"use strict";return e.fn.fromTo=function(e,n,r){var i=this.length>1?this:this[0],o=this.length>1?"allFromTo":"fromTo";return t[o](i,e,n,r)},e.fn.to=function(e,n){var r=this.length>1?this:this[0],i=this.length>1?"allTo":"to";return t[i](r,e,n)},this});
// KUTE.js v1.6.0 | © dnp_theme | jQuery Plugin | MIT-License
!function(e,t){if("function"==typeof define&&define.amd)define(["./kute.js","jquery"],function(e,n){return t(n,e),e});else if("object"==typeof module&&"function"==typeof require){var n=require("./kute.js"),r=require("jquery");module.exports=t(r,n)}else{if("undefined"==typeof e.KUTE||"undefined"==typeof e.$&&"undefined"==typeof e.jQuery)throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery");var r=e.jQuery||e.$,n=e.KUTE;t(r,n)}}(this,function(e,t){"use strict";return e.fn.fromTo=function(e,n,r){var i=this.length>1?this:this[0],o=this.length>1?"allFromTo":"fromTo";return t[o](i,e,n,r)},e.fn.to=function(e,n){var r=this.length>1?this:this[0],i=this.length>1?"allTo":"to";return t[i](r,e,n)},this});

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
// KUTE.js v1.5.99 | © dnp_theme | Text Plugin | MIT-License
// KUTE.js v1.6.0 | © dnp_theme | Text Plugin | MIT-License
!function(t,e){if("function"==typeof define&&define.amd)define(["kute.js"],e);else if("object"==typeof module&&"function"==typeof require)module.exports=e(require("kute.js"));else{if("undefined"==typeof t.KUTE)throw new Error("Text-Plugin require KUTE.js.");e(t.KUTE)}}(this,function(t){"use strict";var e="undefined"!=typeof global?global:window,n=t,r=n.dom,i=n.prepareStart,s=n.parseProperty,u=e.Interpolate.number,o=String("abcdefghijklmnopqrstuvwxyz").split(""),a=String("abcdefghijklmnopqrstuvwxyz".toUpperCase()).split(""),l=String("~!@#$%^&*()_+{}[];'<>,./?=-").split(""),p=String("0123456789").split(""),f=o.concat(a,p),h=(f.concat(l),Math.random),c=Math.min;return i.text=i.number=function(t,e){return this.element.innerHTML},s.text=function(t,e){return"text"in r||(r.text=function(t,e,n,r,i,s){var u=u||"alpha"===s.textChars?o:"upper"===s.textChars?a:"numeric"===s.textChars?p:"alphanumeric"===s.textChars?f:"symbols"===s.textChars?l:s.textChars?s.textChars.split(""):o,g=u.length,m=u[h()*g>>0],b="",d="",x=n.substring(0),y=r.substring(0);b=""!==n?x.substring(x.length,c(i*x.length,x.length)>>0):"",d=y.substring(0,c(i*y.length,y.length)>>0),t.innerHTML=i<1?d+m+b:r}),e},s.number=function(t,e,n){return"number"in r||(r.number=function(t,e,n,r,i){t.innerHTML=u(n,r,i)>>0}),parseInt(e)||0},this});

4
dist/kute.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
/* KUTE.js - The Light Tweening Engine
* package - Attributes Plugin
* desc - enables animation for any numeric presentation attribute
* desc - enables animation for color attributes and any numeric presentation attribute
* by dnp_theme
* Licensed under MIT-License
*/
@ -25,7 +25,7 @@
// here we go with the plugin
var getCurrentValue = function(e,a){ return e.getAttribute(a); }, // get current attribute value
svgColors = ['fill','stroke','stop-color'], atts,
svgColors = ['fill','stroke','stop-color'], attributes,
replaceUppercase = function(a) {
return a.replace(/[A-Z]/g, "-$&").toLowerCase();
};
@ -49,53 +49,53 @@
DOM.attributes[o](l,o,a[o],b[o],v);
}
}
atts = DOM.attributes = {}
attributes = DOM.attributes = {}
}
var ats = {};
var attributesObject = {};
for ( var p in o ) {
var prop = replaceUppercase(p), regex = /(%|[a-z]+)$/, cv = getCurrentValue(this.element,prop.replace(/_+[a-z]+/,''));
if ( svgColors.indexOf(prop) === -1) {
if ( cv !== null && regex.test(cv) ) {
var prefix = trueDimension(cv).u || trueDimension(o[p]).u, s = /%/.test(prefix) ? '_percent' : '_'+prefix;
if (!(prop+s in atts)) {
if (!(prop+s in attributes)) {
if (/%/.test(prefix)) {
atts[prop+s] = function(l,p,a,b,v) {
attributes[prop+s] = function(l,p,a,b,v) {
var _p = _p || p.replace(s,'');
l.setAttribute(_p, ((number(a.v,b.v,v) * 100>>0)/100) + b.u );
}
} else {
atts[prop+s] = function(l,p,a,b,v) {
attributes[prop+s] = function(l,p,a,b,v) {
var _p = _p || p.replace(s,'');
l.setAttribute(_p, (number(a.v,b.v,v)>>0) + b.u );
}
}
}
ats[prop+s] = trueDimension(o[p]);
attributesObject[prop+s] = trueDimension(o[p]);
} else if ( !regex.test(o[p]) || cv === null || cv !== null && !regex.test(cv) ) {
if (!(prop in atts)) {
if (!(prop in attributes)) {
if (/opacity/i.test(p)) {
atts[prop] = function(l,o,a,b,v) {
attributes[prop] = function(l,o,a,b,v) {
l.setAttribute(o, (number(a,b,v) * 100 >> 0) / 100 );
}
} else {
atts[prop] = function(l,o,a,b,v) {
attributes[prop] = function(l,o,a,b,v) {
l.setAttribute(o, (number(a,b,v) *10 >> 0 ) / 10 );
}
}
}
ats[prop] = parseFloat(o[p]);
attributesObject[prop] = parseFloat(o[p]);
}
} else {
if (!(prop in atts)) {
atts[prop] = function(l,u,a,b,v) {
if (!(prop in attributes)) {
attributes[prop] = function(l,u,a,b,v) {
l.setAttribute(u, color(a,b,v,o.keepHex));
}
}
ats[prop] = trueColor(o[p]);
attributesObject[prop] = trueColor(o[p]);
}
}
return ats;
return attributesObject;
}
return this;

View file

@ -16,11 +16,12 @@
})(this, function(KUTE){
'use strict';
var g = typeof global !== 'undefined' ? global : window, K = KUTE, DOM = K.dom,
var g = typeof global !== 'undefined' ? global : window, K = KUTE, DOM = K.dom, // connect to KUTE object and global
parseProperty = K.parseProperty, prepareStart = K.prepareStart, property = K.property,
getCurrentStyle = K.getCurrentStyle, trueDimension = K.truD, trueColor = K.truC,
number = g.Interpolate.number, unit = g.Interpolate.unit, color = g.Interpolate.color;
// supported properties
var _colors = ['borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'outlineColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
_boxModel = ['right', 'bottom', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
'padding', 'margin', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'marginTop','marginBottom', 'marginLeft', 'marginRight',

View file

@ -21,7 +21,7 @@
} else if (typeof root.KUTE !== "undefined" && (typeof root.$ !== 'undefined' || typeof root.jQuery !== 'undefined' ) ) {
// jQuery always has two ways of existing... Find one, and pass.
var $ = root.jQuery || root.$, KUTE = root.KUTE;
$.fn.KUTE = factory($, KUTE);
factory($, KUTE);
} else {
throw new Error("jQuery Plugin for KUTE.js depend on KUTE.js and jQuery");
}
@ -39,4 +39,4 @@
};
return this;
});
});

View file

@ -22,24 +22,33 @@
DOM = K.dom, parseProperty = K.parseProperty, prepareStart = K.prepareStart, getCurrentStyle = K.getCurrentStyle,
trueColor = K.truC, trueDimension = K.truD, crossCheck = K.crossCheck,
number = g.Interpolate.number, unit = g.Interpolate.unit, color = g.Interpolate.color, // interpolate functions
_isIE = navigator && (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null) ? parseFloat( RegExp.$1 ) : false;
isIE = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null ? parseFloat( RegExp.$1 ) : false,
isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // we optimize morph depending on device type
if (isIE&&isIE<9) {return;} // return if SVG API is not supported
// here we go with the plugin
var pathReg = /(m[^(h|v|l)]*|[vhl][^(v|h|l|z)]*)/gmi, ns = 'http://www.w3.org/2000/svg',
coords = g.Interpolate.coords = function(a,b,l,v) { // function(array1, array2, length, progress) for SVG morph
coords = g.Interpolate.coords = isMobile ? function(a,b,l,v) { // function(array1, array2, length, progress) for SVG morph
var points =[];
for(var i=0;i<l;i++) { // for each point
points[i] = [];
for(var j=0;j<2;j++) { // each point coordinate
points[i].push( (a[i][j]+(b[i][j]-a[i][j])*v) >> 0 );
points[i].push( a[i][j]+(b[i][j]-a[i][j])*v );
}
}
return points;
} : function(a,b,l,v) { // on desktop devices we use more accuracy for morph
var points =[];
for(var i=0;i<l;i++) { // for each point
points[i] = [];
for(var j=0;j<2;j++) { // each point coordinate
points[i].push( ((a[i][j]+(b[i][j]-a[i][j])*v) * 10 >> 0)/10 );
}
}
return points;
};
if (_isIE&&_isIE<9) {return;} // return if SVG API is not supported
// SVG MORPH
var getSegments = function(s,e,r){ // getSegments returns an array of points based on a sample size morphPrecision
var s1 = [], e1 = [], le1 = s.getTotalLength(), le2 = e.getTotalLength(), ml = Math.max(le1,le2),
@ -126,7 +135,8 @@
return p;
},
computePathCross = function(s,e){ // pathCross
var s1, e1, pointsArray, largerPathLength, smallerPath, largerPath, simulatedSmallerPath, nsm = [], sml, cl = [], len, tl, cs;
var s1, e1, pointsArray, largerPathLength, smallerPath, largerPath, simulatedSmallerPath, nsm = [], sml, cl = [], len, tl, cs,
index = this.options.morphIndex;
if (!this._isPolygon) {
s = createPath(s); e = createPath(e);
@ -158,8 +168,8 @@
if (this.options.reverseSecondPath) { e1.reverse(); }
// shift second array to for smallest tween distance
if (this.options.morphIndex) {
var e11 = e1.splice(this.options.morphIndex,largerPathLength-this.options.morphIndex);
if (index) {
var e11 = e1.splice(index,largerPathLength-index);
e1 = e11.concat(e1);
}
@ -197,7 +207,7 @@
// SVG DRAW
var percent = function(v,l){ return parseFloat(v) / 100 * l; }, // percent
var percent = function(v,l){ return parseFloat(v) / 100 * l; },
// SVG DRAW UTILITITES
// http://stackoverflow.com/a/30376660
getRectLength = function(el){ // returns the length of a Rect
@ -295,116 +305,117 @@
// SVG Transform
var parseTransform = function (a){ // helper function that turns transform value from string to object
var d = a && /\)/.test(a) ? a.split(')') : 'none', j, c ={}, p;
var parseStringOrigin = function(origin,box){
return /[a-zA-Z]/.test(origin) && !/px/.test(origin) ? origin.replace(/top|left/,0).replace(/right|bottom/,100).replace(/center|middle/,50)
: /%/.test(origin) ? (box.x + parseFloat(origin) * box.width / 100) : parseFloat(origin);
},
parseTransformString = function (a){ // helper function that turns transform value from string to object
var d = a && /\)/.test(a) ? a.substring(0, a.length-1).split(/\)\s|\)/) : 'none', c = {};
if (d instanceof Array) {
for (j=0; j<d.length; j++){
p = d[j].split('('); p[0] !== '' && (c[p[0].replace(/\s/,'')] = p[1] );
for (var j=0, jl = d.length; j<jl; j++){
var p = d[j].trim().split('('); c[p[0]] = p[1];
}
}
return c;
},
translateSVG = g.Interpolate.translateSVG = function (s,e,a,b,v){ // translate(i+'(',')',a[i],b[i],v)
return s + ( (a[1] === b[1] && b[1] === 0 ) ? ((number(a[0],b[0],v) * 10 >> 0)/10)
: (((number(a[0],b[0],v) * 10 >> 0)/10) + ' ' + ((number(a[1],b[1],v)) *10 >> 0)/10) ) + e;
},
rotateSVG = g.Interpolate.rotateSVG = function (s,e,a,b,v){
return s + ( (number(a[0],b[0],v)*10 >> 0)/10 + ' ' + b[1] + ',' + b[2] ) + e;
},
scaleSVG = g.Interpolate.scaleSVG = function (s,e,a,b,v){ // scale would very much like to have 3 decimals
return s + ( (number(a,b,v)*1000 >> 0)/1000 ) + e;
},
skewSVG = g.Interpolate.skewSVG = function (s,e,a,b,v){ // skew
return s + ( (number(a,b,v)*10 >> 0)/10 ) + e;
parseTransformObject = function(v){
var svgTransformObject = {}, bb = this.element.getBBox(),
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, // by default the transformOrigin is "50% 50%" of the shape box
origin = this.options.transformOrigin, translation;
origin = !!origin ? (origin instanceof Array ? origin : origin.split(/\s/)) : [cx,cy];
origin[0] = typeof origin[0] === 'number' ? origin[0] : parseStringOrigin(origin[0],bb);
origin[1] = typeof origin[1] === 'number' ? origin[1] : parseStringOrigin(origin[1],bb);
svgTransformObject.origin = origin;
for ( var i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
svgTransformObject[i] = typeof v[i] === 'number' ? v[i] : v[i] instanceof Array ? v[i][0] : v[i].split(/\s/)[0]*1;
} else if (i === 'translate'){
translation = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(',') : [v[i],0];
svgTransformObject[i] = [translation[0]*1||0, translation[1]*1||0];
} else if (/skew/.test(i)) {
svgTransformObject[i] = v[i]*1||0;
} else if (i === 'scale'){
svgTransformObject[i] = parseFloat(v[i])||1;
}
}
return svgTransformObject;
};
parseProperty.svgTransform = function(p,v){
// register the render function
if (!('svgTransform' in DOM)) {
DOM.svgTransform = function(l,p,a,b,v){
l.setAttribute('transform', ('translate' in a ? translateSVG('translate(',')',a.translate,b.translate,v) : '')
+('rotate' in a ? rotateSVG('rotate(',')',a.rotate,b.rotate,v) : '')
+('scale' in a ? scaleSVG('scale(',')',a.scale,b.scale,v) : '')
+('skewX' in a ? skewSVG('skewX(',')',a.skewX,b.skewX,v) : '')
+('skewY' in a ? skewSVG('skewY(',')',a.skewY,b.skewY,v) : ''));
var x = 0, y = 0, tmp, deg = Math.PI/180,
scale = 'scale' in b ? number(a.scale,b.scale,v) : 1,
rotate = 'rotate' in b ? number(a.rotate,b.rotate,v) : 0,
sin = Math.sin(rotate*deg), cos = Math.cos(rotate*deg),
skewX = 'skewX' in b ? number(a.skewX,b.skewX,v) : 0,
skewY = 'skewY' in b ? number(a.skewY,b.skewY,v) : 0,
complex = rotate||skewX||skewY||scale!==1 || 0;
// start normalizing the translation, we start from last to first (from last chained translation)
// the normalized translation will handle the transformOrigin tween option and makes sure to have a consistent transformation
x -= complex ? b.origin[0] : 0; y -= complex ? b.origin[1] : 0; // we start with removing transformOrigin from translation
x *= scale; y *= scale; // we now apply the scale
y += skewY ? x*Math.tan(skewY*deg) : 0; x += skewX ? y*Math.tan(skewX*deg) : 0; // now we apply skews
tmp = cos*x - sin*y; // apply rotation as well
y = rotate ? sin*x + cos*y : y; x = rotate ? tmp : x;
x += 'translate' in b ? number(a.translate[0],b.translate[0],v) : 0; // now we apply the actual translation
y += 'translate' in b ? number(a.translate[1],b.translate[1],v) : 0;
x += complex ? b.origin[0] : 0; y += complex ? b.origin[1] : 0; // normalizing ends with the addition of the transformOrigin to the translation
// finally we apply the transform attribute value
l.setAttribute('transform',
( x||y ? ('translate(' + (x*10>>0)/10 + ( y ? (',' + ((y*10>>0)/10)) : '') + ')') : '' )
+( rotate ? 'rotate(' + (rotate*10>>0)/10 + ')' : '' )
+( skewX ? 'skewX(' + (skewX*10>>0)/10 + ')' : '' )
+( skewY ? 'skewY(' + (skewY*10>>0)/10 + ')' : '' )
+( scale !== 1 ? 'scale(' + (scale*1000>>0)/1000 +')' : '' ) );
}
}
// now prepare transform
var svgTransformObject = {}, bb = this.element.getBBox(), cx = bb.x + bb.width/2, cy = bb.y + bb.height/2, r, cr, t, ct;
for ( i in v ) { // populate the valuesStart and / or valuesEnd
if (i === 'rotate'){
r = v[i] instanceof Array ? v[i]
: /\s/.test(v[i]) ? [v[i].split(' ')[0]*1, v[i].split(' ')[1].split(',')[0]*1, v[i].split(' ')[1].split(',')[1]*1]
: [v[i]*1,cx,cy];
svgTransformObject[i] = r;
} else if (i === 'translate'){
t = v[i] instanceof Array ? v[i] : /\,|\s/.test(v[i]) ? v[i].split(/\,|\s/) : [v[i]*1,0];
svgTransformObject[i] = [t[0] * 1||0, t[1] * 1||0];
} else if (i === 'scale'){
svgTransformObject[i] = v[i] * 1||1;
} else if (/skew/.test(i)) {
svgTransformObject[i] = v[i] * 1||0;
}
}
// try to adjust translation when scale is used, probably we should do the same when using skews, but I think it's a waste of time
// http://www.petercollingridge.co.uk/interactive-svg-components/pan-and-zoom-control
if ('scale' in svgTransformObject) {
!('translate' in svgTransformObject) && ( svgTransformObject['translate'] = [0,0] ); // if no translate is found in current value or next value, we default to 0
svgTransformObject['translate'][0] += (1-svgTransformObject['scale']) * bb.width/2;
svgTransformObject['translate'][1] += (1-svgTransformObject['scale']) * bb.height/2;
// adjust rotation transform origin and translation when skews are used, to make the animation look exactly the same as if we were't using svgTransform
// http://stackoverflow.com/questions/39191054/how-to-compensate-translate-when-skewx-and-skewy-are-used-on-svg/39192565#39192565
if ('rotate' in svgTransformObject) {
svgTransformObject['rotate'][1] -= 'skewX' in svgTransformObject ? Math.tan(svgTransformObject['skewX']) * bb.height : 0;
svgTransformObject['rotate'][2] -= 'skewY' in svgTransformObject ? Math.tan(svgTransformObject['skewY']) * bb.width : 0;
}
svgTransformObject['translate'][0] += 'skewX' in svgTransformObject ? Math.tan(svgTransformObject['skewX']) * bb.height*2 : 0;
svgTransformObject['translate'][1] += 'skewY' in svgTransformObject ? Math.tan(svgTransformObject['skewY']) * bb.width*2 : 0;
} // more variations here https://gist.github.com/thednp/0b93068e20adb84658b5840ead0a07f8
return svgTransformObject;
return parseTransformObject.call(this,v);
}
// returns an obect with current transform attribute value
prepareStart.svgTransform = function(p,t) {
var tr = {}, i, ctr = parseTransform(this.element.getAttribute('transform'));
for (i in t) { tr[i] = i in ctr ? ctr[i] : (i==='scale'?1:0); } // find a value in current attribute value or add a default value
return tr;
var transformObject = {}, currentTransform = parseTransformString(this.element.getAttribute('transform'));
for (var i in t) { transformObject[i] = i in currentTransform ? currentTransform[i] : (i==='scale'?1:0); } // find a value in current attribute value or add a default value
return transformObject;
}
crossCheck.svgTransform = function() { // helper function that helps preserve current transform properties into the objects
var bb = this.element.getBBox(), ctr = parseTransform(this.element.getAttribute('transform')), r, t, i,
cx = bb.x + bb.width/2, cy = bb.y + bb.height/2;
for ( i in ctr ) { // populate the valuesStart
if (i === 'translate'){
t = ctr[i] instanceof Array ? ctr[i] : /\,|\s/.test(ctr[i]) ? ctr[i].split(/\,|\s/) : [ctr[i]*1,0];
this.valuesStart.svgTransform[i] = [t[0] * 1||0, t[1] * 1||0];
} else if (i === 'scale'){
this.valuesStart.svgTransform[i] = ctr[i] * 1||1;
} else if (i === 'rotate'){
r = ctr[i] instanceof Array ? ctr[i]
: /\s/.test(ctr[i]) ? [ctr[i].split(' ')[0]*1, ctr[i].split(' ')[1].split(',')[0]*1, ctr[i].split(' ')[1].split(',')[1]*1]
: [ctr[i]*1,cx,cy];
this.valuesStart.svgTransform[i] = r;
} else if (/skew/.test(i)) {
this.valuesStart.svgTransform[i] = ctr[i] * 1||0;
}
var valuesStart = this.valuesStart.svgTransform, valuesEnd = this.valuesEnd.svgTransform,
currentTransform = parseTransformObject.call(this, parseTransformString(this.element.getAttribute('transform')) );
for ( var i in currentTransform ) { // populate the valuesStart first
valuesStart[i] = currentTransform[i];
}
for (var i in this.valuesStart.svgTransform) {
if (!(i in this.valuesEnd.svgTransform)) { // copy existing and unused properties to the valuesEnd
this.valuesEnd.svgTransform[i] = this.valuesStart.svgTransform[i];
}
if (i === 'rotate' in this.valuesStart.svgTransform && 'rotate' in this.valuesEnd.svgTransform){ // make sure to use the right transform origin when rotation is used
this.valuesEnd.svgTransform.rotate[1] = this.valuesStart.svgTransform.rotate[1] = cx;
this.valuesEnd.svgTransform.rotate[2] = this.valuesStart.svgTransform.rotate[2] = cy;
}
// now try to determine the REAL translation
var parentSVG = this.element.ownerSVGElement,
newTransform = parentSVG.createSVGTransformFromMatrix(
parentSVG.createSVGMatrix()
.translate(-valuesStart.origin[0],-valuesStart.origin[1]) // - origin
.translate(valuesStart.translate[0]||0,valuesStart.translate[1]||0) // the current translate
.rotate(valuesStart.rotate||0).skewX(valuesStart.skewX||0).skewY(valuesStart.skewY||0).scale(valuesStart.scale||1)// the other functions
.translate(+valuesStart.origin[0],+valuesStart.origin[1]) // + origin
);
valuesStart.translate = [newTransform.matrix.e,newTransform.matrix.f]; // finally the translate we're looking for
newTransform = null;
// copy existing and unused properties to the valuesEnd
for ( var i in valuesStart) {
if ( !(i in valuesEnd)) { valuesEnd[i] = valuesStart[i]; }
}
}

124
kute.js
View file

@ -15,7 +15,7 @@
// set a custom scope for KUTE.js
var g = typeof global !== 'undefined' ? global : window, time = g.performance,
tweens = [], tick = null;
tweens = [], tick = null; // tick must be null!!
//supported properties
var _colors = ['color', 'backgroundColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0)
@ -163,9 +163,9 @@
body = document.body, html = document.getElementsByTagName('HTML')[0],
scrollContainer = navigator && /webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? body : html,
_isIE = navigator && (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null) ? parseFloat( RegExp.$1 ) : false,
_isIE8 = _isIE === 8; // check IE8/IE
isIE = navigator && (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) !== null) ? parseFloat( RegExp.$1 ) : false,
isIE8 = isIE === 8, // check IE8/IE
isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // we optimize morph depending on device type
// KUTE.js INTERPOLATORS
var interpolate = g.Interpolate = {},
@ -180,12 +180,19 @@
for (c in b) { _c[c] = c !== 'a' ? (number(a[c],b[c],v)>>0 || 0) : (a[c] && b[c]) ? (number(a[c],b[c],v) * 100 >> 0 )/100 : null; }
return h ? rgbToHex( _c.r, _c.g, _c.b ) : !_c.a ? r + _c.r + cm + _c.g + cm + _c.b + ep : ra + _c.r + cm + _c.g + cm + _c.b + cm + _c.a + ep;
},
translate = interpolate.translate = function (a,b,u,v){
translate = interpolate.translate = isMobile ? function (a,b,u,v){
var translation = {};
for (var ax in b){
translation[ax] = ( a[ax]===b[ax] ? b[ax] : (a[ax] + ( b[ax] - a[ax] ) * v ) >> 0 ) + u;
}
return translation.x||translation.y ? 'translate(' + translation.x + ',' + translation.y + ')' :
'translate3d(' + translation.translateX + ',' + translation.translateY + ',' + translation.translateZ + ')';
} : function (a,b,u,v){
var translation = {};
for (var ax in b){
translation[ax] = ( a[ax]===b[ax] ? b[ax] : ( (a[ax] + ( b[ax] - a[ax] ) * v ) * 10 >> 0 ) /10 ) + u;
}
return translation.x ? 'translate(' + translation.x + ',' + translation.y + ')' :
return translation.x||translation.y ? 'translate(' + translation.x + ',' + translation.y + ')' :
'translate3d(' + translation.translateX + ',' + translation.translateY + ',' + translation.translateZ + ')';
},
rotate = interpolate.rotate = function (a,b,u,v){
@ -232,7 +239,7 @@
if (elapsed === 1) {
if (this.options.repeat > 0) {
if ( this.options.repeat < 9999 ) { this.options.repeat--; } else { this.options.repeat = 0; } // we have to make it stop somewhere, infinity is too damn much
if ( isFinite(this.options.repeat ) ) { this.options.repeat--; }
if (this.options.yoyo) { // handle yoyo
this.reversed = !this.reversed;
@ -261,11 +268,15 @@
// applies the transform origin and perspective
perspective = function () {
if ( this.options.perspective !== undefined && transformProperty in this.valuesEnd ) { this.valuesStart[transformProperty]['perspective'] = this.valuesEnd[transformProperty]['perspective']; } // element perspective
if ( this.options.transformOrigin !== undefined ) { this.element.style[property('transformOrigin')] = this.options.transformOrigin; } // element transform origin
if ( this.options.perspectiveOrigin !== undefined ) { this.element.style[property('perspectiveOrigin')] = this.options.perspectiveOrigin; } // element perspective origin
if ( this.options.parentPerspective !== undefined ) { this.element.parentNode.style[property('perspective')] = this.options.parentPerspective + 'px'; } // parent perspective
if ( this.options.parentPerspectiveOrigin !== undefined ) { this.element.parentNode.style[property('perspectiveOrigin')] = this.options.parentPerspectiveOrigin; } // parent perspective origin
var el = this.element, ops = this.options;
if ( ops.perspective !== undefined && transformProperty in this.valuesEnd ) { // element perspective
this.valuesStart[transformProperty]['perspective'] = this.valuesEnd[transformProperty]['perspective'];
}
// element transform origin / we filter it out for svgTransform to fix the Firefox transformOrigin bug https://bugzilla.mozilla.org/show_bug.cgi?id=923193
if ( ops.transformOrigin !== undefined && (!('svgTransform' in this.valuesEnd)) ) { el.style[property('transformOrigin')] = ops.transformOrigin; }
if ( ops.perspectiveOrigin !== undefined ) { el.style[property('perspectiveOrigin')] = ops.perspectiveOrigin; } // element perspective origin
if ( ops.parentPerspective !== undefined ) { el.parentNode.style[property('perspective')] = ops.parentPerspective + 'px'; } // parent perspective
if ( ops.parentPerspectiveOrigin !== undefined ) { el.parentNode.style[property('perspectiveOrigin')] = ops.parentPerspectiveOrigin; } // parent perspective origin
},
// plugin connector objects
@ -278,7 +289,7 @@
boxModel : function(p,v){
if (!(p in DOM)){
DOM[p] = function(l,p,a,b,v){
l.style[p] = ( v > 0.99 || v < 0.01 ? ((number(a,b,v)*10)>>0)/10 : (number(a,b,v) ) >> 0 ) + 'px' ;
l.style[p] = ( v > 0.99 || v < 0.01 ? ((number(a,b,v)*10)>>0)/10 : (number(a,b,v) ) >> 0 ) + 'px';
}
}
var boxValue = trueDimension(v);
@ -288,10 +299,10 @@
if (!(transformProperty in DOM)) {
DOM[transformProperty] = function(l,p,a,b,v,o){
l.style[p] = (a.perspective||'')
+ (a.translate ? translate(a.translate,b.translate,'px',v):'')
+ (a.rotate ? rotate(a.rotate,b.rotate,'deg',v):'')
+ (a.skew ? skew(a.skew,b.skew,'deg',v):'')
+ (a.scale ? scale(a.scale,b.scale,v):'');
+ ('translate' in a ? translate(a.translate,b.translate,'px',v):'')
+ ('rotate' in a ? rotate(a.rotate,b.rotate,'deg',v):'')
+ ('skew' in a ? skew(a.skew,b.skew,'deg',v):'')
+ ('scale' in a ? scale(a.scale,b.scale,v):'');
}
}
@ -342,7 +353,7 @@
};
} else if (p === 'opacity') {
if (!(p in DOM)) {
if (_isIE8) {
if (isIE8) {
DOM[p] = function(l,p,a,b,v) {
var st = "alpha(opacity=", ep = ')';
l.style.filter = st + ((number(a,b,v) * 100)>>0) + ep;
@ -366,7 +377,7 @@
}
},
// process properties for _vE and _vS or one of them
// process properties for endValues and startValues or one of them
preparePropertiesObject = function(obj, fn) { // this, props object, type: start/end
var element = this.element, propertiesObject = fn === 'start' ? this.valuesStart : this.valuesEnd,
skewObject = {}, rotateObject = {}, translateObject = {}, transformObject = {};
@ -471,7 +482,7 @@
}
} else {
if ( p !== 'scroll' ) {
if (p === 'opacity' && _isIE8 ) { // handle IE8 opacity
if (p === 'opacity' && isIE8 ) { // handle IE8 opacity
var currentOpacity = getCurrentStyle(this.element,'filter');
startValues['opacity'] = typeof currentOpacity === 'number' ? currentOpacity : _defaults['opacity'];
} else {
@ -486,7 +497,7 @@
}
}
}
for ( var p in currentStyle ){ // also add to _vS values from previous tweens
for ( var p in currentStyle ){ // also add to startValues values from previous tweens
if ( _transform.indexOf(p) !== -1 && (!( p in this.valuesStart )) ) {
startValues[p] = currentStyle[p] || _defaults[p];
}
@ -571,8 +582,8 @@
easing.easingBounceInOut = function(t) { if ( t < 0.5 ) return easing.easingBounceIn( t * 2 ) * 0.5; return easing.easingBounceOut( t * 2 - 1 ) * 0.5 + 0.5;};
// single Tween object construct
var Tween = function (_el, _vS, _vE, _o) {
this.element = 'scroll' in _vE && (_el === undefined || _el === null) ? scrollContainer : _el; // element animation is applied to
var Tween = function (targetElement, startObject, endObject, options) {
this.element = 'scroll' in endObject && (targetElement === undefined || targetElement === null) ? scrollContainer : targetElement; // element animation is applied to
this.playing = false;
this.reversed = false;
@ -582,15 +593,15 @@
this._pauseTime = null;
this._startFired = false;
this.options = {}; for (var o in _o) { this.options[o] = _o[o]; }
this.options.rpr = _o.rpr || false; // internal option to process inline/computed style at start instead of init true/false
this.options = {}; for (var o in options) { this.options[o] = options[o]; }
this.options.rpr = options.rpr || false; // internal option to process inline/computed style at start instead of init true/false
this.valuesRepeat = {}; // internal valuesStartRepeat
this.valuesEnd = {}; // valuesEnd
this.valuesStart = {}; // valuesStart
preparePropertiesObject.call(this,_vE,'end'); // valuesEnd
if ( _o.rpr ) { this.valuesStart = _vS; } else { preparePropertiesObject.call(this,_vS,'start'); } // valuesStart
preparePropertiesObject.call(this,endObject,'end'); // valuesEnd
if ( options.rpr ) { this.valuesStart = startObject; } else { preparePropertiesObject.call(this,startObject,'start'); } // valuesStart
if ( this.options.perspective !== undefined && transformProperty in this.valuesEnd ) { // element transform perspective
var perspectiveString = 'perspective('+parseInt(this.options.perspective)+'px)';
@ -598,20 +609,21 @@
}
for ( var e in this.valuesEnd ) {
if (e in crossCheck && !_o.rpr) crossCheck[e].call(this); // this is where we do the valuesStart and valuesEnd check for fromTo() method
if (e in crossCheck && !options.rpr) crossCheck[e].call(this); // this is where we do the valuesStart and valuesEnd check for fromTo() method
}
this.options.chain = []; // chained Tweens
this.options.easing = _o.easing && typeof processEasing(_o.easing) === 'function' ? processEasing(_o.easing) : easing.linear;
this.options.repeat = _o.repeat || 0;
this.options.repeatDelay = _o.repeatDelay || 0;
this.options.yoyo = _o.yoyo || false;
this.options.duration = _o.duration || 700; // duration option | default
this.options.delay = _o.delay || 0; // delay option | default
this.options.easing = options.easing && typeof processEasing(options.easing) === 'function' ? processEasing(options.easing) : easing.linear;
this.options.repeat = options.repeat || 0;
this.options.repeatDelay = options.repeatDelay || 0;
this.options.yoyo = options.yoyo || false;
this.options.duration = options.duration || 700; // duration option | default
this.options.delay = options.delay || 0; // delay option | default
this.repeat = this.options.repeat; // we cache the number of repeats to be able to put it back after all cycles finish
},
// tween control and chain
TweenProto = Tween.prototype = {
// queue tween object to main frame update
start : function (t) { // move functions that use the ticker outside the prototype to be in the same scope with it
scrollIn.call(this);
@ -653,7 +665,7 @@
if (!this.paused && this.playing) {
remove(this);
this.paused = true;
this._pauseTime = (time.now() * 1000 >> 0) / 1000;
this._pauseTime = time.now();
if (this.options.pause) { this.options.pause.call(); }
}
return this;
@ -681,19 +693,19 @@
// the multi elements Tween constructs
TweensTO = function (els, vE, o) { // .to
this.tweens = []; var _o = [];
this.tweens = []; var options = [];
for ( var i = 0, tl = els.length; i < tl; i++ ) {
_o[i] = o || {}; o.delay = o.delay || 0;
_o[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
this.tweens.push( to(els[i], vE, _o[i]) );
options[i] = o || {}; o.delay = o.delay || 0;
options[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
this.tweens.push( to(els[i], vE, options[i]) );
}
},
TweensFT = function (els, vS, vE, o) { // .fromTo
this.tweens = []; var _o = [];
this.tweens = []; var options = [];
for ( var i = 0, l = els.length; i < l; i++ ) {
_o[i] = o || {}; o.delay = o.delay || 0;
_o[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
this.tweens.push( fromTo(els[i], vS, vE, _o[i]) );
options[i] = o || {}; o.delay = o.delay || 0;
options[i].delay = i>0 ? o.delay + (o.offset||0) : o.delay;
this.tweens.push( fromTo(els[i], vS, vE, options[i]) );
}
},
ws = TweensTO.prototype = TweensFT.prototype = {
@ -712,30 +724,28 @@
},
// main methods
to = function (el, to, o) {
var _el = selector(el); o = o || {}; o.rpr = true;
return new Tween(_el, to, to, o);
to = function (element, endObject, options) {
options = options || {}; options.rpr = true;
return new Tween(selector(element), endObject, endObject, options);
},
fromTo = function (el, f, to, o) {
var _el = selector(el); o = o || {};
return new Tween(_el, f, to, o);
fromTo = function (element, startObject, endObject, options) {
options = options || {};
return new Tween(selector(element), startObject, endObject, options);
},
// multiple elements tweening
allTo = function (els, to, o) {
var _els = selector(els,true);
return new TweensTO(_els, to, o);
allTo = function (elements, endObject, options) {
return new TweensTO(selector(elements,true), endObject, options);
},
allFromTo = function (els, f, to, o) {
var _els = selector(els,true);
return new TweensFT(_els, f, to, o);
allFromTo = function (elements, f, endObject, options) {
return new TweensFT(selector(elements,true), f, endObject, options);
};
return { // export core methods to public for plugins
property: property, getPrefix: getPrefix, selector: selector, processEasing : processEasing, // utils
to: to, fromTo: fromTo, allTo: allTo, allFromTo: allFromTo, // main methods
ticker : ticker, tweens : tweens, update: update, dom : DOM, // update
ticker : ticker, tick : tick, tweens : tweens, update: update, dom : DOM, // update
parseProperty: parseProperty, prepareStart: prepareStart, crossCheck : crossCheck, Tween : Tween, // property parsing & preparation | Tween | crossCheck
truD: trueDimension, truC: trueColor, rth: rgbToHex, htr: hexToRGB, getCurrentStyle: getCurrentStyle, // property parsing
};
}));
}));

View file

@ -1,6 +1,6 @@
{
"name": "kute.js",
"version": "1.5.99",
"version": "1.6.0",
"description": "Complete Native Javascript animation engine.",
"main": "kute.js",
"scripts": {