diff --git a/README.md b/README.md index 6888e2d..d059838 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # kute.js -A minimal native Javascript tweening engine with jQuery plugin, forked from tween.js. Since most of web developers don't actually use `yoyo`, `repeat`, `play`/`pause`/`resume`/`timeline`/whatever or tweening array values (processed with array interpolation functions), I've removed them, for simplicity and performance. +A minimal native Javascript tweening engine with jQuery plugin, forked from tween.js with most essential options for web developers, designers and animators. Unlike the original script, KUTE.js delivers easy to use methods to set up high performance animations on the fly. kute.js is like a merge of my own jQueryTween with tween.js, but generally it's a much more smarter build. You link the script at your ending </body> tag and write one line to do just about any animation you can think of. @@ -12,10 +12,10 @@ Thanks to jsdelivr, we have CDN link demo. #jQuery Plugin -That's right, there you have it, just a few bits of code to bridge the awesome `kute.js` to your jQuery powered projects/apps. The plugin can be found in the [/dist](https://github.com/thednp/kute.js/blob/master/dist/kute.jquery.js) folder. +That's right, there you have it, just a few bits of code to bridge the awesome `kute.js` to your jQuery powered projects/apps. The plugin can be found in the [/dist](https://github.com/thednp/kute.js/blob/master/dist/kute-jquery.min.js) folder. # What else it does * computes option values properly according to their measurement unit (px,%,deg,etc) @@ -90,18 +49,14 @@ That's right, there you have it, just a few bits of code to bridge the awesome ` * it converts `RGBA` & `HEX` colors to `RGB` and tweens the inner values, then ALWAYS updates color via `HEX`; no support for `RGBA` * properly replaces `top`, `centered` or any other background position with proper value to be able to tween * for most supported properties it reads the current element style property value as initial value (via `currentStyle || getComputedStyle`) -* allows you to add 3 different callbacks: `start`, `special`, `finish`, and they can be set as tween options (so no more nested functions are invoked as object attributes) +* allows you to add many callbacks: `start`, `update`, `complete`, `pause`, `stop`, and they can be set as tween options (so no more nested functions are invoked as object attributes) * since `translate3D` is best for performance, `kute.js` will always uses it * accepts "nice & easy string" easing functions, like `linear` or `exponentialOut` (removes the use of the evil `eval`, making development, safer easier and closer to development standards :) -* uses 31 easing functions, all Robert Penner's easing equations -* like mentioned above, for IE8 `zoom` is used for `transform: scale(0.5)`, it's not perfect as the object moves from it's floating point to the middle, and some left & top adjustments can be done, but to keep it simple and performance driven, I leave it as is, it's better than nothing. -* generally it's using for `-webkit-` prefix for Safari and older webkit browsers for CSS powered transitions. +* uses 31 easing functions, all Robert Penner's easing equations and 2 more libraries +* generally it's doing browser prefixes for you as well. # Browser Support -Since most modern browsers can handle pretty much everything, legacy browsers need some help, so give them polyfills.io. Also `kute.js` needs to know when doing stuff for IE9- like my other scripts here, I highy recommend Paul Irish's conditional stylesheets guides to add ie ie[version] to your site's HTML tag. - -# Demo -coming soon.. +Since most modern browsers can handle pretty much everything, legacy browsers need some help, so give them polyfills.io. Also `kute.js` needs to know when doing stuff for IE9- like my other scripts here, I highy recommend Paul Irish's conditional stylesheets guides to add ie ie[version] to your site's HTML tag. # License MIT License diff --git a/demo/about.html b/demo/about.html new file mode 100644 index 0000000..907e3f0 --- /dev/null +++ b/demo/about.html @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + About KUTE.js | Javascript Animation Engine + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

Did you know?

+

Tween is a term used by animators and software engineers to define the numeric start, end and the inbetween values used in digital animation, while the digital animation uses these tween values on a given frequency (interval) or scaled by hardware capability (monitors refresh rate, GPU frames per second, etc). The term was introduced to the world of web development by early Javascrpt libraries and later used in dedicated animation libraries such as GSAP, Dynamics, Velocity, Shifty, our own KUTE.js here and many others.

+

Tween Object is a Javascript Object that stores temporarily or for a given time a set of variables such as tween values, HTML elements to animate, CSS properties and other tween options to be used for animation. To improve performance on repetitive animations, this object can be cached and reused whenever needed. In Javascript animation, the term tween actually refers to the tween object.

+

polyfill is a term introduced by Remy Sharp back in 2009 as "a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively". Basically a polyfill covers what legacy browsers don't support or in other cases corrects the implemented behavior that is different from the standards. More details.

+

requestAnimationFrame is a Javascript method developed to enable hardware acceleration animations for the web today. In Javascript, the window.requestAnimationFrame(callback); method is all we need to setup animations really for all the above mentioned animation engines. Some developers built a polyfil to cover the legacy browsers chaos.

+

JANK is a term used when browsers miss frames due to long script execution and/or long layout recomposition. JANK is the phenomenon reffering to severe frame drops. Luckily there are people who explain all about it, so you don't have to stay in the dark.

+

Methods are functions that create tween objects or control the animation for KUTE.js, so we will encounter mostly main methods and tween control methods. Once a main method is used, then the control methods apply in a specific order.

+ + +

How Does It Work?

+

Well, first things first: it's smart built. Let's briefly explain the phases:

+
    +
  1. On first initialization KUTE.js creates some variables such as supported properties and their default values, the user's browser prefix, the true scroll container (some browsers actually scroll the body, while others prefer the HTML tag), a boolean variable that makes KUTE.js aware it's working with IE8, as well as other variables required during the main thread. This phase is very important for the performance on the next phases.
  2. +
  3. In the next phase it's going to build the tween object with the chosen method according to it's distinct functionalities. If the chosen method is .to() KUTE.js will look for the current values of the properties used or assign the default values built in the previous phase. For both methods, KUTE.js collects all the data, processes values and options (for instance easing functions need to be processed if you use a string like 'easingElasticOut', right?) and builds the tween object, with all properties' values start and values end, measurement units, tween options and callback functions.
  4. +
  5. In the third phase KUTE.js is ready to start the animation, but the animation starts only after the .start() function, if used, has finished. When animation starts, KUTE.js will start ticking on the frequency decided by requestAnimationFrame or setInterval for legacy browsers, quickly updating the style for the properties and execute the update:function callback if any. Also while animating, KUTE.js will begin listening for your tween control input such as .pause() or .stop() or any other. Also, when a certain tween control method is used, KUTE.js will execute it's specific callback, if used.
  6. +
  7. When tween animation is finished, the complete:function callback function is executed and then KUTE.js starts the animation for any chained tween, or else will stop ticking with cancelAnimationFrame to save power.
  8. +
+

Basically, this is it!

+ +

A Word On Performance

+

As said before, performance varies from case to case; this chapter aims to explain what you should expect working with animation engines in these various scenarios at maximum stress, usually when your CPU cooler starts to work really hard, and how scalable performance can really be on various machines, operating systems or mobile devices.

+ +

Translate and Position

+

While the code execution is the fastest for the layout modifiers or what we call box-model, say the position based properties set such as left or top, they may force the entire page layout to change and thus requires the browser to repaint all elements affected by animated repositioning and their parent elements. On the other side translate doesn't trigger a repaint but involves more complex operations such as object traversing, string concatenation or check for certain conditions to be met. All of this is because translate is part of transform CSS3 property that has to stack in a single line many more properties such as rotate, skew and scale. An article by Paul Irish explains more about differences in performance between position and translation.

+ +

I would stress on this a bit: even faster performance for translation can be achieved by using an improved version of the tiny tween.js, as it only tweens the values and allows you to concatenate strings as you please. On large amounts of elements translating on vertical or horizontal axis, tween.js would be the best of them all, but well, we'll see about that in the performance testing page.

+ +

To put it short left executes faster but requires repaint on every frame while translateX or translate3d execute slower but require no repaint on each animation frame. The winner is left, when it comes to code execution, but if we also count the elements' size, the larger size the more favor the translation so the overall winner is translate. With other words the more pixels to recompose in the layout, the more time spent on each frame, and this is why translation is better in most cases, and animated positioning is best to be used as fallback animation for legacy browsers.

+ +

Translate, TranslateX and Translate3D

+

While running a 2D translate:150 animation could score similar performance as translateX:150, interestingly, translate3d:[150,0,0] is slightly faster than the other translations. Some performance tests confirm that translate3d is the prefered property for hardware acceleration. For this reason, translate3d is the winner and KUTE.js always uses it even if you only use translateX or translateY for instance.

+

Similarly, if you animate the 2D translate this always goes translate(x,y) even if you use translate:150 (only for the X axis) or translate:[150,0] (both X and Y axis), for better performance as well. And by the way, this works great on IE9 and other legacy browsers.

+ +

Box Model

+

We compared position with transition above, but now we are going to talk about other issues related to resizers: width, height, margin, padding and borderWidth or any of their variations. The code execution is super fast, but when resizing the window while animations are running, the browser is also computing the resize handlers, the animation performance is very very low on all browsers, especially when you animate these resize properties. When this toxic combination occurs animating a large amount of elements to animate could crash any browser, no exception, and I think any developer should know about this.

+

The resize event triggered by these resizer properties can cause some severe issues with legacy browsers such as IE8. These good old browsers don't understand much about Javascript driven layout changes and thus skip/fail to execute any handlers attached to window resize event bubbles.

+

A workaound the resizers effect on the layout would be to use them only for absolute positioned elements, this way the layout will not need to be repainted and the recomposition is limited to the element itself. If not, and you are required to provide legacy support, you must DISABLE any resize handlers for IE8 and any other browser that runs slow or crashes. You should also consider not using any resize animation for legacy browsers especially when usability and larger reach is expected.

+ +

RGB and HEX

+

When animating any color property such as (text) color or background-color, KUTE.js always uses/converts to RGB/RGBA, but there is a keepHex:true tween option that overrides that. Still some browsers such as Chrome will still show you the computed style for your color as RGB no matter what. The conversion process will decrease performance, making RGB the winner.

+ +

TO and FROMTO

+

The two main methods for creating animation setups (tween objects) that are coming with KUTE.js are .to() and .fromTo(). While .to() is much more simple and convenient to use, very useful for tween chaining, it has to process the starting values on every .start() delaying the animation for a few miliseconds depending on the browser and hardware, making .fromTo() the winner. On a large amount of elements animating at the same time, these scripting based delays can produce some serious syncronization issues, so caution is advised. In that case you should use .fromTo() properly.

+ +

Easing Functions

+

KUTE.js comes with 3 packs of easing functions: the popular easing functions by Robert Penner, dynamics physics easing functions by Michael Villar and bezier-easing by Gaëtan Renaudeau. I've worked very hard to optimize the last 2 as much as possible, but they will never beat Robert Penner's functions in any performance test, that's an all time winner.

+

The point here is that the more accuracy a function offers, the more power needed, and the result is less performance. For instance the cubic-bezier based functions have a 0.0000001 error margin, while the Exponential easing functions by Robert Penner are somewhat glitchy on long page scrolls or translations. Interestingly, some physics based functions perform exceedingly well, and generally the difference in performance is fairly negligible even for large amounts of elements, and have no impact on very few elements.

+ +

Garbage Collection And Repeat

+

The goal of the development strategy is to be able to execute the script, update layout and repaint, all under 16 miliseconds, so that the animation runs constantly at 60fps. However running some repeatable animations for a large amount of elements would really give garbage collectors a lot of work and thus some frames take more than 16 miliseconds. The more properties and/or elements, the more work.

+

While garbage collection is a great way modern browsers use to clean the memory, sometimes the garbage collector can jump in anytime, cousing drops in the order of miliseconds. Still, if it's the case, there are ways to help composing the layout faster, but we will see that in the performance testing page.

+ +

OSs, Desktops and Mobiles

+

The performance tests have been performed mainly on Microsoft Windows 8.1 and Ubuntu Linux 14.04 Trusty Tahr with latest nVidia graphics drivers on both OSs, all set up for maximum performance. The browsers are obviously Firefox (both OSs), Google Chrome (both OSs), Opera (both OSs) and IE11 (Win8).

+

The results show Windows based browsers came better than Ubuntu based ones, mainly because of DirectX and better drivers that greatly improve hardware accelerated graphics, while Linux still faces some noticeable issues with vertical sync among many others, but hey it's a work in progress and it's open source!

+ +

The browsers' performance goes like this (from best to poorest): Google Chrome, Opera, Internet Explorer, Firefox. Yes, Firefox is the slowest on Windows OS. I never tested anything on iOS or MAC-OS but I believe Safari performs very well with transforms. Some argue that Safari outperforms Google Chrome due to the latest Webkit upgrade.

+ +

Also know that legacy browsers don't support requestAnimationFrame and pollyfills usually replace it with setInterval, a clasic Javascript method that's significantly affecting performance, because it's one of the main causes for lots of JANK.

+ +

Another important aspect as far as performance goes, the power saving profiles on Windows OS drops performance for desktop computers and especally laptops. Also when a laptop is unplugged, Windows automatically changes power profile drastically decreasing performance.

+ +

As for the mobiles, you must know that even if you have an octacore CPU powered phone or tablet is never going to match a desktop and not even a laptop. For a mobile device these guys recommend to keep everything under 7 miliseconds for the smooth experience that most users expect and that the animation performance of a phone is actually up to 5 times lower than a desktop or laptop. I would stress that having 2 or 3 simoultaneous animations on a phone at a certain point is just about enough.

+ +

Another thing to keep in mind is that scrollling on a mobile device is actually hardware accelerated animation and thus compete for power drastically reducing performance for any other CSS or Javascript driven animations. To understand how critical performance is on a mobile device, I highly recommend checking the Google I/O 2014 presentation. Now you understand how much performance really matters.

+

Remember: do not open any Javascript animation engine performance test with your phone, you may burn your battery, espectially if it's unpluggable.

+ +

KUTE.js Project

+

KUTE.js continues what was started with jQueryTween 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.

+

It all started with a fork of the popular tween.js and ended up having a KUTE.js version 0.9.5 that's almost as good as the boss, GSAP, at least in terms of performance and browser support. TweenMax have been an outstanding source of wonderful coding practices, a true inspiration for the entire developers' community, not to mention the huge contribution and knowledge sharing.

+

In the hystory of the making there were consistent contributions of Dav aka @dalisoft for features such as play & pause, 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.

+

Also I would like to thank Ingwie Phoenix for the npm/Bower and UMD implementations.

+ + +
+ + + + +
+ + + + + + + + diff --git a/demo/api.html b/demo/api.html new file mode 100644 index 0000000..08df62d --- /dev/null +++ b/demo/api.html @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + KUTE.js Developer API | Javascript Animation Engine + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

Getting Started

+

Welcome to KUTE.js API documentation, here we're going to talk about how to download, install, use, control and set up cross browser animations, in great detailed. KUTE.js can be found on CDN and also npm and Bower repositories with all it's features and tools.

+ +

Bower and NPM

+

You can install KUTE.js package by using either Bower or NPM.

+
$ npm install --save kute.js
+# Or
+$ bower install --save kute.js
+
+ +

Websites

+

In your website add the following code, the best would be to put it at the end of your body tag:

+
<script src="https://cdn.jsdelivr.net/kute.js/0.9.5/kute.min.js"></script> <!-- core KUTE.js -->
+ +

Also you can include the tools that you need for your project:

+
<script src="https://cdn.jsdelivr.net/kute.js/0.9.5/kute-jquery.min.js"></script> <!-- jQuery Plugin -->
+<script src="https://cdn.jsdelivr.net/kute.js/0.9.5/kute-easing.min.js"></script> <!-- Bezier Easing Functions -->
+<script src="https://cdn.jsdelivr.net/kute.js/0.9.5/kute-physics.min.js"></script> <!-- Physics Easing Functions -->
+
+

Your awesome animation coding would follow after these script links.

+ +

Ideal HTML Template

+

You need to know when users' browser is a legacy one in order to use KUTE.js only for what browsers can actually do. A quick note here: IE8 doesn't support any transform property or RGBA colors while IE9 can only do 2D transformations. Check the 2D transforms and the 3D transforms browser support list for more information.

+

Don't use Modernizr, the best thing we can actually do is use the Microsoft's synthax for it's own legacy browsers, so here's how a very basic HTML template for your websites would look like:

+
<!DOCTYPE html>
+	<!--[if lt IE 8]><html class="ie prehistory" lang="en"><![endif]-->			
+	<!--[if IE 8]><html class="ie ie8" lang="en"><![endif]-->			
+	<!--[if IE 9]><html class="ie ie9" lang="en"><![endif]-->			
+	<!--[if !IE]><!--> <html lang="en"> <!--<![endif]-->				
+	<head>
+		<meta charset="utf-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1">				
+		<!-- SEO meta here  -->					
+		<!-- add your CSS here  -->				
+		<!-- add polyfills  -->
+		<script src="https://cdn.polyfill.io/v2/polyfill.js?features=default,getComputedStyle|gated"> </script>
+	</head>					
+	<body>
+		<!-- site content here -->	
+		<!-- scripts go here -->				
+	</body>
+</html>
+
+

For other legacy browsers there is a ton of ways to target them, quite efficiently I would say: there you go.

+
+ +
+

Main Methods

+

These methods allow you to create tween objects; here a tween object is essentially like an animation setup for a given HTML element, defining CSS properties, animation duration or repeat. The methods have different uses and performance scores while making it easy to work with.

+

.to() method is the most simple method which allows you to create tween objects for animating CSS properties from a specific default value OR from current/computed value TO a desired value. + It's performance is not the same as for the next two because it has to compute the default/current value on tween .start() and thus delays the animation for a cuple of miliseconds, but this feature is great for simple animations AND it has the ability to stack transform properties as they go, making smooth transform animations on chained tweens. See the .start() method for the solution for sync/delay issue.

+

Considering a given div element is already transparent, a super quick example would be:

+
KUTE.to(div,{opacity:1}).start()
+

.fromTo() method is the best way to build animations for BEST performance and absolute control. The tests prove this method to be the fastest methods but unlike the .to() method, it does not stack transform properties on chained tweens. Also, another advantage is the fact that you can set measurement units for both starting and end values, to avoid glitches. We've talked about this in the features page. So here's a quick example:

+
KUTE.fromTo(div,{opacity:1},{opacity:0}).start()
+

.Animate() method is only a fallback for the older KUTE.js versions and works as the .fromTo() method. It will be deprecated with later versions.

+
+ +
+

Tween Control Methods

+

These methods allows you to control when the animation starts or stops. Let's write a basic tween object to work with the methods:

+
var tween = KUTE.fromTo(div,{opacity:1},{opacity:0});
+

This tween object is now ready to work with the methods.

+ +

Starting Animations

+

.start() method starts animation for a given tween object. It can start the animation for both cached and non-cached objects. Unlike previous versions of KUTE.js, where animation started immediately after tween object creation, now you have to manually start them.

+
//cached object defined above
+tween.start();
+
+//non-cached object are created on the fly and garbage collected after animation has finised
+KUTE.fromTo(div,{opacity:1},{opacity:0}).start();
+
+//also start the tween at a certain time
+tween.start(now); // where now must be the current or future time as number, see below
+
+ +

As you can see, you can also set a time for the animation to start, example: tween.start(myTimeValue). Having access to the method is useful when starting animation for large amounts of elements with same properties at the same time because using it properly eliminates any syncronization issue that may occur, even if you are using the .to() method. This applies to our performance test page as well, and the trick is super duper simple:

+ +
// step 1 - create an empty array and grab the elements to animate
+var tweens = [], myElements = document.querySelector('.myManyElements');
+
+// step 2 - define tween objects for each element
+for (var i = 0; i < numberOfElements; i++) {
+	var tween = KUTE.fromTo(myElements[i], fromValues, toValues, options);
+	//now we populate the tweens array
+	tweens.push(tween);
+}
+
+// step 3 - calculate the right time to start
+// first we need the exact current time
+var now = window.performance.now(); // this returns the exact current time in numeric format
+
+// also we estimate/calculate an adjustment lag 
+// depending on the number of the elements AND hardware capability
+// maybe (numberOfElements / 16) would be an accurate value for PCs
+var lag = 100; // number of miliseconds for the script to built tween objects for all elements
+
+// step4 - we just start the animation for all elements at once
+for (var i = 0; i < numberOfElements; i++) {
+	tweens[i].start(now+lag);
+}
+
+ +

If you care to see the actual working code, check it in the perf.js file.

+ +

Stopping Animation

+

.stop() method stops animation for a given tween object while animating. You cannot stop the animation for tween objects created on the fly, only for cached objects. Let's assume that for the given tween we decide to stop the animation via click action:

+
stopButton.addEventListener('click', function(){
+	tween.stop();
+}, false);
+
+ +

Pausing Animation

+

.pause() method freezez the animation at any given time for a given tween object, and unlike the .stop() method, this one allows resuming the animation on a later use of the next method .play().

+
pauseButton.addEventListener('click', function(){
+	tween.pause();
+}, false);
+
+ +

Resuming Paused Animation

+

.play() or .resume() methods allows you to resume an animation for a given tween object only if it was paused or else will produce no effect.

+
playButton.addEventListener('click', function(){
+	tween.play(); // or tween.resume();
+}, false);
+
+ +

Chaining Tweens

+

.chain() method can be used to chain tweens together. When the animation finishes for a given tween, it triggers the animation start for another tween.

+
var tween2 = KUTE.fromTo(div,{left:50},{left:0});
+
+//the first tween chains the new tween
+tween.chain(tween2);
+
+//the new tween chains the first one creating a loop
+tween2.chain(tween);
+
+

It's also possible to chain multiple tweens, just as shown in the below example, but the one that finishes last (has longest delay and duration together) should be used last in the .chain() method arguments list. Why? Because when a tween is finished it triggers cancelAnimationFrame() and KUTE.js will stop "ticking" causing all other chained tweens to stop prematurelly.

+
//chain multiple tweens
+tween.chain(tween1,tween2);
+
+ + +
+ +
+

Tween Options

+

Common Options

+

These options affect all types of tweens, no matter the properties used or context.

+

duration: 500 option allows you to set the animation duration in miliseconds. The default value is 700.

+

repeat: 20 option allows you to run the animation of given tween multiple times. The default value is 0.

+

delay: 500 option allows you to schedule the tween animation after a certain number of miliseconds. The default value is 0.

+

repeatDelay: 500 option allows you to set a number of miliseconds delay between repeatable animations. If repeat option is set to 0, will produce no effect. The default value is 0.

+

yoyo: true/false option makes use of the internal reverse functionality to also animate from end to start for a given tween. This option requires that you use the repeat option with at least value 1. The default value is false.

+

easing: 'easingCubicInOut' option allows you to use a custom easing function for your animation. For more info on the easing functions, you need to see the example pages. The default value is linear.

+ +

Transform Options

+

These options only affect animation involving any property from CSS3 transform specs and have no effect on other CSS properties. While you can set perspective or perspective origin via CSS, these options are here to help, especially with full browser support and preffix free handling.

+

perspective: 500 option allows you to set a 3D transformation perspective for a given HTML element that is subject to transform animation. No default value.

+

perspectiveOrigin: "50% 50%" option allows you to set a perspectiveOrigin for a given HTML. This option has no default value and only accepts valid CSS values according to it's specs.

+

parentPerspective: 500 option allows you to set a 3D perspective for the parent of the HTML element subject to the transform animation.

+

parentPerspectiveOrigin: "50% 50%" option allows you to set a perspectiveOrigin 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.

+ +

Callback Options

+

These options also affect all types of tweens, and are bound by the tween control options and the internal update functions.

+

start: function option allows you to set a function to run once tween animation starts.

+

update: function option allows you to set a function to run on every frame.

+

pause: function option allows you to set a function to run when animation is paused.

+

resume: function option allows you to set a function to run when animation is resumed.

+

stop: function option allows you to set a function to run when animation is stopped.

+

complete: function option allows you to set a function to run when animation is finished.

+

A quick example would look like this:

+
//define a function
+var callback = function(){
+	//do some foo
+}
+
+//create object and start animating already
+KUTE.fromTo(div,{left:150},{left:0},{complete: callback}).start();
+
+

Other

+

keepHex: true option allows you to always use HEX color format, even if you have used RGB or RGBA. This option is useful when tweening color properties on legacy browsers, however modern browsers may ignore this option for performance reasons.

+
+ +
+

Easing Functions

+

The easing functions generally make animations closer to reality and completely eliminate the boring factor for a given context. The most simple example to understand what they do, think of gravity. Dropping an object from a given height, will start moving to the ground with accelerated speed. If the object has some sort of bounciness like a ball, it will jump back up and up again, till the gravity will eventually stick the object to the ground.

+

What scientists observed and put in theory houndreads of years ago, later the pioneers of scripting started to implement the laws of physics into digital animation and came up with this notion of easing to describe the progression of movement. If you care to dig into the concept, here's an excellent resource some developers recommend. I would also recommend this one too.

+ +

Core Functions

+

Modern browsers that support transition can also make use of some generic easing functions via the CSS3 transition-timing-function:ease-out property, but in Javascript animation, we need some special functions. The popular Robert Penner's easing functions set is one of them, and is the default set included with KUTE.js because it's the fastest set I know in terms of performance. Some functions may lack a bit of accuracy but they cover the most animation needs. Generally the easing functions' names are built with keywords that describe the type of easing, like circular or exponential, and also the type of progression in and/or out.

+ +

To use them, simply set a tween option like so easing: KUTE.Easing.easingSinusoidalInOut or simply easing: 'easingSinusoidalInOut'.

+

linear is the default easing function and just as it sounds, it means that the animation has no acceleration or deceleration over time. While this one is basically boring, it's the fastest in all, and it's very useful when animating opacity or colors because we cannot really distinguish changes in speed for such cases, but mostly for movement.

+ +

curve based functions are the next set of easings we are going to tak about. They are basically the same, the only difference is the number of multipliers applied (better think of it like the more weight an object has, the more acceleration):

+ + +

The In / Out explained:

+ + +

back easing functions describe more complex animations (I would call them reverse gravity easings). They also come with in and/or out types of progression.

+ + +

elasticity easing functions describe the kind of animation where the object is elastic. With in and/or out as well.

+ + +

gravity based easing functions describe the kind of animation where the object has a certain degree of bounciness, like a ball. With in and/or out as well.

+ + +

Cubic Bezier Functions

+

While modern browsers support CSS3 transition with transition-timing-function: cubic-bezier(0.1,0.5,0.8,0.5), in Javascript animation we need some specific functions to cover that kind of functionality. As mentioned in the features page, we are using a modified version of the cubic-bezier by Gaëtan Renaudeau. I believe this must be most accurate easing functions set.

+

You can use them either with easing: KUTE.Ease.bezier(mX1, mY1, mX2, mY2) or easing: 'bezier(mX1, mY1, mX2, mY2)', where mX1, mY1, mX2, mY2 are Float values from 0 to 1. You can find the right values you need right here.

+

There is also a pack of presets, and the keywords look very similar if you have used jQuery.Easing plugin before:

+ + +

Physics Based Functions

+

KUTE.js also packs the dynamics physics easing functions by Michael Villar and I have to say these functions are amazing in terms of flexibility, control and performance. They allow you to control the friction, bounciness, frequency, elasticity, or multiple bezier points for your animations.

+

You can use them either with regular Javascript invocation as shown below and configure / visualize them on the author's website, while you can also use the pack of presets featuring mostly bezier based functions. Ok now, let's get to it:

+ + +

The presets can be used both as a string easing:'physicsIn' or easing:KUTE.Physics.physicsIn(friction:200). The list is:

+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + diff --git a/demo/assets/css/kute.css b/demo/assets/css/kute.css new file mode 100644 index 0000000..6689962 --- /dev/null +++ b/demo/assets/css/kute.css @@ -0,0 +1,345 @@ +/*! + * KUTE.js | https://github.com/thednp/kute.js/ + * Licensed under MIT (https://github.com/thednp/kute.js/blob/master/LICENSE) + */ + +/* GLOBAL STYLES +-------------------------------------------------- */ +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 2; /* ~25px */ + color: #ddd; + background-color: #999; + position: relative + +} + +body > .fill { + position: fixed; top: 0; left:0; right: 0; bottom:0; +} + +.fill { + background-size: cover; + background-position: 50% 50%; + background-repeat: no-repeat; + width: 100%; height: 100%; +} +.ie8 .fill {background-size: auto 100%} + +.overlay { + background-color: #000; + opacity: 0.7 +} + +.ie8 .overlay { filter: alpha(opacity=70) } + +footer { + clear: both; overflow: hidden; margin-top: 60px +} + +footer .content-wrap { + padding-top: 5px; + border-top: 1px solid rgb(120,120,120); border-top: 1px solid rgba(255,255,255,0.2); +} + +footer p {margin: 0 0 10px} + +/* site-wrapper */ +.site-wrapper { position: relative; overflow: hidden} + +/* navbar */ +.navbar-wrapper { position: relative; clear: both } +.navbar-wrapper .content-wrap { height: 64px; padding: 20px 0 0; } + +.navbar-wrapper h1 { color: #fff; font-size: 32px; line-height: 25px; letter-spacing: -2px; float: left; padding-right: 25px; margin-right: 25px; border-right: 1px solid rgb(120,120,120); border-right: 1px solid rgba(255,255,255,0.2) } +.navbar-wrapper h1 span { font-size: 24px; color: #555; letter-spacing: -1px; } +.navbar-wrapper h1.active span { color: #ffd626 } +.navbar-wrapper .nav { float: left; padding: 0 0 18px; margin: 0; border-bottom: 1px solid #555 } +.nav li { float: left; display: block; line-height: 25px; list-style: none } +.nav li:not(:last-child) { margin-right: 12px } +.ie8 .nav li { margin-right: 12px } +.nav li.active a { color: #ffd626 } +.nav li a { color: #ccc } +@media (max-width: 768px){ + .navbar-wrapper .content-wrap { height: 94px} + .navbar-wrapper h1 {border: 0} + .navbar-wrapper .nav, + .navbar-wrapper h1 { float: none; } + .navbar-wrapper .nav { height: 30px } +} + +.ie8 .btn.top-right { top:55px } + +/* featurettes */ +.featurettes { +background: #222; + padding: 60px 0; + width: 100%; + clear: both; + margin: 60px 0; + float: left; +} + +.content-wrap .featurettes { margin: 0 0 20px; padding: 20px 0 0 20px; display: inline-block; border-radius: 10px; position: relative } + +/* example box */ +.example-box { + font-size: 40px; line-height: 150px; text-align:center; font-weight: bold; + width: 150px; height: 150px; float: left; position:relative; + border-radius: 5px; margin: 0 20px 20px 0; +/* easy hack to improve box model properties performance on modern browsers only ofc */ + transform: translate3d(0px,0px,0px); -webkit-transform: translate3d(0px,0px,0px); +} +.example-buttons {position: absolute; top: 18px; right:0} + +/* text properties example */ +h1.example-item { + font-size: 50px; + line-height:50px; + color: #fff; +} + +h1.example-item span { + line-height: inherit; + opacity: 0; display: inline; + vertical-align: top; +} +.btn.example-item {opacity: 0} + +.ie8 h1.example-item span, +.ie8 .btn.example-item {filter: alpha(opacity=0)} +/*.ie8 .btn.example-item * {filter: inherit}*/ + +/* UTILITY STYLES +-------------------------------------------------- */ +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} + +.hiddenoverflow { overflow: hidden } + +.media {float: left; margin: 5px 20px 0 0; height: auto; font-size: 64px; line-height: 64px; width: 64px; text-align: center} + + +/* WRAPPER STYLES +-------------------------------------------------- */ +.content-wrap { position: relative; width: 980px; margin: 0 auto; max-width: 100%; clear: both; } +@media (max-width: 1200px){ + .content-wrap { width: 100%; max-width: 80%; } +} + +/* check div consistency +div { background-color: rgba(0,0,0,0.2) }*/ + +/* TYPO STYLES +-------------------------------------------------- */ +p, ul, ol { margin: 0 0 20px } +h1, h2, h3, h4, strong {color: #ffd626} +h1 { font-size: 54px; letter-spacing:-3px; line-height: 0.92; font-weight: normal; } +h2 { font-size: 46px; letter-spacing:-2px; line-height: 1.08; font-weight: normal; margin: 1.08em 0 0.27em; width: 100%; } +h3 { font-size: 24px; letter-spacing:0px; line-height: 0.96; font-weight: normal; } +h4 { font-size: 16px; letter-spacing:0px; line-height: 1.14; font-weight: normal; } +h1, h3, [class*="col"] > h4 {margin: 0 0 20px} + +.lead { font-size: 16px } + +.nomargin { margin-top: 0px !important } +@media (min-width: 768px){ + .nomarginlarge { margin-top: 0 !important } +} + +/* COLUMN STYLES +-------------------------------------------------- */ +.columns { position: relative; width: auto; margin: 0 -20px; clear: both } +.columns > [class*="col"] { padding: 0 20px; float:left; position: relative } +.col2 { width: 50% } +.col3 { width: 33.3% } +.col4 { width: 25% } +.col8 { width: 75% } + +@media (min-width: 480px) and (max-width: 768px){ + /*.columns:not(#blocks) .col3:last-child{width: 100%;}*/ + .col3, + .col4 { width: 50% } + .col8 { width: 100% } +} +@media (max-width: 479px){ + .columns > [class*="col"] { float:none; width: 100%; } +} + +.table { display: table; height: 480px } +.cell { display: table-cell; vertical-align: middle } + +@media (max-width: 479px){ + .table { height: 320px } +} + +/* welcome */ +.col3.bg { /*min-height: 120px;*/ width: 32%; margin: 1.3% 1.3% 0 0; float: left; padding: 0; opacity:0 } +.ie8 .col3.bg { filter: alpha(opacity=0); } + +.col3.bg:nth-child(3), +.col3.bg:nth-child(6), +.col3.bg:nth-child(9) { margin: 1.3% 0 0 } + +.welcome > .table > .cell {perspective: 600px; -webkit-perspective: 600px; } +#blocks { + transform: rotateY(-10deg); -webkit-transform: rotateY(-10deg); width: 90%; +} + +/*.replay { display: none; }*/ + +@media (max-width: 768px){ + .columns.welcome .col2.table { width: 100% !important; float: left } + .columns.welcome .col2:nth-child(2) { position: absolute; top: 0; z-index: -1 } + #blocks { width: auto } +} + +/* STYLING CONTENT +-------------------------------------------------- */ +/* images */ +img { max-width: 100% } +img.circle { border-radius: 50% } + +/* links */ +a { + color: #ffd626; + text-decoration: none; +} +a:hover, +a:focus { + color: #4CAF50; + text-decoration: underline; +} +a:focus { + outline: none; +} + +hr { + border: 1px solid #444; + margin: 10px 0; +} + +/* share */ +#share {position: fixed; top: 20px;right: 20px;} +#share .icon {font-size: 24px; line-height: 1} + +/* buttons */ +.btn { padding: 12px 15px; color:#fff; border:0; background-color: #999; line-height: 44px; } +.bg-gray { color:#fff; background-color: #555; } +.btn.active { background-color: #2196F3 } +.btn:hover, .btn:active, .btn:focus { color: #fff; text-decoration: none; background-color: #777} +.btn-olive, .bg-olive {background-color: #9C27B0; color: #fff} .btn-olive:hover, .btn-olive:active, .btn-olive:focus { background-color: #673AB7 } +.btn-indigo, .bg-indigo { background-color: #673AB7; color: #fff} .btn-indigo:hover, .btn-indigo:active, .btn-indigo:focus { background-color: #ffd626; color:#000 } +.btn-green, .bg-green { background-color: #4CAF50; color: #fff} .btn-green:hover, .btn-green:active, .btn-green:focus { background-color: #9C27B0 } +.btn-red, .bg-red { background-color: #e91b1f; color: #fff} .btn-red:hover, .btn-red:active, .btn-red:focus { background-color: #4CAF50 } +.btn-yellow, .bg-yellow { background-color: #ffd626; color:#000} .btn-yellow:hover, .btn-yellow:active, .btn-yellow:focus { background-color: #4CAF50; color: #000 } +.btn-blue, .bg-blue { background-color: #2196F3; color: #fff} .btn-blue:hover, .btn-blue:active, .btn-blue:focus { background-color: #e91b1f } +.btn-pink, .bg-pink { background-color: #E91E63; color: #fff} .btn-pink:hover, .btn-pink:active, .btn-pink:focus { background-color: #2196F3 } +.btn-orange, .bg-orange { background-color: #FF5722; color: #fff} .btn-orange:hover, .btn-orange:active, .btn-orange:focus { background-color: #4CAF50 } +.btn-lime, .bg-lime { background-color: #CDDC39; color: #000} .btn-lime:hover, .btn-lime:active, .btn-lime:focus { background-color: #e91b1f } +.btn-teal, .bg-teal { background-color: #009688; color: #fff} .btn-teal:hover, .btn-teal:active, .btn-teal:focus { background-color: #9C27B0 } + +.icon-large { font-size: 78px; line-height: 0.64; text-shadow: 2px 2px 0 #FFF,3px 3px 0px #ccc;} +.icon-large.fa-cogs:before { color: #4CAF50 } +.icon-large.fa-rocket:before { color: #673AB7 } +.icon-large.fa-code-fork:before { color: #9C27B0 } + +.btn span { + font-size: 150%; + vertical-align: middle; +} + +.btn span.right { margin: 0 0 0 10px } +.btn span.left { margin: 0 10px 0 0 } + + +/* STYLE CODE WRAPPING +-------------------------------------------------- */ +code, kbd, pre { + font-family: Menlo,Monaco,Consolas,"Courier New",monospace; +} +pre { + display: block; + padding: 10px 15px !important; + margin: 0 0 20px !important; + line-height: 2.08; + color: #999; + word-break: break-all; + background-color: rgb(33,33,33); + background-color: rgba(11,11,11,0.5); + /*border: 1px solid rgb(22,22,22); + border: 1px solid rgba(11,11,11,0.8);*/ + border-radius: 4px; + text-align: left; + position: relative; +} +pre.language-javascript:after, +pre.language-clike:after, +pre.language-markup:after { + position: absolute; top:0; right:0; padding: 2px 5px; + background: #000; + border-radius: 0px 0px 0px 5px; + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; color: #999; +} + +pre.language-javascript:after {content: 'Javascript';} +pre.language-clike:after {content: 'node';} +pre.language-markup:after {content: 'HTML';} +pre code {background: none;padding: 0; font-weight: normal; font-size: 100%;} +code { + padding: 2px 4px; + font-size: 90%; + color: #999; + background-color: #111; + border-radius: 4px; + white-space: pre; + font-weight: bold +} + +kbd { + padding: 2px 4px; + font-size: 90%; + color: #333; + background-color: #eee; + border-radius: 3px; + font-weight: bold +} \ No newline at end of file diff --git a/demo/assets/css/prism.css b/demo/assets/css/prism.css new file mode 100644 index 0000000..c7ced87 --- /dev/null +++ b/demo/assets/css/prism.css @@ -0,0 +1,3 @@ + /* prism okaidia | ocodia */ + +code[class*=language-],pre[class*=language-]{color:#f8f8f2;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#f8f8f2}.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} \ No newline at end of file diff --git a/demo/assets/css/reset.css b/demo/assets/css/reset.css new file mode 100644 index 0000000..af84377 --- /dev/null +++ b/demo/assets/css/reset.css @@ -0,0 +1,209 @@ +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +figure { + margin: 0; +} +img { + /*vertical-align: middle;*/ +} \ No newline at end of file diff --git a/demo/assets/img/favicon.png b/demo/assets/img/favicon.png new file mode 100644 index 0000000..7737268 Binary files /dev/null and b/demo/assets/img/favicon.png differ diff --git a/demo/assets/img/img-blank.gif b/demo/assets/img/img-blank.gif new file mode 100644 index 0000000..5891de4 Binary files /dev/null and b/demo/assets/img/img-blank.gif differ diff --git a/demo/assets/img/loader.gif b/demo/assets/img/loader.gif new file mode 100644 index 0000000..335e00c Binary files /dev/null and b/demo/assets/img/loader.gif differ diff --git a/demo/assets/js/examples.js b/demo/assets/js/examples.js new file mode 100644 index 0000000..5d3482c --- /dev/null +++ b/demo/assets/js/examples.js @@ -0,0 +1,343 @@ +// some regular checking +var isIE = /ie/.test(document.documentElement.className), + isIE8 = /ie8/.test(document.documentElement.className), + isIE9 = /ie9/.test(document.documentElement.className); + + +/* TRANSFORMS EXAMPLES */ +var featurettes = document.querySelectorAll('.featurettes'), fl = featurettes.length; + +for ( var i=0; i0 && op[i]!==undefined) { + op[i] = op[i].charAt(0).toUpperCase() + op[i].slice(1); + } + } + op = op.join(''); + options[op] = attr[l].value; + } else if (/property/.test(attr[l].nodeName)) { + var pp = attr[l].nodeName.replace('data-property-','').replace(/\s/,'').split('-'); + for (var j=0;j0 && pp[j]!==undefined) { + pp[j] = pp[j].charAt(0).toUpperCase() + pp[j].slice(1); + } + } + pp = pp.join(''); + properties[pp] = pp === 'translate3d' || pp === 'translate' ? attr[l].value.replace(/\[|\]/g,'').split(',') : attr[l].value; + } + } + } + return {options: options, properties: properties}; +} +/* TRANSFORMS EXAMPLES */ + + +/* CHAINED TWEENS EXAMPLE */ +var chainedTweens = document.getElementById('chainedTweens'), + el1 = chainedTweens.querySelectorAll('.example-item')[0], + el2 = chainedTweens.querySelectorAll('.example-item')[1], + el3 = chainedTweens.querySelectorAll('.example-item')[2], + ctb = chainedTweens.querySelector('.btn'); + +// built the tween objects for element1 +var tween11 = KUTE.fromTo(el1, {translateX:0, rotateX: 0}, {translateX:100, rotateX: 25}, {perspective:100, duration: 2000}); +var tween12 = KUTE.fromTo(el1, {translateY:0, rotateY: 0}, {translateY:20, rotateY: 15}, {perspective:100, duration: 2000}); +var tween13 = KUTE.fromTo(el1, {translate3d:[100,20,0], rotateX: 25, rotateY:15}, {translate3d:[0,0,0], rotateX: 0, rotateY:0}, {perspective:100, duration: 2000}); + +// chain tweens +tween11.chain(tween12); +tween12.chain(tween13); + +// built the tween objects for element2 +var tween21 = KUTE.fromTo(el2, {translateX:0, translateY:0, rotateX: 0, rotateY:0 }, {translateX:150, translateY:0, rotateX: 25, rotateY:0}, {perspective:100, duration: 2000}); +var tween22 = KUTE.fromTo(el2, {translateX:150, translateY:0, rotateX: 25, rotateY: 0}, {translateX:150, translateY:20, rotateX: 25, rotateY: 15}, {perspective:100, duration: 2000}); +var tween23 = KUTE.fromTo(el2, {translate3d:[150,20,0], rotateX: 25, rotateY:15}, {translate3d:[0,0,0], rotateX: 0, rotateY:0}, {perspective:100, duration: 2000}); + +// chain tweens +tween21.chain(tween22); +tween22.chain(tween23); + +// built the tween objects for element3 +var tween31 = KUTE.to(el3,{translateX:200, rotateX: 25}, {perspective:100, duration: 2000}); +var tween32 = KUTE.to(el3,{translate3d:[200,20,0], rotateY: 15}, {perspective:100, duration: 2000}); +var tween33 = KUTE.to(el3,{translate3d:[0,0,0], rotateX: 0, rotateY:0}, {perspective:100, duration: 2000}); + +// chain tweens +tween31.chain(tween32); +tween32.chain(tween33); + +ctb.addEventListener('click',function(e){ + e.preventDefault(); + tween11.start(); tween21.start(); tween31.start(); +},false); +/* CHAINED TWEENS EXAMPLE */ + + +/* BOX MODEL EXAMPLE */ +var boxModel = document.getElementById('boxModel'), + btb = boxModel.querySelector('.btn'), + box = boxModel.querySelector('.example-box'); + +// built the tween objects +var bm1 = KUTE.to(box,{width:250},{ yoyo: true, repeat: 1, duration: 1500, update: onWidth}); +var bm2 = KUTE.to(box,{height:250},{ yoyo: true, repeat: 1, duration: 1500, update: onHeight}); +var bm3 = KUTE.to(box,{left:250},{ yoyo: true, repeat: 1, duration: 1500, update: onLeft}); +var bm4 = KUTE.to(box,{top:-250},{ yoyo: true, repeat: 1, duration: 1500, update: onTop}); +var bm5 = KUTE.fromTo(box,{padding:0},{padding:20},{ yoyo: true, repeat: 1, duration: 1500, update: onPadding}); +var bm6 = KUTE.to(box,{marginTop:50,marginLeft:50,marginBottom:70},{ yoyo: true, repeat: 1, duration: 1500, update: onMargin, complete: onComplete}); + +// chain the bms +bm1.chain(bm2); +bm2.chain(bm3); +bm3.chain(bm4); +bm4.chain(bm5); +bm5.chain(bm6); + +//callback functions +function onWidth() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'WIDTH
'+parseInt(css.width)+'px'; } +function onHeight() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'HEIGHT
'+parseInt(css.height)+'px'; } +function onLeft() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'LEFT
'+parseInt(css.left)+'px'; } +function onTop() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'TOP
'+parseInt(css.top)+'px'; } +function onPadding() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'PADDING
'+(parseInt(css.padding)+'px')||'auto'; } +function onMargin() { var css = box.currentStyle || window.getComputedStyle(box); box.innerHTML = 'MARGIN
'+parseInt(css.marginTop)+'px'; } +function onComplete() { box.innerHTML = 'BOX
MODEL'; btb.style.display='inline'; } + +btb.addEventListener('click', function(e){ + e.preventDefault(); + bm1.start(); + btb.style.display='none'; +},false); +/* BOX MODEL EXAMPLE */ + + +/* TEXT PROPERTIES EXAMPLE */ +var textProperties = document.getElementById('textProperties'), + heading = textProperties.querySelector('h1'), + button = textProperties.querySelectorAll('.btn')[0], + tbt = textProperties.querySelectorAll('.btn')[1], + + // let's split the heading text by character + chars = heading.innerHTML.split(''); + +// wrap the splits into spans and build an object with these spans +heading.innerHTML = '' + chars.join('') + ''; +var charsObject = heading.getElementsByTagName('SPAN'), l = charsObject.length; + + +// built the tween objects +var tp1 = KUTE.fromTo( + button, + {width: 150, opacity:0, height: 70, lineHeight:70, fontSize: 40}, + {width: 100, opacity:1, height: 35, lineHeight:35, fontSize: 20}); + +function runHeadingAnimation() { + for (var i=0; i + function CSSStyleDeclaration(element) { + var style = this, + currentStyle = element.currentStyle, + fontSize = getComputedStylePixel(element, 'fontSize'), + unCamelCase = function (match) { + return '-' + match.toLowerCase(); + }, + property; + + for (property in currentStyle) { + Array.prototype.push.call(style, property == 'styleFloat' ? 'float' : property.replace(/[A-Z]/, unCamelCase)); + + if (property == 'width') { + style[property] = element.offsetWidth + 'px'; + } else if (property == 'height') { + style[property] = element.offsetHeight + 'px'; + } else if (property == 'styleFloat') { + style.float = currentStyle[property]; + } else if (/margin.|padding.|border.+W/.test(property) && style[property] != 'auto') { + style[property] = Math.round(getComputedStylePixel(element, property, fontSize)) + 'px'; + } else if (/^outline/.test(property)) { + // errors on checking outline + try { + style[property] = currentStyle[property]; + } catch (error) { + style.outlineColor = currentStyle.color; + style.outlineStyle = style.outlineStyle || 'none'; + style.outlineWidth = style.outlineWidth || '0px'; + style.outline = [style.outlineColor, style.outlineWidth, style.outlineStyle].join(' '); + } + } else { + style[property] = currentStyle[property]; + } + } + + setShortStyleProperty(style, 'margin'); + setShortStyleProperty(style, 'padding'); + setShortStyleProperty(style, 'border'); + + style.fontSize = Math.round(fontSize) + 'px'; + } + + CSSStyleDeclaration.prototype = { + constructor: CSSStyleDeclaration, + // .getPropertyPriority + getPropertyPriority: function () { + throw new Error('NotSupportedError: DOM Exception 9'); + }, + // .getPropertyValue + getPropertyValue: function (property) { + return this[property.replace(/-\w/g, function (match) { + return match[1].toUpperCase(); + })]; + }, + // .item + item: function (index) { + return this[index]; + }, + // .removeProperty + removeProperty: function () { + throw new Error('NoModificationAllowedError: DOM Exception 7'); + }, + // .setProperty + setProperty: function () { + throw new Error('NoModificationAllowedError: DOM Exception 7'); + }, + // .getPropertyCSSValue + getPropertyCSSValue: function () { + throw new Error('NotSupportedError: DOM Exception 9'); + } + }; + + // .getComputedStyle + window.getComputedStyle = function getComputedStyle(element) { + return new CSSStyleDeclaration(element); + }; + })(); +} + +// requestAnimationFrame +if (!window.requestAnimationFrame) { + + var lT = Date.now(); // lastTime + window.requestAnimationFrame = function (callback) { + 'use strict'; + if (typeof callback !== 'function') { + throw new TypeError(callback + 'is not a function'); + } + + var cT = Date.now(), // currentTime + dl = 16 + lT - cT; // delay + + if (dl < 0) { dl = 0; } + + lT = cT; + + return setTimeout(function () { + lT = Date.now(); + callback(window.performance.now()); + }, dl); + }; + + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; +} + + +// Event +if (!window.Event||!Window.prototype.Event) { + (function (){ + window.Event = Window.prototype.Event = Document.prototype.Event = Element.prototype.Event = function Event(t, args) { + if (!t) { throw new Error('Not enough arguments'); } // t is event.type + var ev, + b = args && args.bubbles !== undefined ? args.bubbles : false, + c = args && args.cancelable !== undefined ? args.cancelable : false; + if ( 'createEvent' in document ) { + ev = document.createEvent('Event'); + ev.initEvent(t, b, c); + } else { + ev = document.createEventObject(); + ev.type = t; + ev.bubbles = b; + ev.cancelable = c; + } + return ev; + }; + })(); +} + +// CustomEvent +if (!('CustomEvent' in window) || !('CustomEvent' in Window.prototype)) { + (function(){ + window.CustomEvent = Window.prototype.CustomEvent = Document.prototype.CustomEvent = Element.prototype.CustomEvent = function CustomEvent(type, args) { + if (!type) { + throw Error('TypeError: Failed to construct "CustomEvent": An event name must be provided.'); + } + var ev = new Event(type, args); + ev.detail = args && args.detail || null; + return ev; + }; + + })() +} + +// addEventListener +if (!window.addEventListener||!Window.prototype.addEventListener) { + (function (){ + window.addEventListener = Window.prototype.addEventListener = Document.prototype.addEventListener = Element.prototype.addEventListener = function addEventListener() { + var el = this, // element + t = arguments[0], // type + l = arguments[1]; // listener + + if (!el._events) { el._events = {}; } + + if (!el._events[t]) { + el._events[t] = function (e) { + var ls = el._events[e.type].list, evs = ls.slice(), i = -1, lg = evs.length, eE; // list | events | index | length | eventElement + + e.preventDefault = function preventDefault() { + if (e.cancelable !== false) { + e.returnValue = false; + } + }; + + e.stopPropagation = function stopPropagation() { + e.cancelBubble = true; + }; + + e.stopImmediatePropagation = function stopImmediatePropagation() { + e.cancelBubble = true; + e.cancelImmediate = true; + }; + + e.currentTarget = el; + e.relatedTarget = e.fromElement || null; + e.target = e.target || e.srcElement || el; + e.timeStamp = new Date().getTime(); + + if (e.clientX) { + e.pageX = e.clientX + document.documentElement.scrollLeft; + e.pageY = e.clientY + document.documentElement.scrollTop; + } + + while (++i < lg && !e.cancelImmediate) { + if (i in evs) { + eE = evs[i]; + + if (ls.indexOf(eE) !== -1 && typeof eE === 'function') { + eE.call(el, e); + } + } + } + }; + + el._events[t].list = []; + + if (el.attachEvent) { + el.attachEvent('on' + t, el._events[t]); + } + } + + el._events[t].list.push(l); + }; + + window.removeEventListener = Window.prototype.removeEventListener = Document.prototype.removeEventListener = Element.prototype.removeEventListener = function removeEventListener() { + var el = this, t = arguments[0], l = arguments[1], i; // element // type // listener // index + + if (el._events && el._events[t] && el._events[t].list) { + i = el._events[t].list.indexOf(l); + + if (i !== -1) { + el._events[t].list.splice(i, 1); + + if (!el._events[t].list.length) { + if (el.detachEvent) { + el.detachEvent('on' + t, el._events[t]); + } + delete el._events[t]; + } + } + } + }; + })(); +} + +// Event dispatcher / trigger +if (!window.dispatchEvent||!Window.prototype.dispatchEvent||!Document.prototype.dispatchEvent||!Element.prototype.dispatchEvent) { + (function(){ + window.dispatchEvent = Window.prototype.dispatchEvent = Document.prototype.dispatchEvent = Element.prototype.dispatchEvent = function dispatchEvent(e) { + if (!arguments.length) { + throw new Error('Not enough arguments'); + } + + if (!e || typeof e.type !== 'string') { + throw new Error('DOM Events Exception 0'); + } + + var el = this, t = e.type; // element | event type + + try { + if (!e.bubbles) { + e.cancelBubble = true; + + var cancelBubbleEvent = function (event) { + event.cancelBubble = true; + + (el || window).detachEvent('on' + t, cancelBubbleEvent); + }; + + this.attachEvent('on' + t, cancelBubbleEvent); + } + + this.fireEvent('on' + t, e); + } catch (error) { + e.target = el; + + do { + e.currentTarget = el; + + if ('_events' in el && typeof el._events[t] === 'function') { + el._events[t].call(el, e); + } + + if (typeof el['on' + t] === 'function') { + el['on' + t].call(el, e); + } + + el = el.nodeType === 9 ? el.parentWindow : el.parentNode; + } while (el && !e.cancelBubble); + } + + return true; + }; + })(); +} \ No newline at end of file diff --git a/demo/assets/js/perf.js b/demo/assets/js/perf.js new file mode 100644 index 0000000..4c7723d --- /dev/null +++ b/demo/assets/js/perf.js @@ -0,0 +1,178 @@ +//returns browser prefix +function getPrefix() { + var div = document.createElement('div'), i = 0, pf = ['Moz', 'moz', 'Webkit', 'webkit', 'O', 'o', 'Ms', 'ms'], pl = pf.length, + s = ['MozTransform', 'mozTransform', 'WebkitTransform', 'webkitTransform', 'OTransform', 'oTransform', 'MsTransform', 'msTransform']; + + for (i; i < pl; i++) { if (s[i] in div.style) { return pf[i]; } } + div = null; +} + +// generate a random number within a given range +function random(min, max) { + return Math.random() * (max - min) + min; +} + +// vendor prefix handle +var prefix = getPrefix(), // prefix + prefixRequired = (!('transform' in document.getElementsByTagName('div')[0].style)) ? true : false, // is prefix required for transform + transformProperty = prefixRequired ? prefix + 'Transform' : 'transform'; + +// the variables +var container = document.getElementById('container'), + easing = 'easingQuadraticInOut', + tweens = []; + +function createTest(count, property, engine, repeat, hack) { + for (var i = 0; i < count; i++) { + var tween, + div = document.createElement('div'), + windowHeight = document.documentElement.clientHeight - 10, + left = random(-200, 200), + toLeft = random(-200, 200), + top = Math.round(Math.random() * parseInt(windowHeight)), + background = 'rgb('+parseInt(random(0, 255))+','+parseInt(random(0, 255))+','+parseInt(random(0, 255))+')', + fromValues, toValues, fn = i===count-1 ? complete : null; + repeat = parseInt(repeat); + + div.className = 'line'; + div.style.top = top + 'px'; + div.style.backgroundColor = background; + + if (property==='left') { + div.style.left = left + 'px'; + if (hack) { div.className += ' hack'; } + fromValues = engine==="tween" ? { left: left, div: div } : { left: left }; + toValues = { left: toLeft } + } else { + div.style[transformProperty] = 'translate3d('+left + 'px,0px,0px)'; + if (engine==="kute"){ + fromValues = { translateX: left } + toValues = { translateX: toLeft } + } else if ((engine==="gsap") || (engine==="tween")) { + fromValues = engine==='gsap' ? { x: left } : { x: left, div : div } + toValues = { x: toLeft } + } + } + + container.appendChild(div); + + // perf test + if (engine==='kute') { + tween = KUTE.fromTo(div, fromValues, toValues, { delay: 100, easing: easing, repeat: repeat, yoyo: true, duration: 1000, complete: fn }); + tweens.push(tween); + } else if (engine==='gsap') { + if (property==="left"){ + tween = TweenMax.fromTo(div, 1, fromValues, {left : toValues.left, repeat : repeat, yoyo : true, ease : Quad.easeInOut, onComplete: fn }); + } else { + tween = TweenMax.fromTo(div, 1, fromValues, { x:toValues.x, repeat : repeat, yoyo : true, ease : Quad.easeInOut, onComplete: fn }); + } + } else if (engine==='tween') { + var update; + + if (property==="left"){ + update = function(){ + this.div.style['left'] = this.left+'px'; + } + } else if (property==="translateX"){ + update = function(){ + this.div.style[transformProperty] = 'translate3d('+this.x + 'px,0px,0px)'; + } + } + + tween = new TWEEN.Tween(fromValues) + .to(toValues,1000) + .easing( TWEEN.Easing.Quadratic.InOut ) + .onComplete( complete ) + .onUpdate( update) + .repeat(repeat) + .yoyo(true); + tweens.push(tween); + } + } + if (engine==='tween') { + animate(); + function animate( time ) { + requestAnimationFrame( animate ); + TWEEN.update( time ); + } + } + + // since our engines don't do sync, we make it our own here + if (engine==='tween'||engine==='kute') { + var now = window.performance.now(); + for (var t =0; t'; + b.setAttribute('data-'+link.parentNode.parentNode.parentNode.id,link.id); + if ( /LEFT/.test(document.getElementById('property').querySelector('.btn').innerHTML) ) { + document.getElementById('hack').style.display = 'block'; + } else { + document.getElementById('hack').style.display = 'none'; + } + } + } +} + +document.getElementById('hack').querySelector('.btn').onclick = function(){ + var self= this; + setTimeout(function(){ + if ( !self.querySelector('INPUT').checked ) { + self.className = self.className.replace('btn-info','btn-warning'); + self.querySelector('.state').innerHTML = 'Hack ON'; + } else if ( self.querySelector('INPUT').checked ) { + self.className = self.className.replace('btn-warning','btn-info'); + self.querySelector('.state').innerHTML = 'Hack OFF'; + } + },200) +} + +// the start button handle +document.getElementById('start').onclick = function(){ + var c = document.querySelector('[data-count]'), e = document.querySelector('[data-engine]'), r = document.querySelector('[data-repeat]'), + p = document.querySelector('[data-property]'), ct = c && document.querySelector('[data-count]').getAttribute('data-count'), + count = ct ? parseInt(ct) : null, + engine = e && document.querySelector('[data-engine]').getAttribute('data-engine') || null, + repeat = r && document.querySelector('[data-repeat]').getAttribute('data-repeat') || null, + property = p && document.querySelector('[data-property]').getAttribute('data-property') || null, + hack = document.getElementById('hack').getElementsByTagName('INPUT')[0].getAttribute('checked') ? true : false, + warning = document.createElement('DIV'); + + warning.className = 'text-warning padding lead'; + container.innerHTML = ''; + if (count && engine && property && repeat) { + document.getElementById('info').style.display = 'none'; + + createTest(count,property,engine,repeat,hack); + } else { + + if (!count && !property && !repeat && !engine){ + warning.innerHTML = 'We are missing all the settings here.'; + } else { + warning.innerHTML = 'Now missing
'; + warning.innerHTML += !engine ? '- engine
' : ''; + warning.innerHTML += !property ? '- property
' : ''; + warning.innerHTML += !repeat ? '- repeat
' : ''; + warning.innerHTML += !count ? '- count
' : ''; + } + + container.appendChild(warning); + } +} \ No newline at end of file diff --git a/demo/assets/js/prism.js b/demo/assets/js/prism.js new file mode 100644 index 0000000..8d21c08 --- /dev/null +++ b/demo/assets/js/prism.js @@ -0,0 +1,6 @@ +/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=_self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),P=[p,1];b&&P.push(b);var A=new a(i,g?t.tokenize(m,g):m,h);P.push(A),w&&P.push(w),Array.prototype.splice.apply(r,P)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var l={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}t.hooks.run("wrap",l);var o="";for(var s in l.attributes)o+=(o?" ":"")+s+'="'+(l.attributes[s]||"")+'"';return"<"+l.tag+' class="'+l.classes.join(" ")+'" '+o+">"+l.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code,l=n.immediateClose;_self.postMessage(t.highlight(r,t.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; +Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript; diff --git a/demo/assets/js/scripts.js b/demo/assets/js/scripts.js new file mode 100644 index 0000000..babe497 --- /dev/null +++ b/demo/assets/js/scripts.js @@ -0,0 +1,14 @@ +// common demo JS + +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +//scroll top? +var toTop = document.getElementById('toTop'); +toTop.addEventListener('click',topHandler,false); + +function topHandler(e){ + e.preventDefault(); + KUTE.to( 'window', { scroll: 0 }, {easing: 'easingQuarticOut', duration : 1500 } ).start(); +} \ No newline at end of file diff --git a/demo/assets/js/tween.min.js b/demo/assets/js/tween.min.js new file mode 100644 index 0000000..299b67d --- /dev/null +++ b/demo/assets/js/tween.min.js @@ -0,0 +1,2 @@ +// KUTE.js | dnp_theme | MIT License +!function(t,e){"function"==typeof define&&define.amd?define(["KUTE"],e):"object"==typeof exports?module.exports=e():t.KUTE=t.KUTE||e()}(this,function(){function t(){var t=document.createElement("div"),e=0,r=["Moz","moz","Webkit","webkit","O","o","Ms","ms"],i=r.length,n=["MozTransform","mozTransform","WebkitTransform","webkitTransform","OTransform","oTransform","MsTransform","msTransform"];for(e;i>e;e++)if(n[e]in t.style)return r[e];t=null}for(var e,r=r||{},i=[],n=!1,s=t(),a=(a||("requestAnimationFrame"in window?!1:!0)),o=(o||("transform"in document.getElementsByTagName("div")[0].style?!1:!0)),u=(u||("border-radius"in document.getElementsByTagName("div")[0].style?!1:!0)),l=(l||"ontouchstart"in window||navigator.msMaxTouchPoints||!1),f=f||(l?"touchstart":"mousewheel"),p=document.body,h=document.getElementsByTagName("HTML")[0],c=/webkit/i.test(navigator.userAgent)||"BackCompat"==document.compatMode?p:h,d=/ie/.test(document.documentElement.className),v=/ie8/.test(document.documentElement.className),g=g||o?s+"Perspective":"perspective",_=_||o?s+"PerspectiveOrigin":"perspectiveOrigin",m=m||o?s+"Transform":"transform",E=E||u?s+"BorderRadius":"borderRadius",y=y||u?s+"BorderTopLeftRadius":"borderTopLeftRadius",b=b||u?s+"BorderTopRightRadius":"borderTopRightRadius",w=w||u?s+"BorderBottomLeftRadius":"borderBottomLeftRadius",O=O||u?s+"BorderBottomRightRadius":"borderBottomRightRadius",x=x||a?window[s+"RequestAnimationFrame"]:window.requestAnimationFrame,T=T||a?window[s+"CancelAnimationFrame"]:window.cancelAnimationFrame,C=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],I=["scrollTop","scroll"],S=["clip"],R=["opacity"],D=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],M=["top","left","right","bottom","width","height","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],B=["fontSize","lineHeight","letterSpacing"],k=["backgroundPosition"],L=["rotateX","rotateY","translateZ"],A=["translate3d","translateX","translateY","translateZ","rotate","translate","rotateX","rotateY","rotateZ","skewX","skewY","scale"],F=C.concat(I,S,R,D,M,B,k,A),P=F.length,Y={},X={},Z={},z={},q={},Q={},W=W||{},N=0;P>N;N++){var H=F[N];-1!==C.indexOf(H)?W[H]="rgba(0,0,0,0)":-1!==D.indexOf(H)||-1!==M.indexOf(H)||-1!==B.indexOf(H)?W[H]=0:-1!==k.indexOf(H)?W[H]=[50,50]:"clip"===H?W[H]=[0,0,0,0]:"translate3d"===H?W[H]=[0,0,0]:"translate"===H?W[H]=[0,0]:"rotate"===H||/X|Y|Z/.test(H)?W[H]=0:("scale"===H||"opacity"===H)&&(W[H]=1)}r.getAll=function(){return i},r.removeAll=function(){i=[]},r.add=function(t){i.push(t)},r.remove=function(t){var e=i.indexOf(t);-1!==e&&i.splice(e,1)},r.t=function(t){e=x(r.t);for(var s=0,a=i.length;a>s;){if(!i[s])return!1;i[s].u(t)?s++:i.splice(s,1)}return n=!1,!0},r.s=function(){n===!1&&(T(e),n=!0,e=null)},r.to=function(t,e,i){void 0===i&&(i={});var n=n||"object"==typeof t?t:document.querySelector(t),s=s||i;s.rpr=!0,s.easing=s&&r.pe(s.easing)||r.Easing.linear;var a=e,o=r.prP(e,!0),u=new r.Tween(n,a,o,s);return u},r.fromTo=function(t,e,i,n){void 0===n&&(n={});var s=s||"object"==typeof t?t:document.querySelector(t),a=n;a.easing=a&&r.pe(a.easing)||r.Easing.linear;var o=r.prP(e,!1),u=r.prP(i,!0),l=new r.Tween(s,o,u,a);return l},r.Animate=function(t,e,i,n){return r.fromTo(t,e,i,n)},r.r=function(t,e){var i,n=t._el&&t._el.style,s=v?"filter":"opacity",a=void 0===t._el||null===t._el?c:t._el;for(i in t._vE){var o=t._vS[i],u=t._vE[i],l=o.value,f=u.value,p=l+(f-l)*e,h=u.unit,g=-1!==C.indexOf(i),_=-1!==B.indexOf(i)||-1!==M.indexOf(i),x=-1!==D.indexOf(i)&&!v,T=-1!==I.indexOf(i),A=-1!==k.indexOf(i),F=-1!==S.indexOf(i),P=-1!==R.indexOf(i),Y="transform"===i&&!v;if(x)"borderRadius"===i?n[E]=p+h:"borderTopLeftRadius"===i?n[y]=p+h:"borderTopRightRadius"===i?n[b]=p+h:"borderBottomLeftRadius"===i?n[w]=p+h:"borderBottomRightRadius"===i&&(n[O]=p+h);else if(Y){var X,Z,z="",q="perspective("+t._pp+"px) ";for(X in u){var Q=o[X],W=u[X];if(Z=-1!==L.indexOf(X)&&!d,"translate"===X){var N,H="",j={};for(N in W){var K=Q[N].value||0,U=W[N].value||0,$=W[N].unit||"px";j[N]=K===U?U+$:K+(U-K)*e+$}H=W.x?"translate("+j.x+","+j.y+")":"translate3d("+j.translateX+","+j.translateY+","+j.translateZ+")",z=""===z?H:H+" "+z}else if("rotate"===X){var G,J="",V={};for(G in W)if(Q[G]){var te=Q[G].value,ee=W[G].value,re=W[G].unit||"deg",ie=te+(ee-te)*e;V[G]="z"===G?"rotate("+ie+re+")":G+"("+ie+re+") "}J=W.z?V.z:(V.rotateX||"")+(V.rotateY||"")+(V.rotateZ||""),z=""===z?J:z+" "+J}else if("skew"===X){var ne="",se={};for(var ae in W)if(Q[ae]){var oe=Q[ae].value,ue=W[ae].value,le=W[ae].unit||"deg",fe=oe+(ue-oe)*e;se[ae]=ae+"("+fe+le+") "}ne=(se.skewX||"")+(se.skewY||""),z=""===z?ne:z+" "+ne}else if("scale"===X){var pe=Q.value,he=W.value,ce=pe+(he-pe)*e,de=X+"("+ce+")";z=""===z?de:z+" "+de}}n[m]=Z||void 0!==t._pp&&0!==t._pp?q+z:z}else if(g){var ve,ge={};for(ve in f)ge[ve]="a"!==ve?parseInt(l[ve]+(f[ve]-l[ve])*e)||0:l[ve]&&f[ve]?parseFloat(l[ve]+(f[ve]-l[ve])*e):null;n[i]=t._hex?r.rth(parseInt(ge.r),parseInt(ge.g),parseInt(ge.b)):!ge.a||v?"rgb("+ge.r+","+ge.g+","+ge.b+")":"rgba("+ge.r+","+ge.g+","+ge.b+","+ge.a+")"}else if(_)n[i]=p+h;else if(T)a.scrollTop=l+(f-l)*e;else if(A){var _e=o.x.v,me=u.x.v,Ee=o.y.v,ye=u.y.v,be=_e+(me-_e)*e,we="%",Oe=Ee+(ye-Ee)*e,xe="%";n[i]=be+we+" "+Oe+xe}else if(F){var Te=0,Ce=[];for(Te;4>Te;Te++){var Ie=o[Te].v,Se=u[Te].v,Re=u[Te].u||"px";Ce[Te]=Ie+(Se-Ie)*e+Re}n[i]="rect("+Ce+")"}else P&&(n[s]=v?"alpha(opacity="+parseInt(100*p)+")":p)}},r.perspective=function(t,e){void 0!==e._ppo&&(t.style[_]=e._ppo),void 0!==e._ppp&&(t.parentNode.style[g]=e._ppp+"px"),void 0!==e._pppo&&(t.parentNode.style[_]=e._pppo)},r.Tween=function(t,e,r,i){this._el=this._el||t,this._dr=this._dr||i&&i.duration||700,this._r=this._r||i&&i.repeat||0,this._vSR={},this._vS=e,this._vE=r,this._y=this._y||i&&i.yoyo||!1,this.playing=!1,this.reversed=!1,this._rD=this._rD||i&&i.repeatDelay||0,this._dl=this._dl||i&&i.delay||0,this._sT=null,this.paused=!1,this._pST=null,this._pp=this._pp||i.perspective,this._ppo=this._ppo||i.perspectiveOrigin,this._ppp=this._ppp||i.parentPerspective,this._pppo=this._pppo||i.parentPerspectiveOrigin,this._rpr=this._rpr||i.rpr||!1,this._hex=this._hex||i.keepHex||!1,this._e=this._e||i.easing,this._cT=this._cT||[],this._sC=this._sC||i&&i.start||null,this._sCF=!1,this._uC=i&&i.update||null,this._cC=i&&i.complete||null,this._pC=i&&i.pause||null,this._rC=i&&i.play||null,this._stC=i&&i.stop||null,this.repeat=this._r};var j=r.Tween.prototype;j.start=function(t){this.scrollIn();var i={};if(r.perspective(this._el,this),this._rpr){i=this.prS(),this._vS={},this._vS=r.prP(i,!1);for(H in this._vS)if("transform"===H&&H in this._vE)for(var n in this._vS[H]){n in this._vE[H]||(this._vE[H][n]={});for(var s in this._vS[H][n])if(void 0!==this._vS[H][n][s].value){s in this._vE[H][n]||(this._vE[H][n][s]={});for(var a in this._vS[H][n][s])a in this._vE[H][n][s]||(this._vE[H][n][s][a]=this._vS[H][n][s][a])}if("value"in this._vS[H][n]&&!("value"in this._vE[H][n]))for(var s in this._vS[H][n])s in this._vE[H][n]||(this._vE[H][n][s]=this._vS[H][n][s])}}for(H in this._vE)this._vSR[H]=this._vS[H];return r.add(this),this.playing=!0,this.paused=!1,this._sCF=!1,this._sT=t||window.performance.now(),this._sT+=this._dl,e||r.t(),this},j.u=function(t){if(t=t||window.performance.now(),t1?1:e,r.r(this,this._e(e)),this._uC&&this._uC.call(),1===e){if(this._r>0)return 1/0!==this._r&&this._r--,this._y&&(this.reversed=!this.reversed,this.reverse()),this._sT=this._y&&!this.reversed?t+this._rD:t,!0;this._cC&&this._cC.call(),this.scrollOut();var i=0,n=this._cT.length;for(i;n>i;i++)this._cT[i].start(this._sT+this._dr);return this.close(),!1}return!0},j.stop=function(){return!this.paused&&this.playing&&(r.remove(this),this.playing=!1,this.paused=!1,this.scrollOut(),null!==this._stC&&this._stC.call(),this.stopChainedTweens(),this.close()),this},j.pause=function(){return!this.paused&&this.playing&&(r.remove(this),this.paused=!0,this._pST=window.performance.now(),null!==this._pC&&this._pC.call()),this},j.play=function(){return this.paused&&this.playing&&(this.paused=!1,null!==this._rC&&this._rC.call(),this._sT+=window.performance.now()-this._pST,r.add(this),e||r.t()),this},j.resume=function(){return this.play(),this},j.reverse=function(){if(this._y)for(var t in this._vE){var e=this._vSR[t];this._vSR[t]=this._vE[t],this._vE[t]=e,this._vS[t]=this._vSR[t]}return this},j.chain=function(){return this._cT=arguments,this},j.stopChainedTweens=function(){var t=0,e=this._cT.length;for(t;e>t;t++)this._cT[t].stop()},j.scrollOut=function(){("scroll"in this._vE||"scrollTop"in this._vE)&&(this.removeListeners(),document.body.removeAttribute("data-tweening"))},j.scrollIn=function(){("scroll"in this._vE||"scrollTop"in this._vE)&&(document.body.getAttribute("data-tweening")||(document.body.setAttribute("data-tweening","scroll"),this.addListeners()))},j.addListeners=function(){document.addEventListener(f,r.preventScroll,!1)},j.removeListeners=function(){document.removeEventListener(f,r.preventScroll,!1)},j.prS=function(){var t={},e=this._el,r=this._vS,i=this.gIS("transform"),n=["rotate","skew"],s=["X","Y","Z"];for(var a in r)if(-1!==A.indexOf(a)){var o="rotate"===a||"translate"===a||"scale"===a;if(/translate/.test(a)&&"translate"!==a)t.translate3d=i.translate3d||W[a];else if(o)t[a]=i[a]||W[a];else if(!o&&/rotate|skew/.test(a))for(var u=0;2>u;u++)for(var l=0;3>l;l++){var f=n[u]+s[l];-1!==A.indexOf(f)&&f in r&&(t[f]=i[f]||W[f])}}else if(-1===I.indexOf(a))if("opacity"===a&&v){var p=this.gCS("filter");t.opacity="number"==typeof p?p:W.opacity}else t[a]=this.gCS(a)||W[a];else t[a]=null===e||void 0===e?window.pageYOffset||c.scrollTop:e.scrollTop;for(var a in i)-1===A.indexOf(a)||a in r||(t[a]=i[a]||W[a]);return t},j.gIS=function(){if(this._el){var t=this._el,e=t.style.cssText,r={},i=e.replace(/\s/g,"").split(";"),n=0,s=i.length;for(n;s>n;n++)if(/transform/.test(i[n])){var a=i[n].split(":")[1].split(")"),o=0,u=a.length;for(o;u>o;o++){var l=a[o].split("(");""!==l[0]&&A.indexOf(l)&&(r[l[0]]=/translate3d/.test(l[0])?l[1].split(","):l[1])}}return r}},j.gCS=function(t){var e=this._el,r=window.getComputedStyle(e)||e.currentStyle,i=!v&&o&&/transform|Radius/.test(t)?"-"+s.toLowerCase()+"-"+t:t,n=o&&"transform"===t||o&&-1!==D.indexOf(t)?r[i]:r[t];if("transform"!==t&&i in r){if(n){if("filter"===i){var a=parseInt(n.split("=")[1].replace(")","")),u=parseFloat(a/100);return u}return n}return W[t]}},j.close=function(){var t=this;setTimeout(function(){var e=i.indexOf(t);e===i.length-1&&r.s(),t.repeat>0&&(t._r=t.repeat),t._y&&t.reversed===!0&&(t.reverse(),t.reversed=!1),t.playing=!1},100)},r.prP=function(t,e){var i={},n=e===!0?X:Y,s=e===!0?z:Z,a=e===!0?Q:q;s={},n={};for(var o in t)if(-1!==A.indexOf(o)){if("translate"!==o&&/translate/.test(o)){var u=["X","Y","Z"],l=0;for(l;3>l;l++){var f=u[l];s["translate"+f]=/3d/.test(o)?r.pp("translate"+f,t[o][l]):"translate"+f in t?r.pp("translate"+f,t["translate"+f]):{value:0,unit:"px"}}n.translate=s}else if("rotate"!==o&&/rotate|skew/.test(o)){var p=/rotate/.test(o)?"rotate":"skew",h=["X","Y","Z"],c=0,d={},v={},a="rotate"===p?d:v;for(c;3>c;c++){var g=h[c];void 0!==t[p+g]&&"skewZ"!==o&&(a[p+g]=r.pp(p+g,t[p+g]))}n[p]=a}else("translate"===o||"rotate"===o||"scale"===o)&&(n[o]=r.pp(o,t[o]));i.transform=n}else-1===A.indexOf(o)&&(i[o]=r.pp(o,t[o]));return i},r.pp=function(t,e){if(-1!==A.indexOf(t)){var i,n=t.replace(/X|Y|Z/,"");if("translate3d"===t)return i=e.split(","),{translateX:{value:r.truD(i[0]).v,unit:r.truD(i[0]).u},translateY:{value:r.truD(i[1]).v,unit:r.truD(i[1]).u},translateZ:{value:r.truD(i[2]).v,unit:r.truD(i[2]).u}};if("translate"!==t&&"translate"===n)return{value:r.truD(e).v,unit:r.truD(e).u||"px"};if("rotate"!==t&&("skew"===n||"rotate"===n)&&"skewZ"!==t)return{value:r.truD(e).v,unit:r.truD(e,t).u||"deg"};if("translate"===t){i="string"==typeof e?e.split(","):e;var s={};return i instanceof Array?(s.x={value:r.truD(i[0]).v,unit:r.truD(i[0]).u},s.y={value:r.truD(i[1]).v,unit:r.truD(i[1]).u}):(s.x={value:r.truD(i).v,unit:r.truD(i).u},s.y={value:0,unit:"px"}),s}if("rotate"===t){var a={};return a.z={value:parseInt(e,10),unit:r.truD(e,t).u||"deg"},a}if("scale"===t)return{value:parseFloat(e,10)}}if(-1!==B.indexOf(t)||-1!==M.indexOf(t))return{value:r.truD(e).v,unit:r.truD(e).u};if(-1!==R.indexOf(t))return{value:parseFloat(e,10)};if(-1!==I.indexOf(t))return{value:parseFloat(e,10)};if(-1!==S.indexOf(t)){if(e instanceof Array)return[r.truD(e[0]),r.truD(e[1]),r.truD(e[2]),r.truD(e[3])];var o;return/rect/.test(e)?o=e.replace(/rect|\(|\)/g,"").split(/\s|\,/):/auto|none|initial/.test(e)&&(o=W[t]),[r.truD(o[0]),r.truD(o[1]),r.truD(o[2]),r.truD(o[3])]}if(-1!==C.indexOf(t))return{value:r.truC(e)};if(-1!==k.indexOf(t)){if(e instanceof Array)return{x:r.truD(e[0])||{v:50,u:"%"},y:r.truD(e[1])||{v:50,u:"%"}};var u=e.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/,50).split(/\s|\,/g),l=r.truD(u[0]),f=r.truD(u[1]);return{x:l,y:f}}if(-1!==D.indexOf(t)){var p=r.truD(e);return{value:p.v,unit:p.u}}},r.truD=function(t,e){function r(){var r,i=0;for(i;s>i;i++)"string"==typeof t&&-1!==t.indexOf(n[i])&&(r=n[i]);return r=void 0!==r?r:e?"deg":"px"}var i=parseInt(t)||0,n=["px","%","deg","rad","em","rem","vh","vw"],s=n.length,a=r();return{v:i,u:a}},r.preventScroll=function(t){var e=document.body.getAttribute("data-tweening");e&&"scroll"===e&&t.preventDefault()},r.truC=function(t){var e,i;return/rgb|rgba/.test(t)?(e=t.replace(/[^\d,]/g,"").split(","),i=e[3]?e[3]:null,i?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(i)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}):/#/.test(t)?{r:r.htr(t).r,g:r.htr(t).g,b:r.htr(t).b}:/transparent|none|initial|inherit/.test(t)?{r:0,g:0,b:0,a:0}:void 0},r.rth=function(t,e,r){return"#"+((1<<24)+(t<<16)+(e<<8)+r).toString(16).slice(1)},r.htr=function(t){var e=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(e,function(t,e,r,i){return e+e+r+r+i+i});var r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null},r.pe=function(t){if("function"==typeof t)return t;if("string"==typeof t){if(/easing|linear/.test(t))return r.Easing[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(","),i=0,n=e.length;for(i;n>i;i++)e[i]=parseFloat(e[i]);return r.Ease.bezier(e[0],e[1],e[2],e[3])}return/physics/.test(t)?r.Physics[t]():r.Ease[t]()}},r.Easing={},r.Easing.linear=function(t){return t};var K=Math.PI,U=2*Math.PI,$=Math.PI/2,G=.1,J=.4;return r.Easing.easingSinusoidalIn=function(t){return-Math.cos(t*$)+1},r.Easing.easingSinusoidalOut=function(t){return Math.sin(t*$)},r.Easing.easingSinusoidalInOut=function(t){return-.5*(Math.cos(K*t)-1)},r.Easing.easingQuadraticIn=function(t){return t*t},r.Easing.easingQuadraticOut=function(t){return t*(2-t)},r.Easing.easingQuadraticInOut=function(t){return.5>t?2*t*t:-1+(4-2*t)*t},r.Easing.easingCubicIn=function(t){return t*t*t},r.Easing.easingCubicOut=function(t){return--t*t*t+1},r.Easing.easingCubicInOut=function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},r.Easing.easingQuarticIn=function(t){return t*t*t*t},r.Easing.easingQuarticOut=function(t){return 1- --t*t*t*t},r.Easing.easingQuarticInOut=function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},r.Easing.easingQuinticIn=function(t){return t*t*t*t*t},r.Easing.easingQuinticOut=function(t){return 1+--t*t*t*t*t},r.Easing.easingQuinticInOut=function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t},r.Easing.easingCircularIn=function(t){return-(Math.sqrt(1-t*t)-1)},r.Easing.easingCircularOut=function(t){return Math.sqrt(1-(t-=1)*t)},r.Easing.easingCircularInOut=function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},r.Easing.easingExponentialIn=function(t){return Math.pow(2,10*(t-1))-.001},r.Easing.easingExponentialOut=function(t){return 1-Math.pow(2,-10*t)},r.Easing.easingExponentialInOut=function(t){return(t*=2)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*(t-1)))},r.Easing.easingBackIn=function(t){var e=1.70158;return t*t*((e+1)*t-e)},r.Easing.easingBackOut=function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},r.Easing.easingBackInOut=function(t){var e=2.5949095;return(t*=2)<1?.5*t*t*((e+1)*t-e):.5*((t-=2)*t*((e+1)*t+e)+2)},r.Easing.easingElasticIn=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,-(G*Math.pow(2,10*(t-=1))*Math.sin((t-e)*U/J)))},r.Easing.easingElasticOut=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,G*Math.pow(2,-10*t)*Math.sin((t-e)*U/J)+1)},r.Easing.easingElasticInOut=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,(t*=2)<1?-.5*G*Math.pow(2,10*(t-=1))*Math.sin((t-e)*U/J):G*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*U/J)*.5+1)},r.Easing.easingBounceIn=function(t){return 1-r.Easing.easingBounceOut(1-t)},r.Easing.easingBounceOut=function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},r.Easing.easingBounceInOut=function(t){return.5>t?.5*r.Easing.easingBounceIn(2*t):.5*r.Easing.easingBounceOut(2*t-1)+.5},r}); \ No newline at end of file diff --git a/demo/examples.html b/demo/examples.html new file mode 100644 index 0000000..3a2c981 --- /dev/null +++ b/demo/examples.html @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + KUTE.js Examples | Javascript Animation Engine + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

Quick Examples

+

KUTE.js can be used in most cases with native Javascript, but also with jQuery. So, before we head over to the more advanced examples, let's have a quick look at these two basic examples here. Note: the examples are posted on codepen.

+ +

Basic Native Javascript Example

+

When developing with native Javascript, a very basic syntax goes like this:

+ +
+// this is the tween object, basically KUTE.method(element, from, to, options);
+var tween = KUTE.fromTo('selector', {left: 0}, {left: 100}, {yoyo: true});
+
+ +

Now the tween object is created, it's a good time for you to know that via Native Javascript we always animate the first HTML element only, even if you're using a class selector. To create/control a tween for multiple elements such as querySelectorAll() or getElementsByTagName(), you need to do a for () loop. Now let's apply the tween control methods:

+
tween.start(); // starts the animation
+tween.stop(); // stops current tween and all chained tweens animating
+tween.pause(); // pauses current tween animation
+tween.play(); // or tween.resume(); resumes current tween animation
+tween.chain(tween2); // when tween animation finished, you can trigger the start of another tween
+
+

The demo for the above example is here.

+ +

Basic jQuery Example

+

KUTE.js includes a jQuery plugin to help you easily implement KUTE.js in your jQuery applications. When using jQuery, the syntax is familiar but works a bit different than plain Javascript due to jQuery's specific code standards. Let's have a look:

+
// this is the tween object, basically $('selector').KUTE(method, from, to, options);
+var tween = $('selector').KUTE('fromTo', {top: 20}, {top: 100}, {yoyo: true});
+
+

We mentioned that the KUTE jQuery plugin is different, and here's why: the above code creates an Array of objects for each HTML element of chosen selector, while the Native Javascript creates a single object. For these objects we can now apply the tween control methods as follows:

+
$(tween).KUTE('start'); // starts the animation
+$(tween).KUTE('stop'); // stops current tween and all chained tweens animating
+$(tween).KUTE('pause'); // pauses current tween animation
+$(tween).KUTE('play'); // or $(myTween).KUTE('resume'); resumes current tween animation
+$(tween).KUTE('chain',myTween2); // when tween animation finished, you can trigger the start of another tween
+
+

The demo for the above example is here.

+ +

Transform Properties Examples

+

KUTE.js supports almost all about transform as described in the spec: the 2D translate, rotate, skewX, skewY and scale, as well as the 3D translateX, translateY, translateZ, translate3d, rotateX, rotateX, rotateY, rotateZ properties. Additionally it allows you to set a perspective for the element or it's parent as well as a perpective-origin for the element or it's parent.

+ +

Translations

+

In the next example the first box is moving to left 250px with translate property, the second box is moving to the right by 200px using translateX and the third box is moving to the bottom using translate3d. The last box also uses translate3d but requires a perspective value for the animation on the Z axis to be effective.

+
var tween1 = KUTE.fromTo('selector1',{translate:0},{translate:-250}); // or translate:[x,y] for both axis
+var tween2 = KUTE.fromTo('selector2',{translateX:0},{translateX:200});
+var tween3 = KUTE.fromTo('selector3',{translate3d:[0,0,0]},{translate3d:[0,100,0]});
+var tween4 = KUTE.fromTo('selector4',{translate3d:[0,0,0]},{translate3d:[0,0,-100]},{parentPerspective: 100});
+
+

And here is how it looks like:

+
+
2D
+
X
+
Y
+
Z
+ +
+ Start +
+
+ +

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

+

Remember: stacking translate and translate3d together may not work and IE9 does not support perspective.

+ +

Rotations

+

Next we're gonna animate 4 elements with one axis each element. Unlike translations, KUTE.js does not support rotate3d.

+
var tween1 = KUTE.fromTo('selector1',{rotate:0},{rotate:-720});
+var tween2 = KUTE.fromTo('selector2',{rotateX:0},{rotateX:200});
+var tween3 = KUTE.fromTo('selector3',{rotateY:0},{rotateY:160},{perspective:100});
+var tween4 = KUTE.fromTo('selector4',{rotateZ:0},{rotateZ:360});
+
+

And here is how it looks like:

+
+
2D
+
X
+
Y
+
Z
+ +
+ Start +
+
+

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

+ +

Skews

+

KUTE.js supports skewX and skewY so let's animate the two. Since they are 2D transformations, IE9 supports skews.

+
var tween1 = KUTE.fromTo('selector1',{skewX:0},{skewX:20});
+var tween2 = KUTE.fromTo('selector2',{skewY:0},{skewY:45});
+
+ +

And here is how it looks like:

+
+
X
+
Y
+ +
+ Start +
+
+

You can download this example here.

+ +

Mixed Transformations

+

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

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

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

+ +
var tween1 = KUTE.fromTo(
+	'selector1', // element
+	{translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from
+	{translateX:250, rotateX:360, rotateY:15, rotateZ:5}, // to
+	{perspective:400, perspectiveOrigin: 'center top'} // trasform options
+);
+var tween2 = KUTE.fromTo(
+	'selector2', // element
+	{translateX:0, rotateX:0, rotateY:0, rotateZ:0}, // from values
+	{translateX:-250, rotateX:360, rotateY:15, rotateZ:5}, // to values
+	{parentPerspective:400, parentPerspectiveOrigin: 'center top'} // trasform options
+);
+
+

Now you can see we are using the specific transform options, the first tween object uses these settings for an element and the second for its parent.

+ +
+
element perspective 400px
+
parent perspective 400px
+ +
+ Start +
+
+ +

This example also shows the difference between an element's perspective and a parent's perspective. You can download the above example here.

+ +

Chained Transformations

+

I'm gonna insist on the tween chaining feature a bit because when we run animations one after another we are kinda expecting a certain degree of continuity. As explained before, the best solution is the .to() method because it has the ability to stack properties found in the element's inline styling, mostly from previous tween animation, and use them as start values for the next tween. It also transfers unchanged values to values end for that same reason. OK now, let's see a side by side comparison with 3 elements:

+
+
FROMTO
+
FROMTO
+
TO
+ +
+ Start +
+
+

What's this all about?

+
    +
  • the first box uses a regular .fromTo() object, we are doing things normally, we would expect them to work properly but due to the nature of the transforms, this is what it does
  • +
  • the second box is also using .fromTo() object, but using proper values for all tweens at all times, so we fixed that glitch
  • +
  • and the last box uses the .to() method, and does the chaining easier for most properties, especially for transform
  • +
+ +

When coding transformation chains I would highly recommend:

+
    +
  • keep the same order of the transform properties, best would be: translation, rotation, skew and scale; an example of the difference shown here for rotations and here for rotations and skew;
  • +
  • 2D and 3D translations would work best in if you provide a value at all times; eg. translate:[x,y] and translate3d:[x,y,z]; for instance using translate:150 or translateX:150 would mean that all other axis are 0;
  • +
  • on larger amount of elements animating chains, the .fromTo() method is fastest, so you will have more work, but can potentially minimize or eliminate any syncronization issues that may occur, as explained in the features page;
  • +
  • download this example here.
  • +
+ +

Border Radius

+

In the example below we are doing some animation on the border-radius property. The first box animates all corners, while the other boxes animate each corner at a time. A quick reminder, for radius properties KUTE.js supports px, % and text properties' units such as em or rem.

+
KUTE.to('selector1',{borderRadius:'100%'}).start();
+KUTE.to('selector2',{borderTopLeftRadius:'100%'}).start();
+KUTE.to('selector3',{borderTopRightRadius:'100%'}).start();
+KUTE.to('selector4',{borderBottomLeftRadius:'100%'}).start();
+KUTE.to('selector5',{borderBottomRightRadius:'100%'}).start();
+
+ +

And here is how it looks like:

+ +
+
ALL
+
TL
+
TR
+
BL
+
BR
+ +
+ Start +
+
+ +

A quick important reminder here is that KUTE.js does not support shorthands for radius properties. Also early implementations by Mozilla's Firefox browser like -moz-border-radius-topleft are not supported because they were depracated with later versions. Download this example here.

+ +

Box Model Properties

+

While KUTE.js supports almost all the box model properties, the next example will animate most common properties, we will focus mostly on size, spacing and position. Other properties such as minWidth or maxHeight require a more complex context and we won't insist on them.

+
var tween1 = KUTE.to('selector1',{width:200});
+var tween2 = KUTE.to('selector1',{height:300});
+var tween3 = KUTE.to('selector1',{left:250});
+var tween4 = KUTE.to('selector1',{top:100});
+var tween5 = KUTE.to('selector1',{padding:'5%'});
+
+

We're gonna chain these tweens and start the animation. You can download this example here.

+
+
BOX MODEL
+ +
+ Start +
+
+ + +

TIP: the width and height properties used together can be great for scale animation fallback on images for legacy browsers.

+ +

Text Properties

+

OK here we're gonna do a cool example for text properties. Basically the below code would work:

+
var tween1 = KUTE.to('selector1',{fontSize:'200%'});
+var tween2 = KUTE.to('selector1',{line-height:24});
+var tween3 = KUTE.to('selector1',{letter-spacing:50});
+
+

But our example will feature some more than just that. We're gonna animate each character of a given string, with a small delay. The heading will animate fontSize and letterSpacing properties for each character while the button will animate fontSize and lineHeight properties. Watch this:

+ +
+

Howdy!

+ Button + +
+ Start +
+
+

TIP: this should also work in IE8 as a fallback for scale animation for text. It's not perfect, can be improved for sure, but if it's a must, this would do. Download this example here.

+ +

Color Properties

+

The next example is about animating color properties. As for example, check these lines for reference.

+
KUTE.to('selector1',{color:'#069'}).start();
+KUTE.to('selector1',{backgroundColor:'#069'}).start();
+KUTE.to('selector1',{borderColor:'rgb(25,25,25)'}).start();
+KUTE.to('selector1',{borderTopColor:'#069'}).start();
+KUTE.to('selector1',{borderRightColor:'rgba(25,25,25,0.25)'}).start();
+KUTE.to('selector1',{borderBottomColor:'#069'}).start();
+KUTE.to('selector1',{borderLeftColor:'#069'}).start();
+
+

Let's get some animation going. Download the example here.

+ +
+
Colors
+ +
+ Start +
+
+ +

A quick reminder: you can also use RGB or RGBA, but the last one is not supported on IE8 and it will fallback to RGB.

+ +

Clip Property

+

This property allows you to animate the rectangular shape of an element that is set to position:absolute. In CSS this property works like this clip: rect(top,right,bottom,left) forming a rectangular shape that masks an element making parts of it invisible.

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

A quick example here could look like this:

+ +
+
+ +
+ Start +
+
+

Note that this would produce no effect for elements that have overflow:visible style rule. Download this example here.

+ +

Background Position

+

Another property we can animate with KUTE.js is backgroundPosition. Quick example:

+
KUTE.to('selector1',{backgroundPosition:[0,50]}).start();
+

A working example would look like this:

+ +
+
+ +
+ Start +
+
+

Download this example here.

+ +

Vertical Scrolling

+

Another property we can animate with KUTE.js is scrollTop. I works for both the window and any scrollable object. Quick example:

+
KUTE.to('selector',{scroll:450}).start(); // for a scrollable element
+KUTE.to('window',{scroll:450}).start(); // for the window
+
+

A working example would work like this. Scroll works with IE8+ and is a unitless property even if these scroll distances are measured in pixels.

+ + +

Cross Browser Animation Example

+

Unlike the examples hosted on Codepen, most examples here should be supported on legacy browsers. The next example is going to explain more details about how to target browsers according to their supported properties, so stick around. So, first check your HTML template to have the browser detection for IE8-IE9, then check to have the polyfills and also make sure you target your browsers, here's a complete reference. Now we are ready: + +

Collect Information And Cache It

+
// grab an HTML element to build a tween object for it 
+var element = document.getElementById("myElement");
+
+// check for IE legacy browsers
+var isIE8 = /ie8/.test(document.documentElement.className);
+var isIE9 = /ie9/.test(document.documentElement.className);
+
+// most browsers have specific checks, so make sure 
+// you include all you need for your target audience
+
+
+

Define Properties And Options Objects

+
// create values and options objects
+var startValues = {};
+var endValues = {};
+var options = {};
+
+// here we define properties that are commonly supported
+startValues.opacity = 1;
+endValues.opacity = 0.5;
+startValues.backgroundColor = '#CDDC39'; 
+endValues.backgroundColor = '#ec1e71';
+
+// here we define the properties according to the target browsers
+if (isIE8) { // or any other browser that doesn"t support transforms		
+	startValues.left = 0;
+	endValues.left = 250;
+} else if (isIE9) { // or any other browser that only support 2d transforms
+	startValues.translate = 0; // 2d translate on X axis
+	endValues.translate = 250;
+	startValues.rotate = -180; // 2d rotation on Z axis
+	endValues.rotate = 0;
+	startValues.scale = 1; // 2d scale
+	endValues.scale = 1.5;
+} else { // most modern browsers
+	startValues.translate3d = [0,0,0]; //3d translation on X axis
+	endValues.translate3d = [250,0,0];				
+	startValues.rotateZ = -180; // 3d rotation on Z axis
+	endValues.rotateZ = 0;
+	startValues.rotateX = -20; // 3d rotation on X axis
+	endValues.rotateX = 0;				
+	startValues.scale = 1; // 2d scale
+	endValues.scale = 1.5;
+	options.perspective = 400; // 3d transform option
+}
+
+// common tween options
+options.easing = "easingCubicOut";
+options.duration = 2500; 	
+
+ +

Build Tween Object And Tween Controls

+
// the cached object
+var myTween = KUTE.fromTo(element, startValues, endValues, options);
+
+// trigger buttons
+var startButton = document.getElementById('startButton'),
+	stopButton = document.getElementById('stopButton'),
+	playPauseButton = document.getElementById('playPauseButton');
+
+// add handlers for the trigger buttons
+startButton.addEventListener('click', function(e){
+	e.preventDefault();
+	if (!myTween.playing) { myTween.start(); } // only start the animation if hasn't started yet
+}, false);
+stopButton.addEventListener('click', function(e){
+	e.preventDefault();
+	if (myTween.playing) { myTween.stop(); } // only stop the animation if there is any
+}, false);
+playPauseButton.addEventListener('click', function(e){
+	e.preventDefault();	
+	if (!myTween.paused && myTween.playing) { 
+		myTween.pause(); playPauseButton.innerHTML = 'Resume';
+	} else { 
+		myTween.resume(); 
+		playPauseButton.innerHTML = 'Pause';
+	}  
+}, false);
+
+

Live Demo

+
+
+ +
+
+ Pause + Start + Stop +
+
+

Let's explain this code a bit. KUTE.js comes gives you the internal variables myTween.playing and myTween.paused (both true/false) to help you easily manage the tween control methods all together as in this example here. As said before, KUTE.js version 0.9.5 doesn't stat animating by default, for all the examples on this page you have to start it yourself, unlike their versions hosted on Codepen.

+
    +
  • the START button will use the .start() method and the animation starts;
  • +
  • the STOP button will use the .stop() method and stops the animation; after this the, animation can only be started again
  • +
  • the PAUSE button will use the .pause() method and pauses the animation; this also changes the button's text and functionality;
  • +
  • the RESUME button will use the .resume() method and resumes the animation; this reverses the button's initial state;
  • +
  • make sure you work with the conditions properly when you want to pause an animation you MUST check both !myTween.playing and myTween.paused conditions because you could end up with errors.
  • +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/demo/features.html b/demo/features.html new file mode 100644 index 0000000..3f62292 --- /dev/null +++ b/demo/features.html @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + KUTE.js Features | Javascript Animation Engine + + + + + + + + + + + + + + + + +
+ +
+ + + +
+

Delivering Killer Performance

+

KUTE.js was developed with best practices in mind for fastest code execution and memory efficiency, but performance varies from case to case, as well as for all the other Javascript based animation engines. As a quick note on how it works, well for the most part values are cached for the entire duration of the animation so that the repetitive tasks run smoothly, uninterruptible and avoid layout thrashing. We all know the more properties used or the more elements to animate at the same time, the more power is required.

+ +

Of course some would argue on many aspects, but we all trade something for the sake of something else, such as convenience and/or flexibility or fork a project that's already great to make it.. better. For the sake of performance or simply willing to provide a feature, some trade/neglect other elements such as syncronisation (check this video), code simplicity (lots of CSS for a custom animation) and more other.

+

To learn more about how performance can vary from case to case, check out this secion, it's very informative.

+
+ +
+

Break Free Of Browser Prefixes

+

KUTE.js uses a simple function to determine the vendor prefix and checks if the prefix is required. In any case it caches the prefixed/unprefixed property name in a variable to make it available when needed. This applies to the following CSS3 properties: transform, perspective, perspective-origin, border-radius and the requestAnimationFrame Javascript method.

+

We aren't only targeting properly browsers for CSS3 styling, but also increase performance because we don't need to update the styling on every frame for all browsers (and their versions) at once, just the right and only one; less string concatenation = more performance. This asumes you are NOT styling the above CSS3 properties using your stylesheets to avoid glitches with legacy browsers.

+

This feature is useful mostly for Safari, older Firefox and Opera versions and Internet Explorer 9.

+
+ +
+

Browser Compatibility

+

KUTE.js covers all modern browsers but also provides fallback options for legacy browsers. The prefix free feature mentioned above is one way to enable smooth Javascript based animations on older versions Gecko/Webkit/IE browsers for transform and border-radius. Generally, KUTE.js is built around most used properties, so I highly recommend checking the can I use website for a very detailed properties support list on many browsers and versions. For instance legacy browsers may support 2D transforms or 3D transforms so make sure you know what browsers support and how to target them before you get to work with a complete browser supported animation setup.

+

I've put a lot of work in making KUTE.js work with all Internet Explorer versions starting with IE8 and it really works with the help of polyfills and an appropriate HTML template. All you need to do is to let the browser breathe, espectially IE8 needs to have resize handlers as minimal as possible. On the other side, IE9 really shines with 2D transforms animation, something that's impossible with CSS transition.

+

Speaking of polyfills, KUTE.js requires window.requestAnimationFrame() for the main thread, window.performance.now() for checking the current time, .indexOf() for array checks, window.getComputedStyle() for the .to() method and .addEventListener() for scroll. Unlike other developers I didn't include these polyfills in the code to keep it clean, so that YOU decide whether your project need them or not. Also know that when using the recommended polyfill service some browser detection will not work because they fill the gap and your code won't work as expected. For instance this would check for IE8 browser var isIE = document.all && !document.addEventListener; but the polyfill covers .addEventListener() so you will never succeed. The provided ideal HTML template is the best solution for targeting Microsoft's legacy browsers.

+

As of Safari, we did some tests there too, KUTE.js does it really well.

+
+ +
+

Methods, Tools and Options

+

Building Tween Objects

+

KUTE.js allows you to create tween objects with the help of .to() and .fromTo() public methods, with distinctive functionalities.

+

KUTE.to('selector', toValues, options) method is super simple and straightforward and requires a polyfill for window.getComputedStyle() Javascript method on IE8 and more other legacy browsers in order to read the current property value. If no value is set in the stylesheets or inline style, a property specific value will be used. It also computes the value on animation start, delaying the actual animation and potentially creating sync issues on large amounts of elements, but it has the great ability to stack transform properties as they come in chained tweens. However fixing the sync issues is not that hard, see the example at start() method API.

+

KUTE.fromTo('selector', fromValues, toValues, options) is the other method that's most powerful in terms of performance, flexibility and control on the animation. As an example, while the first method may not process properties' measurement units properly, this method will never fail in that regard, because you can set for both starting values and end values the exact values with the right unit you need.

+ +

It doesn't stack transform properties for chained tweens but you can set all properties to be used in all tweens if you want (end values from previous tween become start values for the next AND unchanged start values become end values), and make sure nothing is left unchecked, to avoid animation glitches. Still, this method is the fastest and bestest for super performance and super control.

+ +

Tween Control

+

Unlike previous versions where animations started right away, starting with version 0.9.5 KUTE.js gives you great animation control methods such as: .start(), .stop(), .pause() and .resume(). These public methods work either when animation is running or is paused. You need to see the documentation to learn how these work.

+ +

Tween Options

+

Aside from the usual options such as duration, delay, easing, repeat or yoyo, it also comes with specific tween options for transform. For instance 3D rotations require a perspective or a perspective-origin, right?

+ +

Callback System

+

Another important KUTE.js feature is the solid callback system. This allows you to schedule functions to run on animation start, on each frame, on pause / resume, on stop and on complete. The functions bound at start or resume will delay the animation, while the functions running on each frame can potentially influence performance on large amounts of elements so you must use them wisely.

+ +

Addons

+

KUTE.js sports some fine tuned addons: jQuery Plugin, cubic bezier easing functions and also physics based easing functions. I am also considering to feature an attributes plugin as well as SVG library and maybe other tools in the future.

+ +

Check the documentation on these methods and the examples page for more.

+
+ +
+

Support For Plenty Of Properties

+

KUTE.js covers all animation needs such as most transform properties, scroll for window or a given element, colors, border-radius, and almost the full box model. Due to it's modular coding, KUTE.js is very flexible and makes it very easy to add support for more properties, but I'm considering removing unnecessary properties in the future (mostly from the box model category). Note: not all browsers support 2D transforms or 3D transforms.

+

All common measurement units are supported: px and % for translations and box-model properties, or deg and rad for rotations and skews, while clip only supports px. Other properties such as opacity, scale or scroll are unitless, and background-position always uses % as measurement unit. As for the text properties you can use px, em, rem, vh and vw. Be sure to check what your browsers support in terms of measurement unit.

+ +

Opacity

+

In most cases, the best animation possible is the opacity, for performance, aesthetics and maybe more other reasons such as avoiding unwanted layout changes. KUTE.js also covers IE8 here with the help of proprietary synthax filter: alpha(opacity=0) but requires that you use the provided HTML template in order to detect the browser. Also, opacity can be used for instance on legacy browsers that don't support RGBA colors. Eg. opacity:0.5 will make an element semitransparent.

+ +

2D Transform Properties

+
    +
  • translate property can be used for horizontal and / or vertical movement. EG. translate:150 to translate an element 150px to the right or translate:[-150,200] to move the element to the left by 150px and to bottom by 200px. Supported on IE9.
  • +
  • rotate is a property used to rotate an element on the Z axis or the plain document. Eg. rotate:250 will rotate an element clockwise by 250 degrees. Supported on IE9.
  • +
  • skewX is a property used to apply a skew transformation on the X axis. Eg. skewX:25 will skew an element by 25 degrees. Supported on IE9.
  • +
  • skewY is a property used to apply a skew transformation on the Y axis. Eg. skewY:25 will skew an element by 25 degrees. Supported on IE9.
  • +
  • scale is a property used to apply a size transformation. Eg. scale:2 will enlarge an element by a degree of 2. Supported on IE9.
  • +
  • matrix property is not supported.
  • +
+ +

3D Transform Properties

+
    +
  • translateX property is for horizontal movement. EG. translateX:150 to translate an element 150px to the right. Modern browsers only.
  • +
  • translateY property is for vertical movement. EG. translateY:-250 to translate an element 250px towards the top. Modern browsers only.
  • +
  • translateZ property is for movement on the Z axis in a given 3D field. EG. translateZ:-250 to translate an element 250px to it's back, making it smaller. Modern browsers only and requires a perspective tween option to be used; the smaller perspective value, the deeper translation.
  • +
  • translate3d property is for movement on all the axis in a given 3D field. EG. translate3d:[-150,200,150] to translate an element 150px to the left, 200px to the bottom and 150px closer to the viewer, making it larger. Modern browsers only and also requires using a perspective tween option.
  • +
  • rotateX property rotates an element on the X axis in a given 3D field. Eg. rotateX:250 will rotate an element clockwise by 250 degrees. Modern browsers only and requires perspective.
  • +
  • rotateY property rotates an element on the Y axis in a given 3D field. Eg. rotateY:-150 will rotate an element counter-clockwise by 150 degrees. Modern browsers only and also requires perspective.
  • +
  • rotateZ property rotates an element on the Z axis and is the equivalent of the 2D rotation. Eg. rotateZ:-150 will rotate an element counter-clockwise by 150 degrees. Modern browsers only and doesn't require perspective.
  • +
  • rotate3d and matrix3d properties are not supported.
  • +
+ +

Box Model Properties

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

Remember: these properties are layout modifiers that may force repaint of the entire DOM, drastically affecting performance on lower end and mobile devices. They also trigger resize event that may cause crashes on old browsers such as IE8 when using handlers bound on resize, so use with caution.

+ +

Border Radius

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

For all radius properties above borderRadius:20 or borderTopLeftRadius:'25%' will do. In the first case px is the default measurement unit used, while in the second we require using % unit which is relative to the element's size.

+

Remember: shorthands for border-radius are not supported. Also KUTE.js does not cover early implementations by Mozilla Firefox (Eg. -moz-border-radius-topleft) as they were deprecated with later versions.

+ +

Color Properties

+

KUTE.js currently supports values such as HEX, RGB and RGBA for all color properties, but IE8 does not support RGBA and always uses RGB when detected, otherwise will produce no effect. There is also a tween option keepHex:true to convert the color format. Eg. color: '#ff0000' or backgroundColor: 'rgb(202,150,20)' or borderColor: 'rgba(250,100,20,0.5)'

+
    +
  • color allows you to animate the color for a given text element.
  • +
  • backgroundColor allows you to animate the background-color for a given element.
  • +
  • borderColor allows you to animate the border-color on all sides for a given element.
  • +
  • borderTopColor, borderRightColor, borderBottomColor and borderLeftColor properties allow you to animate the color of the border on each side of a given element.
  • +
+

Remember: shorthands for border-color property as well as web color names (Eg. red, green, olive, etc.) are not supported.

+ +

Text Properties

+

These properties can be combinated with each other when applied to text elements (paragraphs, headings) as animation fallback for scale on browsers that don't support transform at all. Yes, IE8 and other legacy browsers.

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

Remember: these properties are also layout modifiers.

+ +

Scroll Animation

+

KUTE.js currently supports only vertical scroll for both the window and a given element that's scrollable. Both scroll: 150 or scrollTop: 150 notations will do. When animating scroll, KUTE.js will disable all scroll and swipe handlers to prevent animation bubbles.

+ +

Other properties

+
    +
  • clip allows you to animate the clip property for a given element. Only rect is supported. Eg. clip:[250,200,300,0]. See spec for details.
  • +
  • backgroundPosition allows you to animate the background-position for a given element that uses a background image. It only uses % as measurement unit. Eg. backgroundPosition:[50,20]
  • +
+ +

Did We Miss Any Important Property?

+

Make sure you go to the issues tracker and report the missing property ASAP.

+
+ +
+

Developer Friendly

+

You can develop with KUTE.js for free thanks to the MIT License terms. The terms in short allow you to use the script for free in both personal and commercial application as long as you give proper credits to the original author. Also a link back would be appreciated.

+

Also KUTE.js is super documented, all features and options are showcased with detailed examples so you can get your hands really dirty.

+ + +
+ + + + +
+ + + + + + + + + + + + diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..1e931f4 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + KUTE.js | Javascript Animation Engine + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+
+
+
+

Welcome Developers!

+

KUTE.js is a Javascript animation engine with top performance, memory efficient & modular code. It delivers a whole bunch of tools to help you create great custom animations.

+

+ Download + Github + CDN + Replay +

+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+

At A Glance

+
+
+

Killer Performance

+

KUTE.js is crazy fast with it's outstanding performance, with super fast code execution, it's also memory efficient. I made a cool demo to showcase how KUTE.js really scales on performance.

+
+
+

Prefix Free

+

KUTE.js can detect if the user's browser requires prefix and uses it accordingly for requestAnimationFrame, transform and border-radius, hustle free for older Gecko/Webkit/IE browsers.

+
+
+
+
+

All Browsers Compatible

+

KUTE.js covers all modern browsers with fallback options for legacy browsers. When using polyfills and the provided demo HTML templates you can manage all kinds of fallback animations for legacy browsers.

+
+
+

Powerful Methods

+

KUTE.js allows you to create tweens and chainable tweens, gives you tween control methods (stop/pause/resume/restart) and comes with full spectrum tween options.

+
+
+
+
+

Packed With Tools

+

KUTE.js comes with tools to help you configure awesome animations: jQuery plugin, cubic-bezier and physics easing functions, color convertors, and a lot of options to play with.

+
+
+

Plenty Of Properties

+

KUTE.js covers all animation needs such as transform, scroll (window or other elements), colors (border, background and text), border-radius, almost the full box model and also text properties.

+
+
+
+
+

MIT License

+

You can develop with KUTE.js for free thanks to the MIT License terms.

+
+
+

Top Notch Documentation

+

All examples, code, tips & tricks are very well documented.

+
+
+
+
+ +
+

Getting Started

+
+
+ +

Examples

+

See KUTE.js in action with all it's functions, options and features.

+
+
+ +

Documentation

+

The API documentation is here for you to get you started.

+
+ +
+ +

Performance

+

Head over to the performance test page right away.

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

Back to KUTE.js

+

Engine

+ + + + + +

Property

+ + + + + + +

Repeat

+ + + + + + +

How many elements to animate:

+ + + + + + + + +
+ +
+ +
+ +

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

+

The hack refers to adding a blank transform translate3d(0px,0px,0px); for the elements to promote them into separate layers, as described here.

+

Do not try this test on lower end or mobile devices.

+ +
+
+ + + + + + + + + + + + + + diff --git a/demo/src/kute-bezier.js b/demo/src/kute-bezier.js new file mode 100644 index 0000000..44c23b9 --- /dev/null +++ b/demo/src/kute-bezier.js @@ -0,0 +1,159 @@ +/* + * KUTE.js - The Light Tweening Engine | dnp_theme + * package bezier easing + * BezierEasing by Gaëtan Renaudeau 2014 – MIT License + * optimized by dnp_theme 2015 – MIT License + * Licensed under MIT-License +*/ + +KUTE.Ease = {}; + +KUTE.Ease.bezier = function(mX1, mY1, mX2, mY2) { + return _bz.pB(mX1, mY1, mX2, mY2); +}; + +var _bz = KUTE.Ease.bezier.prototype; + +// These values are established by empiricism with tests (tradeoff: performance VS precision) +_bz.ni = 4; // NEWTON_ITERATIONS +_bz.nms = 0.001; // NEWTON_MIN_SLOPE +_bz.sp = 0.0000001; // SUBDIVISION_PRECISION +_bz.smi = 10, // SUBDIVISION_MAX_ITERATIONS + +_bz.ksts = 11; // k Spline Table Size +_bz.ksss = 1.0 / (_bz.ksts - 1.0); // k Sample Step Size + +_bz.f32as = 'Float32Array' in window; // float32ArraySupported +_bz.msv = _bz.f32as ? new Float32Array (_bz.ksts) : new Array (_bz.ksts); // m Sample Values + +_bz.A = function(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }; +_bz.B = function(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }; +_bz.C = function(aA1) { return 3.0 * aA1; }; + +_bz.r = {}; +_bz.pB = function (mX1, mY1, mX2, mY2) { +this._p = false; var self = this; + +_bz.r = function(aX){ + if (!self._p) _bz.pc(mX1, mX2, mY1, mY2); + if (mX1 === mY1 && mX2 === mY2) return aX; + + if (aX === 0) return 0; + if (aX === 1) return 1; + return _bz.cB(_bz.gx(aX, mX1, mX2), mY1, mY2); +}; +return _bz.r; +}; + +// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. +_bz.cB = function(aT, aA1, aA2) { // calc Bezier + return ((_bz.A(aA1, aA2)*aT + _bz.B(aA1, aA2))*aT + _bz.C(aA1))*aT; +}; + +// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. +_bz.gS = function (aT, aA1, aA2) { // getSlope + return 3.0 * _bz.A(aA1, aA2)*aT*aT + 2.0 * _bz.B(aA1, aA2) * aT + _bz.C(aA1); +}; + +_bz.bS = function(a, aA, aB, mX1, mX2) { // binary Subdivide + var x, t, i = 0, j = _bz.sp, y = _bz.smi; + do { + t = aA + (aB - aA) / 2.0; + x = _bz.cB(t, mX1, mX2) - a; + if (x > 0.0) { + aB = t; + } else { + aA = t; + } + } while (Math.abs(x) > j && ++i < y); + return t; +}; + +_bz.nri = function (aX, agt, mX1, mX2) { // newton Raphs on Iterate +var i = 0, j = _bz.ni; + for (i; i < j; ++i) { + var cs = _bz.gS(agt, mX1, mX2); + if (cs === 0.0) return agt; + var x = _bz.cB(agt, mX1, mX2) - aX; + agt -= x / cs; + } + return agt; +}; + +_bz.csv = function (mX1, mX2) { // calc Sample Values +var i = 0, j = _bz.ksts; + for (i; i < j; ++i) { + _bz.msv[i] = _bz.cB(i * _bz.ksss, mX1, mX2); + } +}; + +_bz.gx = function (aX,mX1,mX2) { //get to X + var iS = 0.0, cs = 1, ls = _bz.ksts - 1; + + for (; cs != ls && _bz.msv[cs] <= aX; ++cs) { + iS += _bz.ksss; + } + --cs; + + // Interpolate to provide an initial guess for t + var dist = (aX - _bz.msv[cs]) / (_bz.msv[cs+1] - _bz.msv[cs]), + gt = iS + dist * _bz.ksss, + ins = _bz.gS(gt, mX1, mX2), + fiS = iS + _bz.ksss; + + if (ins >= _bz.nms) { + return _bz.nri(aX, gt, mX1, mX2); + } else if (ins === 0.0) { + return gt; + } else { + return _bz.bS(aX, iS, fiS, mX1, mX2); + } +}; + +_bz.pc = function(mX1, mX2, mY1, mY2) { + this._p = true; +if (mX1 != mY1 || mX2 != mY2) + _bz.csv(mX1, mX2); +}; + +// predefined bezier based easings, can be accessed via string, eg 'easeIn' or 'easeInOutQuart' +// _easings = ["linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInExpo","easeOutExpo","easeInOutExpo","slowMo","slowMo1","slowMo2"], +KUTE.Ease.easeIn = function(){ return _bz.pB(0.42, 0.0, 1.00, 1.0); }; +KUTE.Ease.easeOut = function(){ return _bz.pB(0.00, 0.0, 0.58, 1.0); }; +KUTE.Ease.easeInOut = function(){ return _bz.pB(0.50, 0.16, 0.49, 0.86); }; + +KUTE.Ease.easeInSine = function(){ return _bz.pB(0.47, 0, 0.745, 0.715); }; +KUTE.Ease.easeOutSine = function(){ return _bz.pB(0.39, 0.575, 0.565, 1); }; +KUTE.Ease.easeInOutSine = function(){ return _bz.pB(0.445, 0.05, 0.55, 0.95); }; + +KUTE.Ease.easeInQuad = function () { return _bz.pB(0.550, 0.085, 0.680, 0.530); }; +KUTE.Ease.easeOutQuad = function () { return _bz.pB(0.250, 0.460, 0.450, 0.940); }; +KUTE.Ease.easeInOutQuad = function () { return _bz.pB(0.455, 0.030, 0.515, 0.955); }; + +KUTE.Ease.easeInCubic = function () { return _bz.pB(0.55, 0.055, 0.675, 0.19); }; +KUTE.Ease.easeOutCubic = function () { return _bz.pB(0.215, 0.61, 0.355, 1); }; +KUTE.Ease.easeInOutCubic = function () { return _bz.pB(0.645, 0.045, 0.355, 1); }; + +KUTE.Ease.easeInQuart = function () { return _bz.pB(0.895, 0.03, 0.685, 0.22); }; +KUTE.Ease.easeOutQuart = function () { return _bz.pB(0.165, 0.84, 0.44, 1); }; +KUTE.Ease.easeInOutQuart = function () { return _bz.pB(0.77, 0, 0.175, 1); }; + +KUTE.Ease.easeInQuint = function(){ return _bz.pB(0.755, 0.05, 0.855, 0.06); }; +KUTE.Ease.easeOutQuint = function(){ return _bz.pB(0.23, 1, 0.32, 1); }; +KUTE.Ease.easeInOutQuint = function(){ return _bz.pB(0.86, 0, 0.07, 1); }; + +KUTE.Ease.easeInExpo = function(){ return _bz.pB(0.95, 0.05, 0.795, 0.035); }; +KUTE.Ease.easeOutExpo = function(){ return _bz.pB(0.19, 1, 0.22, 1); }; +KUTE.Ease.easeInOutExpo = function(){ return _bz.pB(1, 0, 0, 1); }; + +KUTE.Ease.easeInCirc = function(){ return _bz.pB(0.6, 0.04, 0.98, 0.335); }; +KUTE.Ease.easeOutCirc = function(){ return _bz.pB(0.075, 0.82, 0.165, 1); }; +KUTE.Ease.easeInOutCirc = function(){ return _bz.pB(0.785, 0.135, 0.15, 0.86); }; + +KUTE.Ease.easeInBack = function(){ return _bz.pB(0.600, -0.280, 0.735, 0.045); }; +KUTE.Ease.easeOutBack = function(){ return _bz.pB(0.175, 0.885, 0.320, 1.275); }; +KUTE.Ease.easeInOutBack = function(){ return _bz.pB(0.68, -0.55, 0.265, 1.55); }; + +KUTE.Ease.slowMo = function(){ return _bz.pB(0.000, 0.500, 1.000, 0.500); }; +KUTE.Ease.slowMo1 = function(){ return _bz.pB(0.000, 0.700, 1.000, 0.300); }; +KUTE.Ease.slowMo2 = function(){ return _bz.pB(0.000, 0.900, 1.000, 0.100); }; \ No newline at end of file diff --git a/demo/src/kute-jquery.js b/demo/src/kute-jquery.js new file mode 100644 index 0000000..08b4ead --- /dev/null +++ b/demo/src/kute-jquery.js @@ -0,0 +1,26 @@ +/* KUTE.js - The Light Tweening Engine + * package jQuery Plugin + * by dnp_theme + * Licensed under MIT-License + */ + +(function($) { + $.fn.KUTE = function( method, start, end, ops ) { // method can be Animate(), fromTo(), to(), stop(), start(), chain(), pause() + var tws = [], i, l = this.length; + + for (i=0;i 0.001) { + _kpg.L = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + _kpg.L * bounciness, + H: curve.H * bounciness * bounciness + }; + } + return curve.b; + })(); + + (function() { + var L2, b, curve, _results; + b = Math.sqrt(2 / (gravity * _kpg.L * _kpg.L)); + curve = { + a: -b, + b: b, + H: 1 + }; + if (initialForce) { + curve.a = 0; + curve.b = curve.b * 2; + } + curves.push(curve); + L2 = _kpg.L; + _results = []; + while (curve.b < 1 && curve.H > 0.001) { + L2 = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + L2 * bounciness, + H: curve.H * elasticity + }; + _results.push(curves.push(curve)); + } + return _results; + })(); + _kpg.fn = function(t) { + var curve, i, v; + i = 0; + curve = curves[i]; + while (!(t >= curve.a && t <= curve.b)) { + i += 1; + curve = curves[i]; + if (!curve) { + break; + } + } + if (!curve) { + v = initialForce ? 0 : 1; + } else { + v = _kpg.getPointInCurve(curve.a, curve.b, curve.H, t, options, _kpg.L); + } + return v; + }; + + return _kpg.fn; +}; + +var _kpg = _kp.gravity.prototype; +_kpg.L = {}; +_kpg.fn = {}; +_kpg.getPointInCurve = function(a, b, H, t, o, L) { + var c, t2; + L = b - a; + t2 = (2 / L) * t - 1 - (a * 2 / L); + c = t2 * t2 * H - H + 1; + if (o.initialForce) { + c = 1 - c; + } + return c; +}; + +//throw up and pull down by gravity +_kp.forceWithGravity = function(o) { + var ops = o || {}; + ops.initialForce = true; + return _kp.gravity(ops); +}; + + +// multi point bezier +_kp.bezier = function(options) { + options = options || {}; + var points = options.points, + returnsToSelf = false, Bs = []; + + (function() { + var i, k; + + for (i in points) { + k = parseInt(i); + if (k >= points.length - 1) { + break; + } + _kpb.fn(points[k], points[k + 1], Bs); + } + return Bs; + })(); + + _kpb.run = function(t) { + if (t === 0) { + return 0; + } else if (t === 1) { + return 1; + } else { + return _kpb.yForX(t, Bs, returnsToSelf); + } + }; + return _kpb.run; +}; + +var _kpb = _kp.bezier.prototype; +_kpb.B2 = {}; +_kpb.run = {}; + +_kpb.fn = function(pointA, pointB, Bs) { + var B2 = function(t) { + return _kpb.Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB); + }; + return Bs.push(B2); +}; + +_kpb.Bezier = function(t, p0, p1, p2, p3) { + return { + x: (Math.pow(1 - t, 3) * p0.x) + (3 * Math.pow(1 - t, 2) * t * p1.x) + (3 * (1 - t) * Math.pow(t, 2) * p2.x) + Math.pow(t, 3) * p3.x, + y: (Math.pow(1 - t, 3) * p0.y) + (3 * Math.pow(1 - t, 2) * t * p1.y) + (3 * (1 - t) * Math.pow(t, 2) * p2.y) + Math.pow(t, 3) * p3.y + }; +}; + +_kpb.yForX = function(xTarget, Bs, rTS) { + var B, aB, i, lower, percent, upper, x, xT, _i = 0, _len = Bs.length; + B = null; + for (_i; _i < _len; _i++) { + aB = Bs[_i]; + if (xTarget >= aB(0).x && xTarget <= aB(1).x) { + B = aB; + } + if (B !== null) { + break; + } + } + if (!B) { + return ( rTS ? 0 : 1 ); + } + xT = 0.0001; // xTolerance + lower = 0; upper = 1; + percent = (upper + lower) / 2; + x = B(percent).x; i = 0; + while (Math.abs(xTarget - x) > xT && i < 100) { + if (xTarget > x) { + lower = percent; + } else { + upper = percent; + } + percent = (upper + lower) / 2; + x = B(percent).x; + i++; + } + return B(percent).y; +}; + +_kp.physicsInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] } ] }); +}; + +_kp.physicsIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 1, y: 1 } ] } ] }); +}; + +_kp.physicsOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0, y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] }] }); +}; + +_kp.physicsBackOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0,"y":0}]},{"x":1,"y":1,"cp":[{"x":0.735+(friction/1000),"y":1.3}]}] }); +}; + +_kp.physicsBackIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.28-(friction / 1000),"y":-0.6}]},{"x":1,"y":1,"cp":[{"x":1,"y":1}]}] }); +}; + +_kp.physicsBackInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.68-(friction / 1000),"y":-0.55}]},{"x":1,"y":1,"cp":[{"x":0.265+(friction / 1000),"y":1.45}]}] }); +}; \ No newline at end of file diff --git a/demo/src/kute.js b/demo/src/kute.js new file mode 100644 index 0000000..c9e5019 --- /dev/null +++ b/demo/src/kute.js @@ -0,0 +1,855 @@ +/* KUTE.js - The Light Tweening Engine + * by dnp_theme + * Licensed under MIT-License + */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['KUTE'], factory); // AMD. Register as an anonymous module. + } else if (typeof exports == 'object') { + module.exports = factory(); // Node, not strict CommonJS + } else { + // Browser globals + root.KUTE = root.KUTE || factory(); + } +}(this, function () { + var K = K || {}, _tws = [], _t, _stk = false, // _stoppedTick // _tweens // KUTE, _tween, _tick, + _pf = getPrefix(), // prefix + _rafR = _rafR || ((!('requestAnimationFrame' in window)) ? true : false), // is prefix required for requestAnimationFrame + _pfT = _pfT || ((!('transform' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for transform + _pfB = _pfB || ((!('border-radius' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for border-radius + _tch = _tch || (('ontouchstart' in window || navigator.msMaxTouchPoints) || false), // support Touch? + _ev = _ev || (_tch ? 'touchstart' : 'mousewheel'), //event to prevent on scroll + + _bd = document.body, + _htm = document.getElementsByTagName('HTML')[0], + _sct = (/webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? _bd : _htm), + + _isIE = /ie/.test(document.documentElement.className), + _isIE8 = /ie8/.test(document.documentElement.className), + + //assign preffix to DOM properties + _pfp = _pfp || _pfT ? _pf + 'Perspective' : 'perspective', + _pfo = _pfo || _pfT ? _pf + 'PerspectiveOrigin' : 'perspectiveOrigin', + _tr = _tr || _pfT ? _pf + 'Transform' : 'transform', + _br = _br || _pfB ? _pf + 'BorderRadius' : 'borderRadius', + _brtl = _brtl || _pfB ? _pf + 'BorderTopLeftRadius' : 'borderTopLeftRadius', + _brtr = _brtr || _pfB ? _pf + 'BorderTopRightRadius' : 'borderTopRightRadius', + _brbl = _brbl || _pfB ? _pf + 'BorderBottomLeftRadius' : 'borderBottomLeftRadius', + _brbr = _brbr || _pfB ? _pf + 'BorderBottomRightRadius' : 'borderBottomRightRadius', + _raf = _raf || _rafR ? window[_pf + 'RequestAnimationFrame'] : window['requestAnimationFrame'], + _caf = _caf || _rafR ? window[_pf + 'CancelAnimationFrame'] : window['cancelAnimationFrame'], + + //supported properties + _cls = ['color', 'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0) + _sc = ['scrollTop', 'scroll'], //scroll, it has no default value, it's calculated on tween start + _clp = ['clip'], // clip + _op = ['opacity'], // opacity + _rd = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'], // border radius px/any + _bm = ['top', 'left', 'right', 'bottom', + 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', + 'padding', 'margin', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'marginTop','marginBottom', 'marginLeft', 'marginRight', + 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'], // dimensions / box model + _tp = ['fontSize','lineHeight','letterSpacing'], // text properties + _bg = ['backgroundPosition'], // background position + _3d = ['rotateX', 'rotateY','translateZ'], // transform properties that require perspective + _tf = ['translate3d', 'translateX', 'translateY', 'translateZ', 'rotate', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scale'], // transform + _all = _cls.concat(_sc, _clp, _op, _rd, _bm, _tp, _bg, _tf), al = _all.length, + _tfS = {}, _tfE = {}, _tlS = {}, _tlE = {}, _rtS = {}, _rtE = {}, //internal temp + _d = _d || {}; //all properties default values + + //populate default values object + for ( var i=0; i< al; i++){ + var p = _all[i]; + if (_cls.indexOf(p) !== -1){ + _d[p] = 'rgba(0,0,0,0)'; // _d[p] = {r:0,g:0,b:0,a:1}; + } else if ( _rd.indexOf(p) !== -1 || _bm.indexOf(p) !== -1 || _tp.indexOf(p) !== -1) { + _d[p] = 0; + } else if ( _bg.indexOf(p) !== -1 ){ + _d[p] = [50,50]; + } else if ( p === 'clip' ){ + _d[p] = [0,0,0,0]; + } else if ( p === 'translate3d' ){ + _d[p] = [0,0,0]; + } else if ( p === 'translate' ){ + _d[p] = [0,0]; + } else if ( p === 'rotate' || /X|Y|Z/.test(p) ){ + _d[p] = 0; + } else if ( p === 'scale' || p === 'opacity' ){ + _d[p] = 1; + } + } + + //more internals + K.getAll = function () { return _tws; }; + K.removeAll = function () { _tws = []; }; + K.add = function (tw) { _tws.push(tw); }; + K.remove = function (tw) { + var i = _tws.indexOf(tw); + if (i !== -1) { + _tws.splice(i, 1); + } + }; + + // internal ticker + K.t = function (t) { + _t = _raf(K.t); + var i = 0, l = _tws.length; + while ( i < l ) { + if (!_tws[i]) { return false; } + if (_tws[i].u(t)) { + i++; + } else { + _tws.splice(i, 1); + } + } + _stk = false; + return true; + }; + + // internal stopTick + K.s = function () { + if ( _stk === false ) { + _caf(_t); + _stk = true; + _t = null; + } + }; + + //main methods + K.to = function (el, to, o) { + if ( o === undefined ) { o = {}; } + var _el = _el || typeof el === 'object' ? el : document.querySelector(el), + _o = _o || o; + _o.rpr = true; + _o.easing = _o && K.pe(_o.easing) || K.Easing.linear; + + var _vS = to, // we're gonna have to build this object at start + _vE = K.prP(to, true), + _tw = new K.Tween(_el, _vS, _vE, _o); + return _tw; + }; + + K.fromTo = function (el, f, to, o) { + if ( o === undefined ) { o = {}; } + var _el = _el || typeof el === 'object' ? el : document.querySelector(el); + var _o = o; + + _o.easing = _o && K.pe(_o.easing) || K.Easing.linear; + + var _vS = K.prP(f, false), + _vE = K.prP(to, true), + _tw = new K.Tween(_el, _vS, _vE, _o); + return _tw; + }; + // fallback method for previous versions + K.Animate = function (el, f, to, o) { + return K.fromTo(el, f, to, o); + }; + + // render for each property + K.r = function (w,v) { + var p, css = w._el && w._el.style, opp = _isIE8 ? 'filter':'opacity', + ets = (w._el === undefined || w._el === null) ? _sct : w._el; + for (p in w._vE) { + + var _start = w._vS[p], + _end = w._vE[p], + v1 = _start.value, + v2 = _end.value, + tv = v1 + (v2 - v1) * v, + u = _end.unit, + // checking array on every frame takes time so let's cache these + cls = _cls.indexOf(p) !== -1, + bm = _tp.indexOf(p) !== -1 || _bm.indexOf(p) !== -1, + rd = _rd.indexOf(p) !== -1 && !_isIE8, + sc = _sc.indexOf(p) !== -1, + bg = _bg.indexOf(p) !== -1, + clp = _clp.indexOf(p) !== -1, + op = _op.indexOf(p) !== -1, + tf = p === 'transform' && !_isIE8; + + //process styles by property / property type + if ( rd ) { + if (p === 'borderRadius') { + css[_br] = tv + u; + } else if (p === 'borderTopLeftRadius') { + css[_brtl] = tv + u; + } else if (p === 'borderTopRightRadius') { + css[_brtr] = tv + u; + } else if (p === 'borderBottomLeftRadius') { + css[_brbl] = tv + u; + } else if (p === 'borderBottomRightRadius') { + css[_brbr] = tv + u; + } + + } else if (tf) { + var _tS = '', tP, rps, pps = 'perspective('+w._pp+'px) '; //transform style & property + + for (tP in _end) { + var t1 = _start[tP], t2 = _end[tP]; + rps = _3d.indexOf(tP) !== -1 && !_isIE; + + if ( tP === 'translate' ) { + var tls = '', ts = {}, ax; + + for (ax in t2){ + var x1 = t1[ax].value || 0, x2 = t2[ax].value || 0, xu = t2[ax].unit || 'px'; + ts[ax] = x1===x2 ? x2+xu : (x1 + ( x2 - x1 ) * v) + xu; + } + tls = t2.x ? 'translate(' + ts.x + ',' + ts.y + ')' : + 'translate3d(' + ts.translateX + ',' + ts.translateY + ',' + ts.translateZ + ')'; + + _tS = (_tS === '') ? tls : (tls + ' ' + _tS); + } else if ( tP === 'rotate' ) { + var rt = '', rS = {}, rx; + + for ( rx in t2 ){ + if ( t1[rx] ) { + var a1 = t1[rx].value, a2 = t2[rx].value, au = t2[rx].unit||'deg', + av = a1 + (a2 - a1) * v; + rS[rx] = rx ==='z' ? 'rotate('+av+au+')' : rx + '(' + av + au + ') '; + } + } + rt = t2.z ? rS.z : (rS.rotateX||'') + (rS.rotateY||'') + (rS.rotateZ||''); + + _tS = (_tS === '') ? rt : (_tS + ' ' + rt); + } else if (tP==='skew') { + var sk = '', sS = {}; + for ( var sx in t2 ){ + if ( t1[sx] ) { + var s1 = t1[sx].value, s2 = t2[sx].value, su = t2[sx].unit||'deg', + sv = s1 + (s2 - s1) * v; + sS[sx] = sx + '(' + sv + su + ') '; + } + } + sk = (sS.skewX||'') + (sS.skewY||''); + _tS = (_tS === '') ? sk : (_tS + ' ' + sk); + } else if (tP === 'scale') { + var sc1 = t1.value, sc2 = t2.value, + s = sc1 + (sc2 - sc1) * v, scS = tP + '(' + s + ')'; + _tS = (_tS === '') ? scS : (_tS + ' ' + scS); + } + } + css[_tr] = rps || ( w._pp !== undefined && w._pp !== 0 ) ? pps + _tS : _tS; + } else if ( cls ) { + var _c = {}, c; + + for (c in v2) { + if ( c !== 'a' ){ + _c[c] = parseInt(v1[c] + (v2[c] - v1[c]) * v)||0; + } else { + _c[c] = (v1[c] && v2[c]) ? parseFloat(v1[c] + (v2[c] - v1[c]) * v) : null; + } + } + + if ( w._hex ) { + css[p] = K.rth( parseInt(_c.r), parseInt(_c.g), parseInt(_c.b) ); + } else { + css[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')'; + } + } else if ( bm ) { + css[p] = tv+u; + } else if ( sc ) { + ets.scrollTop = v1 + ( v2 - v1 ) * v; + } else if ( bg ) { + var px1 = _start.x.v, px2 = _end.x.v, py1 = _start.y.v, py2 = _end.y.v, + px = (px1 + ( px2 - px1 ) * v), pxu = '%', + py = (py1 + ( py2 - py1 ) * v), pyu = '%'; + css[p] = px + pxu + ' ' + py + pyu; + } else if ( clp ) { + var h = 0, cl = []; + for (h;h<4;h++){ + var c1 = _start[h].v, c2 = _end[h].v, cu = _end[h].u || 'px'; + cl[h] = ((c1 + ( c2 - c1 ) * v)) + cu; + } + css[p] = 'rect('+cl+')'; + } else if ( op ) { + css[opp] = !_isIE8 ? tv : "alpha(opacity=" + parseInt(tv*100) + ")"; + } + } + }; + + K.perspective = function (l,w) { + if ( w._ppo !== undefined ) { l.style[_pfo] = w._ppo; } // element perspective origin + if ( w._ppp !== undefined ) { l.parentNode.style[_pfp] = w._ppp + 'px'; } // parent perspective + if ( w._pppo !== undefined ) { l.parentNode.style[_pfo] = w._pppo; } // parent perspective origin + }; + + K.Tween = function (_el, _vS, _vE, _o) { + this._el = this._el || _el; // element animation is applied to + this._dr = this._dr || _o&&_o.duration || 700; //duration + this._r = this._r || _o&&_o.repeat || 0; // _repeat + this._vSR = {}; // internal valuesStartRepeat + this._vS = _vS; // valuesStart + this._vE = _vE; // valuesEnd + this._y = this._y || _o&&_o.yoyo || false; // _yoyo + this.playing = false; // _isPlaying + this.reversed = false; // _reversed + this._rD = this._rD || _o&&_o.repeatDelay || 0; // _repeatDelay + this._dl = this._dl || _o&&_o.delay || 0; //delay + this._sT = null; // startTime + this.paused = false; //_paused + this._pST = null; //_pauseStartTime + this._pp = this._pp || _o.perspective; // perspective + this._ppo = this._ppo || _o.perspectiveOrigin; // perspective origin + this._ppp = this._ppp || _o.parentPerspective; // parent perspective + this._pppo = this._pppo || _o.parentPerspectiveOrigin; // parent perspective origin + this._rpr = this._rpr || _o.rpr || false; // internal option to process inline/computed style at start instead of init true/false + this._hex = this._hex || _o.keepHex || false; // option to keep hex for color tweens true/false + this._e = this._e || _o.easing; // _easing + this._cT = this._cT || []; //_chainedTweens + this._sC = this._sC || _o&&_o.start || null; // _on StartCallback + this._sCF = false; //_on StartCallbackFIRED + this._uC = _o&&_o.update || null; // _on UpdateCallback + this._cC = _o&&_o.complete || null; // _on CompleteCallback + this._pC = _o&&_o.pause || null; // _on PauseCallback + this._rC = _o&&_o.play || null; // _on ResumeCallback + this._stC = _o&&_o.stop || null; // _on StopCallback + this.repeat = this._r; // we cache the number of repeats to be able to put it back after all cycles finish + }; + + var w = K.Tween.prototype; + + w.start = function (t) { + this.scrollIn(); + var f = {}; + + K.perspective(this._el,this); // apply the perspective + + if ( this._rpr ) { // on start we reprocess the valuesStart for TO() method + f = this.prS(); + this._vS = {}; + this._vS = K.prP(f,false); + + for ( p in this._vS ) { + if ( p === 'transform' && (p in this._vE) ){ + for ( var sp in this._vS[p]) { + if (!(sp in this._vE[p])) { this._vE[p][sp] = {}; } + for ( var spp in this._vS[p][sp] ) { // 3rd level + if ( this._vS[p][sp][spp].value !== undefined ) { + if (!(spp in this._vE[p][sp])) { this._vE[p][sp][spp] = {}; } + for ( var sppp in this._vS[p][sp][spp]) { // spp = translateX | rotateX | skewX | rotate2d + if ( !(sppp in this._vE[p][sp][spp])) { + this._vE[p][sp][spp][sppp] = this._vS[p][sp][spp][sppp]; // sppp = unit | value + } + } + } + } + if ( 'value' in this._vS[p][sp] && (!('value' in this._vE[p][sp])) ) { // 2nd level + for ( var spp in this._vS[p][sp] ) { // scale + if (!(spp in this._vE[p][sp])) { + this._vE[p][sp][spp] = this._vS[p][sp][spp]; // spp = unit | value + } + } + } + } + } + } + } + + for ( p in this._vE ) { + this._vSR[p] = this._vS[p]; + } + + // now it's a good time to start + K.add(this); + this.playing = true; + this.paused = false; + this._sCF = false; + this._sT = t || window.performance.now(); + this._sT += this._dl; + if (!_t) K.t(); + return this; + }; + + //main worker, doing update on tick + w.u = function(t) { + t = t || window.performance.now(); + if (t < this._sT && this.playing && !this.paused) { return true; } + + if (!this._sCF) { + if (this._sC) { this._sC.call(); } + this._sCF = true; + } + + var e = ( t - this._sT ) / this._dr; //elapsed + e = e > 1 ? 1 : e; + + //render the CSS update + K.r(this,this._e(e)); + + if (this._uC) { this._uC.call(); } + + if (e === 1) { + if (this._r > 0) { + if ( this._r !== Infinity ) { this._r--; } + + if (this._y) { this.reversed = !this.reversed; this.reverse(); } // handle yoyo + + this._sT = (this._y && !this.reversed) ? t + this._rD : t; //set the right time for delay + return true; + } else { + + if (this._cC) { this._cC.call(); } + + //stop preventing scroll when scroll tween finished + this.scrollOut(); + var i = 0, ctl = this._cT.length; + for (i; i < ctl; i++) { + this._cT[i].start(this._sT + this._dr); + } + + //stop ticking when finished + this.close(); + return false; + } + } + return true; + }; + + w.stop = function () { + if (!this.paused && this.playing) { + K.remove(this); + this.playing = false; + this.paused = false; + this.scrollOut(); + + if (this._stC !== null) { + this._stC.call(); + } + this.stopChainedTweens(); + this.close(); + } + return this; + }; + + w.pause = function() { + if (!this.paused && this.playing) { + K.remove(this); + this.paused = true; + this._pST = window.performance.now(); + if (this._pC !== null) { + this._pC.call(); + } + } + return this; + }; + + w.play = function () { + if (this.paused && this.playing) { + this.paused = false; + if (this._rC !== null) { + this._rC.call(); + } + this._sT += window.performance.now() - this._pST; + K.add(this); + if (!_t) K.t(); // restart ticking if stopped + } + return this; + }; + + w.resume = function () { this.play(); return this; }; + + w.reverse = function () { + if (this._y) { + for (var p in this._vE) { + var tmp = this._vSR[p]; + this._vSR[p] = this._vE[p]; + this._vE[p] = tmp; + this._vS[p] = this._vSR[p]; + } + } + return this; + }; + + w.chain = function () { this._cT = arguments; return this; }; + + w.stopChainedTweens = function () { + var i = 0, ctl =this._cT.length; + for (i; i < ctl; i++) { + this._cT[i].stop(); + } + }; + + w.scrollOut = function(){ //prevent scroll when tweening scroll + if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { + this.removeListeners(); + document.body.removeAttribute('data-tweening'); + } + }; + + w.scrollIn = function(){ + if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { + if (!document.body.getAttribute('data-tweening') ) { + document.body.setAttribute('data-tweening', 'scroll'); + this.addListeners(); + } + } + }; + + w.addListeners = function () { + document.addEventListener(_ev, K.preventScroll, false); + }; + + w.removeListeners = function () { + document.removeEventListener(_ev, K.preventScroll, false); + }; + + w.prS = function () { //prepare valuesStart for .to() method + var f = {}, el = this._el, to = this._vS, cs = this.gIS('transform'), deg = ['rotate','skew'], ax = ['X','Y','Z']; + + for (var p in to){ + if ( _tf.indexOf(p) !== -1 ) { + var r2d = (p === 'rotate' || p === 'translate' || p === 'scale'); + if ( /translate/.test(p) && p !== 'translate' ) { + f['translate3d'] = cs['translate3d'] || _d[p]; + } else if ( r2d ) { // 2d transforms + f[p] = cs[p] || _d[p]; + } else if ( !r2d && /rotate|skew/.test(p) ) { // all angles + for (var d=0; d<2; d++) { + for (var a = 0; a<3; a++) { + var s = deg[d]+ax[a]; + if (_tf.indexOf(s) !== -1 && (s in to) ) { f[s] = cs[s] || _d[s]; } + } + } + } + } else { + if ( _sc.indexOf(p) === -1 ) { + if (p === 'opacity' && _isIE8 ) { // handle IE8 opacity + var co = this.gCS('filter'); + f['opacity'] = typeof co === 'number' ? co : _d['opacity']; + } else { + f[p] = this.gCS(p) || _d[p]; + } + } else { + f[p] = (el === null || el === undefined) ? (window.pageYOffset || _sct.scrollTop) : el.scrollTop; + } + } + } + for ( var p in cs ){ // also add to _vS values from previous tweens + if ( _tf.indexOf(p) !== -1 && (!( p in to )) ) { + f[p] = cs[p] || _d[p]; + } + } + return f; + }; + + w.gIS = function(p) { // gIS = get transform style for element from cssText for .to() method, the sp is for transform property + if (!this._el) return; // if the scroll applies to `window` it returns as it has no styling + var l = this._el, cst = l.style.cssText,//the cssText + trsf = {}; //the transform object + // if we have any inline style in the cssText attribute, usually it has higher priority + var css = cst.replace(/\s/g,'').split(';'), i=0, csl = css.length; + for ( i; i 0) { self._r = self.repeat; } + if (self._y && self.reversed===true) { self.reverse(); self.reversed = false; } + self.playing = false; + },100) + }; + + // process properties + K.prP = function (t, e) { // process tween properties for .fromTo() method + var _st = {}, + tr = e === true ? _tfE : _tfS, + tl = e === true ? _tlE : _tlS, + rt = e === true ? _rtE : _rtS; + + tl = {}; tr = {}; + + for (var x in t) { + if (_tf.indexOf(x) !== -1) { + + if (x !== 'translate' && /translate/.test(x)) { //process translate3d + var ta = ['X', 'Y', 'Z'], f = 0; //coordinates // translate[x] = pp(x, t[x]); + + for (f; f < 3; f++) { + var a = ta[f]; + if ( /3d/.test(x) ) { + tl['translate' + a] = K.pp('translate' + a, t[x][f]); + } else { + tl['translate' + a] = ('translate' + a in t) ? K.pp('translate' + a, t['translate' + a]) : { value: 0, unit: 'px' }; + } + } + + tr['translate'] = tl; + } else if ( x !== 'rotate' && /rotate|skew/.test(x)) { //process rotation + var ap = /rotate/.test(x) ? 'rotate' : 'skew', ra = ['X', 'Y', 'Z'], r = 0, + _rt = {}, _sk = {}, rt = ap === 'rotate' ? _rt : _sk; + for (r; r < 3; r++) { + var v = ra[r]; + if ( t[ap+v] !== undefined && x !== 'skewZ' ) { + rt[ap+v] = K.pp(ap + v, t[ap+v]); + } + } + + tr[ap] = rt; + } else if ( x === 'translate' || x === 'rotate' || x === 'scale' ) { //process 2d translation / rotation + tr[x] = K.pp(x, t[x]); + } + + _st['transform'] = tr; + + } else if (_tf.indexOf(x) === -1) { + _st[x] = K.pp(x, t[x]); + } + } + return _st; + }; + + // _cls _sc _op _bm _tp _bg _tf + K.pp = function(p, v) {//process single property + if (_tf.indexOf(p) !== -1) { + var t = p.replace(/X|Y|Z/, ''), tv; + if (p === 'translate3d') { + tv = v.split(','); + return { + translateX : { value: K.truD(tv[0]).v, unit: K.truD(tv[0]).u }, + translateY : { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u }, + translateZ : { value: K.truD(tv[2]).v, unit: K.truD(tv[2]).u } + }; + } else if (p !== 'translate' && t === 'translate') { + return { value: K.truD(v).v, unit: (K.truD(v).u||'px') }; + } else if (p !== 'rotate' && (t === 'skew' || t === 'rotate') && p !== 'skewZ' ) { + return { value: K.truD(v).v, unit: (K.truD(v,p).u||'deg') }; + } else if (p === 'translate') { + tv = typeof v === 'string' ? v.split(',') : v; var t2d = {}; + if (tv instanceof Array) { + t2d.x = { value: K.truD(tv[0]).v, unit: K.truD(tv[0]).u }, + t2d.y = { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u } + } else { + t2d.x = { value: K.truD(tv).v, unit: K.truD(tv).u }, + t2d.y = { value: 0, unit: 'px' } + } + return t2d; + } else if (p === 'rotate') { + var r2d = {}; + r2d.z = { value: parseInt(v, 10), unit: (K.truD(v,p).u||'deg') }; + return r2d; + } else if (p === 'scale') { + return { value: parseFloat(v, 10) }; + } + } + if (_tp.indexOf(p) !== -1 || _bm.indexOf(p) !== -1) { + return { value: K.truD(v).v, unit: K.truD(v).u }; + } + if (_op.indexOf(p) !== -1) { + return { value: parseFloat(v, 10) }; + } + if (_sc.indexOf(p) !== -1) { + return { value: parseFloat(v, 10) }; + } + if (_clp.indexOf(p) !== -1) { + if ( v instanceof Array ){ + return [ K.truD(v[0]), K.truD(v[1]), K.truD(v[2]), K.truD(v[3]) ]; + } else { + var ci; + if ( /rect/.test(v) ) { + ci = v.replace(/rect|\(|\)/g,'').split(/\s|\,/); + } else if ( /auto|none|initial/.test(v) ){ + ci = _d[p]; + } + return [ K.truD(ci[0]), K.truD(ci[1]), K.truD(ci[2]), K.truD(ci[3]) ]; + } + } + if (_cls.indexOf(p) !== -1) { + return { value: K.truC(v) }; + } + if (_bg.indexOf(p) !== -1) { + if ( v instanceof Array ){ + return { x: K.truD(v[0])||{ v: 50, u: '%' }, y: K.truD(v[1])||{ v: 50, u: '%' } }; + } else { + var posxy = v.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/,50).split(/\s|\,/g), + xp = K.truD(posxy[0]), yp = K.truD(posxy[1]); + return { x: xp, y: yp }; + } + } + if (_rd.indexOf(p) !== -1) { + var rad = K.truD(v); + return { value: rad.v, unit: rad.u }; + } + }; + + K.truD = function (d,p) { //true dimension returns { v = value, u = unit } + var x = parseInt(d) || 0, mu = ['px','%','deg','rad','em','rem','vh','vw'], l = mu.length, + y = getU(); + function getU() { + var u,i=0; + for (i;i0?t=b:e=b;while(Math.abs(s)>z&&++_u;++u){var b=_bz.gS(e,t,r);if(0===b)return e;var _=_bz.cB(e,t,r)-n;e-=_/b}return e},_bz.csv=function(n,e){var t=0,r=_bz.ksts;for(t;r>t;++t)_bz.msv[t]=_bz.cB(t*_bz.ksss,n,e)},_bz.gx=function(n,e,t){for(var r=0,u=1,s=_bz.ksts-1;u!=s&&_bz.msv[u]<=n;++u)r+=_bz.ksss;--u;var b=(n-_bz.msv[u])/(_bz.msv[u+1]-_bz.msv[u]),_=r+b*_bz.ksss,z=_bz.gS(_,e,t),a=r+_bz.ksss;return z>=_bz.nms?_bz.nri(n,_,e,t):0===z?_:_bz.bS(n,r,a,e,t)},_bz.pc=function(n,e,t,r){this._p=!0,(n!=t||e!=r)&&_bz.csv(n,e)},KUTE.Ease.easeIn=function(){return _bz.pB(.42,0,1,1)},KUTE.Ease.easeOut=function(){return _bz.pB(0,0,.58,1)},KUTE.Ease.easeInOut=function(){return _bz.pB(.5,.16,.49,.86)},KUTE.Ease.easeInSine=function(){return _bz.pB(.47,0,.745,.715)},KUTE.Ease.easeOutSine=function(){return _bz.pB(.39,.575,.565,1)},KUTE.Ease.easeInOutSine=function(){return _bz.pB(.445,.05,.55,.95)},KUTE.Ease.easeInQuad=function(){return _bz.pB(.55,.085,.68,.53)},KUTE.Ease.easeOutQuad=function(){return _bz.pB(.25,.46,.45,.94)},KUTE.Ease.easeInOutQuad=function(){return _bz.pB(.455,.03,.515,.955)},KUTE.Ease.easeInCubic=function(){return _bz.pB(.55,.055,.675,.19)},KUTE.Ease.easeOutCubic=function(){return _bz.pB(.215,.61,.355,1)},KUTE.Ease.easeInOutCubic=function(){return _bz.pB(.645,.045,.355,1)},KUTE.Ease.easeInQuart=function(){return _bz.pB(.895,.03,.685,.22)},KUTE.Ease.easeOutQuart=function(){return _bz.pB(.165,.84,.44,1)},KUTE.Ease.easeInOutQuart=function(){return _bz.pB(.77,0,.175,1)},KUTE.Ease.easeInQuint=function(){return _bz.pB(.755,.05,.855,.06)},KUTE.Ease.easeOutQuint=function(){return _bz.pB(.23,1,.32,1)},KUTE.Ease.easeInOutQuint=function(){return _bz.pB(.86,0,.07,1)},KUTE.Ease.easeInExpo=function(){return _bz.pB(.95,.05,.795,.035)},KUTE.Ease.easeOutExpo=function(){return _bz.pB(.19,1,.22,1)},KUTE.Ease.easeInOutExpo=function(){return _bz.pB(1,0,0,1)},KUTE.Ease.easeInCirc=function(){return _bz.pB(.6,.04,.98,.335)},KUTE.Ease.easeOutCirc=function(){return _bz.pB(.075,.82,.165,1)},KUTE.Ease.easeInOutCirc=function(){return _bz.pB(.785,.135,.15,.86)},KUTE.Ease.easeInBack=function(){return _bz.pB(.6,-.28,.735,.045)},KUTE.Ease.easeOutBack=function(){return _bz.pB(.175,.885,.32,1.275)},KUTE.Ease.easeInOutBack=function(){return _bz.pB(.68,-.55,.265,1.55)},KUTE.Ease.slowMo=function(){return _bz.pB(0,.5,1,.5)},KUTE.Ease.slowMo1=function(){return _bz.pB(0,.7,1,.3)},KUTE.Ease.slowMo2=function(){return _bz.pB(0,.9,1,.1)}; \ No newline at end of file diff --git a/dist/kute-jquery.min.js b/dist/kute-jquery.min.js new file mode 100644 index 0000000..4f9e775 --- /dev/null +++ b/dist/kute-jquery.min.js @@ -0,0 +1,2 @@ +// KUTE jQuery Plugin for KUTE.js | by dnp_theme | License - MIT +!function(t){t.fn.KUTE=function(t,n,i,h){var s,o=[],a=this.length;for(s=0;a>s;s++){var e=this[s][t];"function"==typeof e&&e.apply(this[s]),"to"===t?o.push(new KUTE[t](this[s],n,i)):"fromTo"===t||"Animate"===t?o.push(new KUTE[t](this[s],n,i,h)):"chain"===t&&this[s].chain.apply(this[s],n)}return o}}(jQuery); \ No newline at end of file diff --git a/dist/kute-physics.min.js b/dist/kute-physics.min.js new file mode 100644 index 0000000..8efe92a --- /dev/null +++ b/dist/kute-physics.min.js @@ -0,0 +1,2 @@ +// dynamics easings KUTE.js | dnp_theme | MIT License +KUTE.Physics={};var _kp=KUTE.Physics,_hPI=Math.PI/2;_kp.spring=function(n){n=n||{};var r=Math.max(1,(n.frequency||300)/20),t=Math.pow(20,(n.friction||200)/100),p=n.anticipationStrength||0,i=(n.anticipationSize||0)/1e3;return _kps.run=function(n){var o,e,a,u,c,k,_,y;return k=n/(1-i)-i/(1-i),i>n?(y=i/(1-i)-i/(1-i),_=0/(1-i)-i/(1-i),c=Math.acos(1/_kps.A1(n,y)),a=(Math.acos(1/_kps.A1(n,_))-c)/(r*-i),o=_kps.A1):(o=_kps.A2,c=0,a=1),e=o(k,i,p,t),u=r*(n-i)*a+c,1-e*Math.cos(u)},_kps.run};var _kps=_kp.spring.prototype;_kps.run={},_kps.A1=function(n,r,t){var p,i,o,e;return o=r/(1-r),e=0,i=(o-.8*e)/(o-e),p=(.8-i)/o,p*n*t/100+i},_kps.A2=function(n,r,t,p){return Math.pow(p/10,-n)*(1-n)},_kp.bounce=function(n){n=n||{};var r=Math.max(1,(n.frequency||300)/20),t=Math.pow(20,(n.friction||200)/100);return _kpo.run=function(n){var p=Math.pow(t/10,-n)*(1-n),i=r*n*1+_hPI;return p*Math.cos(i)},_kpo.run};var _kpo=_kp.bounce.prototype;_kpo.run={},_kp.gravity=function(n){var r,t,p,i,o;return n=n||{},r=(n.bounciness||400)/1250,p=(n.elasticity||200)/1e3,o=n.initialForce||!1,i=100,t=[],_kpg.L=function(){var n,t;for(n=Math.sqrt(2/i),t={a:-n,b:n,H:1},o&&(t.a=0,t.b=2*t.b);t.H>.001;)_kpg.L=t.b-t.a,t={a:t.b,b:t.b+_kpg.L*r,H:t.H*r*r};return t.b}(),function(){var n,e,a,u;for(e=Math.sqrt(2/(i*_kpg.L*_kpg.L)),a={a:-e,b:e,H:1},o&&(a.a=0,a.b=2*a.b),t.push(a),n=_kpg.L,u=[];a.b<1&&a.H>.001;)n=a.b-a.a,a={a:a.b,b:a.b+n*r,H:a.H*p},u.push(t.push(a));return u}(),_kpg.fn=function(r){var p,i,e;for(i=0,p=t[i];!(r>=p.a&&r<=p.b)&&(i+=1,p=t[i]););return e=p?_kpg.getPointInCurve(p.a,p.b,p.H,r,n,_kpg.L):o?0:1},_kpg.fn};var _kpg=_kp.gravity.prototype;_kpg.L={},_kpg.fn={},_kpg.getPointInCurve=function(n,r,t,p,i,o){var e,a;return o=r-n,a=2/o*p-1-2*n/o,e=a*a*t-t+1,i.initialForce&&(e=1-e),e},_kp.forceWithGravity=function(n){var r=n||{};return r.initialForce=!0,_kp.gravity(r)},_kp.bezier=function(n){n=n||{};var r=n.points,t=!1,p=[];return function(){var n,t;for(n in r){if(t=parseInt(n),t>=r.length-1)break;_kpb.fn(r[t],r[t+1],p)}return p}(),_kpb.run=function(n){return 0===n?0:1===n?1:_kpb.yForX(n,p,t)},_kpb.run};var _kpb=_kp.bezier.prototype;_kpb.B2={},_kpb.run={},_kpb.fn=function(n,r,t){var p=function(t){return _kpb.Bezier(t,n,n.cp[n.cp.length-1],r.cp[0],r)};return t.push(p)},_kpb.Bezier=function(n,r,t,p,i){return{x:Math.pow(1-n,3)*r.x+3*Math.pow(1-n,2)*n*t.x+3*(1-n)*Math.pow(n,2)*p.x+Math.pow(n,3)*i.x,y:Math.pow(1-n,3)*r.y+3*Math.pow(1-n,2)*n*t.y+3*(1-n)*Math.pow(n,2)*p.y+Math.pow(n,3)*i.y}},_kpb.yForX=function(n,r,t){var p,i,o,e,a,u,c,k,_=0,y=r.length;for(p=null,_;y>_&&(i=r[_],n>=i(0).x&&n<=i(1).x&&(p=i),null===p);_++);if(!p)return t?0:1;for(k=1e-4,e=0,u=1,a=(u+e)/2,c=p(a).x,o=0;Math.abs(n-c)>k&&100>o;)n>c?e=a:u=a,a=(u+e)/2,c=p(a).x,o++;return p(a).y},_kp.physicsInOut=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:.92-r/1e3,y:0}]},{x:1,y:1,cp:[{x:.08+r/1e3,y:1}]}]})},_kp.physicsIn=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:.92-r/1e3,y:0}]},{x:1,y:1,cp:[{x:1,y:1}]}]})},_kp.physicsOut=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:0,y:0}]},{x:1,y:1,cp:[{x:.08+r/1e3,y:1}]}]})},_kp.physicsBackOut=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:0,y:0}]},{x:1,y:1,cp:[{x:.735+r/1e3,y:1.3}]}]})},_kp.physicsBackIn=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:.28-r/1e3,y:-.6}]},{x:1,y:1,cp:[{x:1,y:1}]}]})},_kp.physicsBackInOut=function(n){var r;return n=n||{},r=n.friction||500,_kp.bezier({points:[{x:0,y:0,cp:[{x:.68-r/1e3,y:-.55}]},{x:1,y:1,cp:[{x:.265+r/1e3,y:1.45}]}]})}; \ No newline at end of file diff --git a/dist/kute.full.min.js b/dist/kute.full.min.js deleted file mode 100644 index 4348543..0000000 --- a/dist/kute.full.min.js +++ /dev/null @@ -1,2 +0,0 @@ -// kute.full.min.js | by dnp_theme | License - MIT -var KUTE=KUTE||function(){var t=[];return{getAll:function(){return t},removeAll:function(){t=[]},add:function(n){t.push(n)},remove:function(n){var r=t.indexOf(n);-1!==r&&t.splice(r,1)},update:function(n){if(0===t.length)return!1;var r=0;for(n=void 0!==n?n:window.performance.now();rt)return!0;l===!1&&(null!==c&&c.call(n),l=!0);var e=(t-u)/i;e=e>1?1:e;var g=s(e);for(a in o){var h=r[a]||0,I=o[a];"string"==typeof I&&(I=h+parseFloat(I,10)),"number"==typeof I&&(n[a]=h+(I-h)*g)}return null!==p&&p.call(n,g),1==e?(null!==f&&f.call(n),!1):!0}},KUTE.process(0),KUTE.Easing={Linear:{None:function(t){return t}},Quadratic:{In:function(t){return t*t},Out:function(t){return t*(2-t)},InOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)}},Cubic:{In:function(t){return t*t*t},Out:function(t){return--t*t*t+1},InOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)}},Quartic:{In:function(t){return t*t*t*t},Out:function(t){return 1- --t*t*t*t},InOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)}},Quintic:{In:function(t){return t*t*t*t*t},Out:function(t){return--t*t*t*t*t+1},InOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)}},Sinusoidal:{In:function(t){return 1-Math.cos(t*Math.PI/2)},Out:function(t){return Math.sin(t*Math.PI/2)},InOut:function(t){return.5*(1-Math.cos(Math.PI*t))}},Exponential:{In:function(t){return 0===t?0:Math.pow(1024,t-1)},Out:function(t){return 1===t?1:1-Math.pow(2,-10*t)},InOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(-Math.pow(2,-10*(t-1))+2)}},Circular:{In:function(t){return 1-Math.sqrt(1-t*t)},Out:function(t){return Math.sqrt(1- --t*t)},InOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)}},Elastic:{In:function(t){var n,r=.1,o=.4;return 0===t?0:1===t?1:(!r||1>r?(r=1,n=o/4):n=o*Math.asin(1/r)/(2*Math.PI),-(r*Math.pow(2,10*(t-=1))*Math.sin(2*(t-n)*Math.PI/o)))},Out:function(t){var n,r=.1,o=.4;return 0===t?0:1===t?1:(!r||1>r?(r=1,n=o/4):n=o*Math.asin(1/r)/(2*Math.PI),r*Math.pow(2,-10*t)*Math.sin(2*(t-n)*Math.PI/o)+1)},InOut:function(t){var n,r=.1,o=.4;return 0===t?0:1===t?1:(!r||1>r?(r=1,n=o/4):n=o*Math.asin(1/r)/(2*Math.PI),(t*=2)<1?-.5*r*Math.pow(2,10*(t-=1))*Math.sin(2*(t-n)*Math.PI/o):r*Math.pow(2,-10*(t-=1))*Math.sin(2*(t-n)*Math.PI/o)*.5+1)}},Back:{In:function(t){var n=1.70158;return t*t*((n+1)*t-n)},Out:function(t){var n=1.70158;return--t*t*((n+1)*t+n)+1},InOut:function(t){var n=2.5949095;return(t*=2)<1?.5*t*t*((n+1)*t-n):.5*((t-=2)*t*((n+1)*t+n)+2)}},Bounce:{In:function(t){return 1-KUTE.Easing.Bounce.Out(1-t)},Out:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},InOut:function(t){return.5>t?.5*KUTE.Easing.Bounce.In(2*t):.5*KUTE.Easing.Bounce.Out(2*t-1)+.5}}},document.addEventListener("mousewheel",preventScroll,!1),document.addEventListener("touchstart",preventScroll,!1);function preventScroll(t){var n=document.body.getAttribute("data-tweening");n&&"scroll"===n&&t.preventDefault()} diff --git a/dist/kute.jquery.js b/dist/kute.jquery.js deleted file mode 100644 index 5466d73..0000000 --- a/dist/kute.jquery.js +++ /dev/null @@ -1,18 +0,0 @@ -// KUTE jQuery Plugin for kute.js | by dnp_theme | License - MIT -// $('selector').Kute(method, options); - -(function($) { - $.fn.KUTE = function( method, start, end, ops ) { // method can be Animate(), fromTo(), to(), stop(), start(), chain(), pause() - var mt = this[0][method], i, l = this.length; - if ( typeof mt === 'function' ) { - mt.apply(this[0]); - } - for (i=0;it)return!0;l===!1&&(null!==c&&c.call(n),l=!0);var o=(t-u)/a;o=o>1?1:o;var h=s(o);for(e in r){var E=i[e]||0,I=r[e];"string"==typeof I&&(I=E+parseFloat(I,10)),"number"==typeof I&&(n[e]=E+(I-E)*h)}return null!==f&&f.call(n,h),1==o?(null!==p&&p.call(n),!1):!0}},KUTE.process(0),KUTE.Easing={Linear:{None:function(t){return t}},Quadratic:{In:function(t){return t*t},Out:function(t){return t*(2-t)},InOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)}},Cubic:{In:function(t){return t*t*t},Out:function(t){return--t*t*t+1},InOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)}},Quartic:{In:function(t){return t*t*t*t},Out:function(t){return 1- --t*t*t*t},InOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)}},Quintic:{In:function(t){return t*t*t*t*t},Out:function(t){return--t*t*t*t*t+1},InOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)}},Sinusoidal:{In:function(t){return 1-Math.cos(t*Math.PI/2)},Out:function(t){return Math.sin(t*Math.PI/2)},InOut:function(t){return.5*(1-Math.cos(Math.PI*t))}},Exponential:{In:function(t){return 0===t?0:Math.pow(1024,t-1)},Out:function(t){return 1===t?1:1-Math.pow(2,-10*t)},InOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(-Math.pow(2,-10*(t-1))+2)}},Circular:{In:function(t){return 1-Math.sqrt(1-t*t)},Out:function(t){return Math.sqrt(1- --t*t)},InOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)}},Elastic:{In:function(t){var n,i=.1,r=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,n=r/4):n=r*Math.asin(1/i)/(2*Math.PI),-(i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-n)*Math.PI/r)))},Out:function(t){var n,i=.1,r=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,n=r/4):n=r*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin(2*(t-n)*Math.PI/r)+1)},InOut:function(t){var n,i=.1,r=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,n=r/4):n=r*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?-.5*i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-n)*Math.PI/r):i*Math.pow(2,-10*(t-=1))*Math.sin(2*(t-n)*Math.PI/r)*.5+1)}},Back:{In:function(t){var n=1.70158;return t*t*((n+1)*t-n)},Out:function(t){var n=1.70158;return--t*t*((n+1)*t+n)+1},InOut:function(t){var n=2.5949095;return(t*=2)<1?.5*t*t*((n+1)*t-n):.5*((t-=2)*t*((n+1)*t+n)+2)}},Bounce:{In:function(t){return 1-KUTE.Easing.Bounce.Out(1-t)},Out:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},InOut:function(t){return.5>t?.5*KUTE.Easing.Bounce.In(2*t):.5*KUTE.Easing.Bounce.Out(2*t-1)+.5}}},document.addEventListener("mousewheel",preventScroll,!1),document.addEventListener("touchstart",preventScroll,!1);function preventScroll(t){var n=document.body.getAttribute("data-tweening");n&&"scroll"===n&&t.preventDefault()} +// KUTE.js | dnp_theme | MIT-License +!function(t,e){"function"==typeof define&&define.amd?define(["KUTE"],e):"object"==typeof exports?module.exports=e():t.KUTE=t.KUTE||e()}(this,function(){function t(){var t=document.createElement("div"),e=0,r=["Moz","moz","Webkit","webkit","O","o","Ms","ms"],i=r.length,n=["MozTransform","mozTransform","WebkitTransform","webkitTransform","OTransform","oTransform","MsTransform","msTransform"];for(e;i>e;e++)if(n[e]in t.style)return r[e];t=null}for(var e,r=r||{},i=[],n=!1,s=t(),a=(a||("requestAnimationFrame"in window?!1:!0)),o=(o||("transform"in document.getElementsByTagName("div")[0].style?!1:!0)),u=(u||("border-radius"in document.getElementsByTagName("div")[0].style?!1:!0)),l=(l||"ontouchstart"in window||navigator.msMaxTouchPoints||!1),f=f||(l?"touchstart":"mousewheel"),p=document.body,h=document.getElementsByTagName("HTML")[0],c=/webkit/i.test(navigator.userAgent)||"BackCompat"==document.compatMode?p:h,d=/ie/.test(document.documentElement.className),v=/ie8/.test(document.documentElement.className),g=g||o?s+"Perspective":"perspective",_=_||o?s+"PerspectiveOrigin":"perspectiveOrigin",m=m||o?s+"Transform":"transform",E=E||u?s+"BorderRadius":"borderRadius",y=y||u?s+"BorderTopLeftRadius":"borderTopLeftRadius",b=b||u?s+"BorderTopRightRadius":"borderTopRightRadius",w=w||u?s+"BorderBottomLeftRadius":"borderBottomLeftRadius",O=O||u?s+"BorderBottomRightRadius":"borderBottomRightRadius",x=x||a?window[s+"RequestAnimationFrame"]:window.requestAnimationFrame,T=T||a?window[s+"CancelAnimationFrame"]:window.cancelAnimationFrame,C=["color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],I=["scrollTop","scroll"],S=["clip"],R=["opacity"],D=["borderRadius","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"],M=["top","left","right","bottom","width","height","minWidth","minHeight","maxWidth","maxHeight","padding","margin","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],B=["fontSize","lineHeight","letterSpacing"],k=["backgroundPosition"],L=["rotateX","rotateY","translateZ"],A=["translate3d","translateX","translateY","translateZ","rotate","translate","rotateX","rotateY","rotateZ","skewX","skewY","scale"],F=C.concat(I,S,R,D,M,B,k,A),P=F.length,Y={},X={},Z={},z={},q={},Q={},W=W||{},N=0;P>N;N++){var H=F[N];-1!==C.indexOf(H)?W[H]="rgba(0,0,0,0)":-1!==D.indexOf(H)||-1!==M.indexOf(H)||-1!==B.indexOf(H)?W[H]=0:-1!==k.indexOf(H)?W[H]=[50,50]:"clip"===H?W[H]=[0,0,0,0]:"translate3d"===H?W[H]=[0,0,0]:"translate"===H?W[H]=[0,0]:"rotate"===H||/X|Y|Z/.test(H)?W[H]=0:("scale"===H||"opacity"===H)&&(W[H]=1)}r.getAll=function(){return i},r.removeAll=function(){i=[]},r.add=function(t){i.push(t)},r.remove=function(t){var e=i.indexOf(t);-1!==e&&i.splice(e,1)},r.t=function(t){e=x(r.t);for(var s=0,a=i.length;a>s;){if(!i[s])return!1;i[s].u(t)?s++:i.splice(s,1)}return n=!1,!0},r.s=function(){n===!1&&(T(e),n=!0,e=null)},r.to=function(t,e,i){void 0===i&&(i={});var n=n||"object"==typeof t?t:document.querySelector(t),s=s||i;s.rpr=!0,s.easing=s&&r.pe(s.easing)||r.Easing.linear;var a=e,o=r.prP(e,!0),u=new r.Tween(n,a,o,s);return u},r.fromTo=function(t,e,i,n){void 0===n&&(n={});var s=s||"object"==typeof t?t:document.querySelector(t),a=n;a.easing=a&&r.pe(a.easing)||r.Easing.linear;var o=r.prP(e,!1),u=r.prP(i,!0),l=new r.Tween(s,o,u,a);return l},r.Animate=function(t,e,i,n){return r.fromTo(t,e,i,n)},r.r=function(t,e){var i,n=t._el&&t._el.style,s=v?"filter":"opacity",a=void 0===t._el||null===t._el?c:t._el;for(i in t._vE){var o=t._vS[i],u=t._vE[i],l=o.value,f=u.value,p=l+(f-l)*e,h=u.unit,g=-1!==C.indexOf(i),_=-1!==B.indexOf(i)||-1!==M.indexOf(i),x=-1!==D.indexOf(i)&&!v,T=-1!==I.indexOf(i),A=-1!==k.indexOf(i),F=-1!==S.indexOf(i),P=-1!==R.indexOf(i),Y="transform"===i&&!v;if(x)"borderRadius"===i?n[E]=p+h:"borderTopLeftRadius"===i?n[y]=p+h:"borderTopRightRadius"===i?n[b]=p+h:"borderBottomLeftRadius"===i?n[w]=p+h:"borderBottomRightRadius"===i&&(n[O]=p+h);else if(Y){var X,Z,z="",q="perspective("+t._pp+"px) ";for(X in u){var Q=o[X],W=u[X];if(Z=-1!==L.indexOf(X)&&!d,"translate"===X){var N,H="",j={};for(N in W){var K=Q[N].value||0,U=W[N].value||0,$=W[N].unit||"px";j[N]=K===U?U+$:K+(U-K)*e+$}H=W.x?"translate("+j.x+","+j.y+")":"translate3d("+j.translateX+","+j.translateY+","+j.translateZ+")",z=""===z?H:H+" "+z}else if("rotate"===X){var G,J="",V={};for(G in W)if(Q[G]){var te=Q[G].value,ee=W[G].value,re=W[G].unit||"deg",ie=te+(ee-te)*e;V[G]="z"===G?"rotate("+ie+re+")":G+"("+ie+re+") "}J=W.z?V.z:(V.rotateX||"")+(V.rotateY||"")+(V.rotateZ||""),z=""===z?J:z+" "+J}else if("skew"===X){var ne="",se={};for(var ae in W)if(Q[ae]){var oe=Q[ae].value,ue=W[ae].value,le=W[ae].unit||"deg",fe=oe+(ue-oe)*e;se[ae]=ae+"("+fe+le+") "}ne=(se.skewX||"")+(se.skewY||""),z=""===z?ne:z+" "+ne}else if("scale"===X){var pe=Q.value,he=W.value,ce=pe+(he-pe)*e,de=X+"("+ce+")";z=""===z?de:z+" "+de}}n[m]=Z||void 0!==t._pp&&0!==t._pp?q+z:z}else if(g){var ve,ge={};for(ve in f)ge[ve]="a"!==ve?parseInt(l[ve]+(f[ve]-l[ve])*e)||0:l[ve]&&f[ve]?parseFloat(l[ve]+(f[ve]-l[ve])*e):null;n[i]=t._hex?r.rth(parseInt(ge.r),parseInt(ge.g),parseInt(ge.b)):!ge.a||v?"rgb("+ge.r+","+ge.g+","+ge.b+")":"rgba("+ge.r+","+ge.g+","+ge.b+","+ge.a+")"}else if(_)n[i]=p+h;else if(T)a.scrollTop=l+(f-l)*e;else if(A){var _e=o.x.v,me=u.x.v,Ee=o.y.v,ye=u.y.v,be=_e+(me-_e)*e,we="%",Oe=Ee+(ye-Ee)*e,xe="%";n[i]=be+we+" "+Oe+xe}else if(F){var Te=0,Ce=[];for(Te;4>Te;Te++){var Ie=o[Te].v,Se=u[Te].v,Re=u[Te].u||"px";Ce[Te]=Ie+(Se-Ie)*e+Re}n[i]="rect("+Ce+")"}else P&&(n[s]=v?"alpha(opacity="+parseInt(100*p)+")":p)}},r.perspective=function(t,e){void 0!==e._ppo&&(t.style[_]=e._ppo),void 0!==e._ppp&&(t.parentNode.style[g]=e._ppp+"px"),void 0!==e._pppo&&(t.parentNode.style[_]=e._pppo)},r.Tween=function(t,e,r,i){this._el=this._el||t,this._dr=this._dr||i&&i.duration||700,this._r=this._r||i&&i.repeat||0,this._vSR={},this._vS=e,this._vE=r,this._y=this._y||i&&i.yoyo||!1,this.playing=!1,this.reversed=!1,this._rD=this._rD||i&&i.repeatDelay||0,this._dl=this._dl||i&&i.delay||0,this._sT=null,this.paused=!1,this._pST=null,this._pp=this._pp||i.perspective,this._ppo=this._ppo||i.perspectiveOrigin,this._ppp=this._ppp||i.parentPerspective,this._pppo=this._pppo||i.parentPerspectiveOrigin,this._rpr=this._rpr||i.rpr||!1,this._hex=this._hex||i.keepHex||!1,this._e=this._e||i.easing,this._cT=this._cT||[],this._sC=this._sC||i&&i.start||null,this._sCF=!1,this._uC=i&&i.update||null,this._cC=i&&i.complete||null,this._pC=i&&i.pause||null,this._rC=i&&i.play||null,this._stC=i&&i.stop||null,this.repeat=this._r};var j=r.Tween.prototype;j.start=function(t){this.scrollIn();var i={};if(r.perspective(this._el,this),this._rpr){i=this.prS(),this._vS={},this._vS=r.prP(i,!1);for(H in this._vS)if("transform"===H&&H in this._vE)for(var n in this._vS[H]){n in this._vE[H]||(this._vE[H][n]={});for(var s in this._vS[H][n])if(void 0!==this._vS[H][n][s].value){s in this._vE[H][n]||(this._vE[H][n][s]={});for(var a in this._vS[H][n][s])a in this._vE[H][n][s]||(this._vE[H][n][s][a]=this._vS[H][n][s][a])}if("value"in this._vS[H][n]&&!("value"in this._vE[H][n]))for(var s in this._vS[H][n])s in this._vE[H][n]||(this._vE[H][n][s]=this._vS[H][n][s])}}for(H in this._vE)this._vSR[H]=this._vS[H];return r.add(this),this.playing=!0,this.paused=!1,this._sCF=!1,this._sT=t||window.performance.now(),this._sT+=this._dl,e||r.t(),this},j.u=function(t){if(t=t||window.performance.now(),t1?1:e,r.r(this,this._e(e)),this._uC&&this._uC.call(),1===e){if(this._r>0)return 1/0!==this._r&&this._r--,this._y&&(this.reversed=!this.reversed,this.reverse()),this._sT=this._y&&!this.reversed?t+this._rD:t,!0;this._cC&&this._cC.call(),this.scrollOut();var i=0,n=this._cT.length;for(i;n>i;i++)this._cT[i].start(this._sT+this._dr);return this.close(),!1}return!0},j.stop=function(){return!this.paused&&this.playing&&(r.remove(this),this.playing=!1,this.paused=!1,this.scrollOut(),null!==this._stC&&this._stC.call(),this.stopChainedTweens(),this.close()),this},j.pause=function(){return!this.paused&&this.playing&&(r.remove(this),this.paused=!0,this._pST=window.performance.now(),null!==this._pC&&this._pC.call()),this},j.play=function(){return this.paused&&this.playing&&(this.paused=!1,null!==this._rC&&this._rC.call(),this._sT+=window.performance.now()-this._pST,r.add(this),e||r.t()),this},j.resume=function(){return this.play(),this},j.reverse=function(){if(this._y)for(var t in this._vE){var e=this._vSR[t];this._vSR[t]=this._vE[t],this._vE[t]=e,this._vS[t]=this._vSR[t]}return this},j.chain=function(){return this._cT=arguments,this},j.stopChainedTweens=function(){var t=0,e=this._cT.length;for(t;e>t;t++)this._cT[t].stop()},j.scrollOut=function(){("scroll"in this._vE||"scrollTop"in this._vE)&&(this.removeListeners(),document.body.removeAttribute("data-tweening"))},j.scrollIn=function(){("scroll"in this._vE||"scrollTop"in this._vE)&&(document.body.getAttribute("data-tweening")||(document.body.setAttribute("data-tweening","scroll"),this.addListeners()))},j.addListeners=function(){document.addEventListener(f,r.preventScroll,!1)},j.removeListeners=function(){document.removeEventListener(f,r.preventScroll,!1)},j.prS=function(){var t={},e=this._el,r=this._vS,i=this.gIS("transform"),n=["rotate","skew"],s=["X","Y","Z"];for(var a in r)if(-1!==A.indexOf(a)){var o="rotate"===a||"translate"===a||"scale"===a;if(/translate/.test(a)&&"translate"!==a)t.translate3d=i.translate3d||W[a];else if(o)t[a]=i[a]||W[a];else if(!o&&/rotate|skew/.test(a))for(var u=0;2>u;u++)for(var l=0;3>l;l++){var f=n[u]+s[l];-1!==A.indexOf(f)&&f in r&&(t[f]=i[f]||W[f])}}else if(-1===I.indexOf(a))if("opacity"===a&&v){var p=this.gCS("filter");t.opacity="number"==typeof p?p:W.opacity}else t[a]=this.gCS(a)||W[a];else t[a]=null===e||void 0===e?window.pageYOffset||c.scrollTop:e.scrollTop;for(var a in i)-1===A.indexOf(a)||a in r||(t[a]=i[a]||W[a]);return t},j.gIS=function(){if(this._el){var t=this._el,e=t.style.cssText,r={},i=e.replace(/\s/g,"").split(";"),n=0,s=i.length;for(n;s>n;n++)if(/transform/.test(i[n])){var a=i[n].split(":")[1].split(")"),o=0,u=a.length;for(o;u>o;o++){var l=a[o].split("(");""!==l[0]&&A.indexOf(l)&&(r[l[0]]=/translate3d/.test(l[0])?l[1].split(","):l[1])}}return r}},j.gCS=function(t){var e=this._el,r=window.getComputedStyle(e)||e.currentStyle,i=!v&&o&&/transform|Radius/.test(t)?"-"+s.toLowerCase()+"-"+t:t,n=o&&"transform"===t||o&&-1!==D.indexOf(t)?r[i]:r[t];if("transform"!==t&&i in r){if(n){if("filter"===i){var a=parseInt(n.split("=")[1].replace(")","")),u=parseFloat(a/100);return u}return n}return W[t]}},j.close=function(){var t=this;setTimeout(function(){var e=i.indexOf(t);e===i.length-1&&r.s(),t.repeat>0&&(t._r=t.repeat),t._y&&t.reversed===!0&&(t.reverse(),t.reversed=!1),t.playing=!1},100)},r.prP=function(t,e){var i={},n=e===!0?X:Y,s=e===!0?z:Z,a=e===!0?Q:q;s={},n={};for(var o in t)if(-1!==A.indexOf(o)){if("translate"!==o&&/translate/.test(o)){var u=["X","Y","Z"],l=0;for(l;3>l;l++){var f=u[l];s["translate"+f]=/3d/.test(o)?r.pp("translate"+f,t[o][l]):"translate"+f in t?r.pp("translate"+f,t["translate"+f]):{value:0,unit:"px"}}n.translate=s}else if("rotate"!==o&&/rotate|skew/.test(o)){var p=/rotate/.test(o)?"rotate":"skew",h=["X","Y","Z"],c=0,d={},v={},a="rotate"===p?d:v;for(c;3>c;c++){var g=h[c];void 0!==t[p+g]&&"skewZ"!==o&&(a[p+g]=r.pp(p+g,t[p+g]))}n[p]=a}else("translate"===o||"rotate"===o||"scale"===o)&&(n[o]=r.pp(o,t[o]));i.transform=n}else-1===A.indexOf(o)&&(i[o]=r.pp(o,t[o]));return i},r.pp=function(t,e){if(-1!==A.indexOf(t)){var i,n=t.replace(/X|Y|Z/,"");if("translate3d"===t)return i=e.split(","),{translateX:{value:r.truD(i[0]).v,unit:r.truD(i[0]).u},translateY:{value:r.truD(i[1]).v,unit:r.truD(i[1]).u},translateZ:{value:r.truD(i[2]).v,unit:r.truD(i[2]).u}};if("translate"!==t&&"translate"===n)return{value:r.truD(e).v,unit:r.truD(e).u||"px"};if("rotate"!==t&&("skew"===n||"rotate"===n)&&"skewZ"!==t)return{value:r.truD(e).v,unit:r.truD(e,t).u||"deg"};if("translate"===t){i="string"==typeof e?e.split(","):e;var s={};return i instanceof Array?(s.x={value:r.truD(i[0]).v,unit:r.truD(i[0]).u},s.y={value:r.truD(i[1]).v,unit:r.truD(i[1]).u}):(s.x={value:r.truD(i).v,unit:r.truD(i).u},s.y={value:0,unit:"px"}),s}if("rotate"===t){var a={};return a.z={value:parseInt(e,10),unit:r.truD(e,t).u||"deg"},a}if("scale"===t)return{value:parseFloat(e,10)}}if(-1!==B.indexOf(t)||-1!==M.indexOf(t))return{value:r.truD(e).v,unit:r.truD(e).u};if(-1!==R.indexOf(t))return{value:parseFloat(e,10)};if(-1!==I.indexOf(t))return{value:parseFloat(e,10)};if(-1!==S.indexOf(t)){if(e instanceof Array)return[r.truD(e[0]),r.truD(e[1]),r.truD(e[2]),r.truD(e[3])];var o;return/rect/.test(e)?o=e.replace(/rect|\(|\)/g,"").split(/\s|\,/):/auto|none|initial/.test(e)&&(o=W[t]),[r.truD(o[0]),r.truD(o[1]),r.truD(o[2]),r.truD(o[3])]}if(-1!==C.indexOf(t))return{value:r.truC(e)};if(-1!==k.indexOf(t)){if(e instanceof Array)return{x:r.truD(e[0])||{v:50,u:"%"},y:r.truD(e[1])||{v:50,u:"%"}};var u=e.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/,50).split(/\s|\,/g),l=r.truD(u[0]),f=r.truD(u[1]);return{x:l,y:f}}if(-1!==D.indexOf(t)){var p=r.truD(e);return{value:p.v,unit:p.u}}},r.truD=function(t,e){function r(){var r,i=0;for(i;s>i;i++)"string"==typeof t&&-1!==t.indexOf(n[i])&&(r=n[i]);return r=void 0!==r?r:e?"deg":"px"}var i=parseInt(t)||0,n=["px","%","deg","rad","em","rem","vh","vw"],s=n.length,a=r();return{v:i,u:a}},r.preventScroll=function(t){var e=document.body.getAttribute("data-tweening");e&&"scroll"===e&&t.preventDefault()},r.truC=function(t){var e,i;return/rgb|rgba/.test(t)?(e=t.replace(/[^\d,]/g,"").split(","),i=e[3]?e[3]:null,i?{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2]),a:parseFloat(i)}:{r:parseInt(e[0]),g:parseInt(e[1]),b:parseInt(e[2])}):/#/.test(t)?{r:r.htr(t).r,g:r.htr(t).g,b:r.htr(t).b}:/transparent|none|initial|inherit/.test(t)?{r:0,g:0,b:0,a:0}:void 0},r.rth=function(t,e,r){return"#"+((1<<24)+(t<<16)+(e<<8)+r).toString(16).slice(1)},r.htr=function(t){var e=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(e,function(t,e,r,i){return e+e+r+r+i+i});var r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null},r.pe=function(t){if("function"==typeof t)return t;if("string"==typeof t){if(/easing|linear/.test(t))return r.Easing[t];if(/bezier/.test(t)){var e=t.replace(/bezier|\s|\(|\)/g,"").split(","),i=0,n=e.length;for(i;n>i;i++)e[i]=parseFloat(e[i]);return r.Ease.bezier(e[0],e[1],e[2],e[3])}return/physics/.test(t)?r.Physics[t]():r.Ease[t]()}},r.Easing={},r.Easing.linear=function(t){return t};var K=Math.PI,U=2*Math.PI,$=Math.PI/2,G=.1,J=.4;return r.Easing.easingSinusoidalIn=function(t){return-Math.cos(t*$)+1},r.Easing.easingSinusoidalOut=function(t){return Math.sin(t*$)},r.Easing.easingSinusoidalInOut=function(t){return-.5*(Math.cos(K*t)-1)},r.Easing.easingQuadraticIn=function(t){return t*t},r.Easing.easingQuadraticOut=function(t){return t*(2-t)},r.Easing.easingQuadraticInOut=function(t){return.5>t?2*t*t:-1+(4-2*t)*t},r.Easing.easingCubicIn=function(t){return t*t*t},r.Easing.easingCubicOut=function(t){return--t*t*t+1},r.Easing.easingCubicInOut=function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},r.Easing.easingQuarticIn=function(t){return t*t*t*t},r.Easing.easingQuarticOut=function(t){return 1- --t*t*t*t},r.Easing.easingQuarticInOut=function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},r.Easing.easingQuinticIn=function(t){return t*t*t*t*t},r.Easing.easingQuinticOut=function(t){return 1+--t*t*t*t*t},r.Easing.easingQuinticInOut=function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t},r.Easing.easingCircularIn=function(t){return-(Math.sqrt(1-t*t)-1)},r.Easing.easingCircularOut=function(t){return Math.sqrt(1-(t-=1)*t)},r.Easing.easingCircularInOut=function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},r.Easing.easingExponentialIn=function(t){return Math.pow(2,10*(t-1))-.001},r.Easing.easingExponentialOut=function(t){return 1-Math.pow(2,-10*t)},r.Easing.easingExponentialInOut=function(t){return(t*=2)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*(t-1)))},r.Easing.easingBackIn=function(t){var e=1.70158;return t*t*((e+1)*t-e)},r.Easing.easingBackOut=function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},r.Easing.easingBackInOut=function(t){var e=2.5949095;return(t*=2)<1?.5*t*t*((e+1)*t-e):.5*((t-=2)*t*((e+1)*t+e)+2)},r.Easing.easingElasticIn=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,-(G*Math.pow(2,10*(t-=1))*Math.sin((t-e)*U/J)))},r.Easing.easingElasticOut=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,G*Math.pow(2,-10*t)*Math.sin((t-e)*U/J)+1)},r.Easing.easingElasticInOut=function(t){var e;return 0===t?0:1===t?1:(!G||1>G?(G=1,e=J/4):e=J*Math.asin(1/G)/U,(t*=2)<1?-.5*G*Math.pow(2,10*(t-=1))*Math.sin((t-e)*U/J):G*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*U/J)*.5+1)},r.Easing.easingBounceIn=function(t){return 1-r.Easing.easingBounceOut(1-t)},r.Easing.easingBounceOut=function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},r.Easing.easingBounceInOut=function(t){return.5>t?.5*r.Easing.easingBounceIn(2*t):.5*r.Easing.easingBounceOut(2*t-1)+.5},r}); \ No newline at end of file diff --git a/kute-bezier.js b/kute-bezier.js new file mode 100644 index 0000000..44c23b9 --- /dev/null +++ b/kute-bezier.js @@ -0,0 +1,159 @@ +/* + * KUTE.js - The Light Tweening Engine | dnp_theme + * package bezier easing + * BezierEasing by Gaëtan Renaudeau 2014 – MIT License + * optimized by dnp_theme 2015 – MIT License + * Licensed under MIT-License +*/ + +KUTE.Ease = {}; + +KUTE.Ease.bezier = function(mX1, mY1, mX2, mY2) { + return _bz.pB(mX1, mY1, mX2, mY2); +}; + +var _bz = KUTE.Ease.bezier.prototype; + +// These values are established by empiricism with tests (tradeoff: performance VS precision) +_bz.ni = 4; // NEWTON_ITERATIONS +_bz.nms = 0.001; // NEWTON_MIN_SLOPE +_bz.sp = 0.0000001; // SUBDIVISION_PRECISION +_bz.smi = 10, // SUBDIVISION_MAX_ITERATIONS + +_bz.ksts = 11; // k Spline Table Size +_bz.ksss = 1.0 / (_bz.ksts - 1.0); // k Sample Step Size + +_bz.f32as = 'Float32Array' in window; // float32ArraySupported +_bz.msv = _bz.f32as ? new Float32Array (_bz.ksts) : new Array (_bz.ksts); // m Sample Values + +_bz.A = function(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }; +_bz.B = function(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }; +_bz.C = function(aA1) { return 3.0 * aA1; }; + +_bz.r = {}; +_bz.pB = function (mX1, mY1, mX2, mY2) { +this._p = false; var self = this; + +_bz.r = function(aX){ + if (!self._p) _bz.pc(mX1, mX2, mY1, mY2); + if (mX1 === mY1 && mX2 === mY2) return aX; + + if (aX === 0) return 0; + if (aX === 1) return 1; + return _bz.cB(_bz.gx(aX, mX1, mX2), mY1, mY2); +}; +return _bz.r; +}; + +// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. +_bz.cB = function(aT, aA1, aA2) { // calc Bezier + return ((_bz.A(aA1, aA2)*aT + _bz.B(aA1, aA2))*aT + _bz.C(aA1))*aT; +}; + +// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. +_bz.gS = function (aT, aA1, aA2) { // getSlope + return 3.0 * _bz.A(aA1, aA2)*aT*aT + 2.0 * _bz.B(aA1, aA2) * aT + _bz.C(aA1); +}; + +_bz.bS = function(a, aA, aB, mX1, mX2) { // binary Subdivide + var x, t, i = 0, j = _bz.sp, y = _bz.smi; + do { + t = aA + (aB - aA) / 2.0; + x = _bz.cB(t, mX1, mX2) - a; + if (x > 0.0) { + aB = t; + } else { + aA = t; + } + } while (Math.abs(x) > j && ++i < y); + return t; +}; + +_bz.nri = function (aX, agt, mX1, mX2) { // newton Raphs on Iterate +var i = 0, j = _bz.ni; + for (i; i < j; ++i) { + var cs = _bz.gS(agt, mX1, mX2); + if (cs === 0.0) return agt; + var x = _bz.cB(agt, mX1, mX2) - aX; + agt -= x / cs; + } + return agt; +}; + +_bz.csv = function (mX1, mX2) { // calc Sample Values +var i = 0, j = _bz.ksts; + for (i; i < j; ++i) { + _bz.msv[i] = _bz.cB(i * _bz.ksss, mX1, mX2); + } +}; + +_bz.gx = function (aX,mX1,mX2) { //get to X + var iS = 0.0, cs = 1, ls = _bz.ksts - 1; + + for (; cs != ls && _bz.msv[cs] <= aX; ++cs) { + iS += _bz.ksss; + } + --cs; + + // Interpolate to provide an initial guess for t + var dist = (aX - _bz.msv[cs]) / (_bz.msv[cs+1] - _bz.msv[cs]), + gt = iS + dist * _bz.ksss, + ins = _bz.gS(gt, mX1, mX2), + fiS = iS + _bz.ksss; + + if (ins >= _bz.nms) { + return _bz.nri(aX, gt, mX1, mX2); + } else if (ins === 0.0) { + return gt; + } else { + return _bz.bS(aX, iS, fiS, mX1, mX2); + } +}; + +_bz.pc = function(mX1, mX2, mY1, mY2) { + this._p = true; +if (mX1 != mY1 || mX2 != mY2) + _bz.csv(mX1, mX2); +}; + +// predefined bezier based easings, can be accessed via string, eg 'easeIn' or 'easeInOutQuart' +// _easings = ["linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInExpo","easeOutExpo","easeInOutExpo","slowMo","slowMo1","slowMo2"], +KUTE.Ease.easeIn = function(){ return _bz.pB(0.42, 0.0, 1.00, 1.0); }; +KUTE.Ease.easeOut = function(){ return _bz.pB(0.00, 0.0, 0.58, 1.0); }; +KUTE.Ease.easeInOut = function(){ return _bz.pB(0.50, 0.16, 0.49, 0.86); }; + +KUTE.Ease.easeInSine = function(){ return _bz.pB(0.47, 0, 0.745, 0.715); }; +KUTE.Ease.easeOutSine = function(){ return _bz.pB(0.39, 0.575, 0.565, 1); }; +KUTE.Ease.easeInOutSine = function(){ return _bz.pB(0.445, 0.05, 0.55, 0.95); }; + +KUTE.Ease.easeInQuad = function () { return _bz.pB(0.550, 0.085, 0.680, 0.530); }; +KUTE.Ease.easeOutQuad = function () { return _bz.pB(0.250, 0.460, 0.450, 0.940); }; +KUTE.Ease.easeInOutQuad = function () { return _bz.pB(0.455, 0.030, 0.515, 0.955); }; + +KUTE.Ease.easeInCubic = function () { return _bz.pB(0.55, 0.055, 0.675, 0.19); }; +KUTE.Ease.easeOutCubic = function () { return _bz.pB(0.215, 0.61, 0.355, 1); }; +KUTE.Ease.easeInOutCubic = function () { return _bz.pB(0.645, 0.045, 0.355, 1); }; + +KUTE.Ease.easeInQuart = function () { return _bz.pB(0.895, 0.03, 0.685, 0.22); }; +KUTE.Ease.easeOutQuart = function () { return _bz.pB(0.165, 0.84, 0.44, 1); }; +KUTE.Ease.easeInOutQuart = function () { return _bz.pB(0.77, 0, 0.175, 1); }; + +KUTE.Ease.easeInQuint = function(){ return _bz.pB(0.755, 0.05, 0.855, 0.06); }; +KUTE.Ease.easeOutQuint = function(){ return _bz.pB(0.23, 1, 0.32, 1); }; +KUTE.Ease.easeInOutQuint = function(){ return _bz.pB(0.86, 0, 0.07, 1); }; + +KUTE.Ease.easeInExpo = function(){ return _bz.pB(0.95, 0.05, 0.795, 0.035); }; +KUTE.Ease.easeOutExpo = function(){ return _bz.pB(0.19, 1, 0.22, 1); }; +KUTE.Ease.easeInOutExpo = function(){ return _bz.pB(1, 0, 0, 1); }; + +KUTE.Ease.easeInCirc = function(){ return _bz.pB(0.6, 0.04, 0.98, 0.335); }; +KUTE.Ease.easeOutCirc = function(){ return _bz.pB(0.075, 0.82, 0.165, 1); }; +KUTE.Ease.easeInOutCirc = function(){ return _bz.pB(0.785, 0.135, 0.15, 0.86); }; + +KUTE.Ease.easeInBack = function(){ return _bz.pB(0.600, -0.280, 0.735, 0.045); }; +KUTE.Ease.easeOutBack = function(){ return _bz.pB(0.175, 0.885, 0.320, 1.275); }; +KUTE.Ease.easeInOutBack = function(){ return _bz.pB(0.68, -0.55, 0.265, 1.55); }; + +KUTE.Ease.slowMo = function(){ return _bz.pB(0.000, 0.500, 1.000, 0.500); }; +KUTE.Ease.slowMo1 = function(){ return _bz.pB(0.000, 0.700, 1.000, 0.300); }; +KUTE.Ease.slowMo2 = function(){ return _bz.pB(0.000, 0.900, 1.000, 0.100); }; \ No newline at end of file diff --git a/kute-jquery.js b/kute-jquery.js new file mode 100644 index 0000000..153a26a --- /dev/null +++ b/kute-jquery.js @@ -0,0 +1,26 @@ +/* KUTE.js - The Light Tweening Engine + * package jQuery Plugin + * by dnp_theme + * Licensed under MIT-License + */ + +(function($) { + $.fn.KUTE = function( method, start, end, ops ) { // method can be Animate(), fromTo(), to(), stop(), start(), chain(), pause() + var tws = [], i, l = this.length; + + for (i=0;i 0.001) { + _kpg.L = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + _kpg.L * bounciness, + H: curve.H * bounciness * bounciness + }; + } + return curve.b; + })(); + + (function() { + var L2, b, curve, _results; + b = Math.sqrt(2 / (gravity * _kpg.L * _kpg.L)); + curve = { + a: -b, + b: b, + H: 1 + }; + if (initialForce) { + curve.a = 0; + curve.b = curve.b * 2; + } + curves.push(curve); + L2 = _kpg.L; + _results = []; + while (curve.b < 1 && curve.H > 0.001) { + L2 = curve.b - curve.a; + curve = { + a: curve.b, + b: curve.b + L2 * bounciness, + H: curve.H * elasticity + }; + _results.push(curves.push(curve)); + } + return _results; + })(); + _kpg.fn = function(t) { + var curve, i, v; + i = 0; + curve = curves[i]; + while (!(t >= curve.a && t <= curve.b)) { + i += 1; + curve = curves[i]; + if (!curve) { + break; + } + } + if (!curve) { + v = initialForce ? 0 : 1; + } else { + v = _kpg.getPointInCurve(curve.a, curve.b, curve.H, t, options, _kpg.L); + } + return v; + }; + + return _kpg.fn; +}; + +var _kpg = _kp.gravity.prototype; +_kpg.L = {}; +_kpg.fn = {}; +_kpg.getPointInCurve = function(a, b, H, t, o, L) { + var c, t2; + L = b - a; + t2 = (2 / L) * t - 1 - (a * 2 / L); + c = t2 * t2 * H - H + 1; + if (o.initialForce) { + c = 1 - c; + } + return c; +}; + +//throw up and pull down by gravity +_kp.forceWithGravity = function(o) { + var ops = o || {}; + ops.initialForce = true; + return _kp.gravity(ops); +}; + + +// multi point bezier +_kp.bezier = function(options) { + options = options || {}; + var points = options.points, + returnsToSelf = false, Bs = []; + + (function() { + var i, k; + + for (i in points) { + k = parseInt(i); + if (k >= points.length - 1) { + break; + } + _kpb.fn(points[k], points[k + 1], Bs); + } + return Bs; + })(); + + _kpb.run = function(t) { + if (t === 0) { + return 0; + } else if (t === 1) { + return 1; + } else { + return _kpb.yForX(t, Bs, returnsToSelf); + } + }; + return _kpb.run; +}; + +var _kpb = _kp.bezier.prototype; +_kpb.B2 = {}; +_kpb.run = {}; + +_kpb.fn = function(pointA, pointB, Bs) { + var B2 = function(t) { + return _kpb.Bezier(t, pointA, pointA.cp[pointA.cp.length - 1], pointB.cp[0], pointB); + }; + return Bs.push(B2); +}; + +_kpb.Bezier = function(t, p0, p1, p2, p3) { + return { + x: (Math.pow(1 - t, 3) * p0.x) + (3 * Math.pow(1 - t, 2) * t * p1.x) + (3 * (1 - t) * Math.pow(t, 2) * p2.x) + Math.pow(t, 3) * p3.x, + y: (Math.pow(1 - t, 3) * p0.y) + (3 * Math.pow(1 - t, 2) * t * p1.y) + (3 * (1 - t) * Math.pow(t, 2) * p2.y) + Math.pow(t, 3) * p3.y + }; +}; + +_kpb.yForX = function(xTarget, Bs, rTS) { + var B, aB, i, lower, percent, upper, x, xT, _i = 0, _len = Bs.length; + B = null; + for (_i; _i < _len; _i++) { + aB = Bs[_i]; + if (xTarget >= aB(0).x && xTarget <= aB(1).x) { + B = aB; + } + if (B !== null) { + break; + } + } + if (!B) { + return ( rTS ? 0 : 1 ); + } + xT = 0.0001; // xTolerance + lower = 0; upper = 1; + percent = (upper + lower) / 2; + x = B(percent).x; i = 0; + while (Math.abs(xTarget - x) > xT && i < 100) { + if (xTarget > x) { + lower = percent; + } else { + upper = percent; + } + percent = (upper + lower) / 2; + x = B(percent).x; + i++; + } + return B(percent).y; +}; + +_kp.physicsInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] } ] }); +}; + +_kp.physicsIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0.92 - (friction / 1000), y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 1, y: 1 } ] } ] }); +}; + +_kp.physicsOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [ { x: 0, y: 0, cp: [ { x: 0, y: 0 } ] }, { x: 1, y: 1, cp: [ { x: 0.08 + (friction / 1000), y: 1 } ] }] }); +}; + +_kp.physicsBackOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0,"y":0}]},{"x":1,"y":1,"cp":[{"x":0.735+(friction/1000),"y":1.3}]}] }); +}; + +_kp.physicsBackIn = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.28-(friction / 1000),"y":-0.6}]},{"x":1,"y":1,"cp":[{"x":1,"y":1}]}] }); +}; + +_kp.physicsBackInOut = function(options) { + var friction; + options = options || {}; + friction = options.friction|| 500; + return _kp.bezier({ points: [{"x":0,"y":0,"cp":[{"x":0.68-(friction / 1000),"y":-0.55}]},{"x":1,"y":1,"cp":[{"x":0.265+(friction / 1000),"y":1.45}]}] }); +}; \ No newline at end of file diff --git a/kute.full.js b/kute.full.js deleted file mode 100644 index b4f34da..0000000 --- a/kute.full.js +++ /dev/null @@ -1,810 +0,0 @@ -// kute.full.js - The Light Tweening Engine | by dnp_theme -// http://themeforest.net/user/dnp_theme -// License - MIT - - -// KUTE MAIN OBJECT -var KUTE = KUTE || ( function () { - var _tweens = []; - return { - getAll: function () { - return _tweens; - }, - removeAll: function () { - _tweens = []; - }, - add: function ( tween ) { - _tweens.push( tween ); - }, - remove: function ( tween ) { - var i = _tweens.indexOf( tween ); - if ( i !== -1 ) { - _tweens.splice( i, 1 ); - } - }, - update: function ( time ) { - if ( _tweens.length === 0 ) return false; - var i = 0; - time = time !== undefined ? time : window.performance.now(); - while ( i < _tweens.length ) { - if ( _tweens[ i ].update( time ) ) { - i++; - } else { - _tweens.splice( i, 1 ); - } - } - return true; - }, - process : function ( time ) { - requestAnimationFrame(KUTE.process); - KUTE.update( time ); - } - }; -} )(); - -KUTE.Animate = function( object, options ) { - - //element to animate - var el = typeof object === 'object' ? object : document.querySelector(object); - - //get true scroll container and current scroll - var bd = document.body, - htm = document.getElementsByTagName('HTML')[0], - sct = /webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? bd : htm, - crs = window.pageYOffset || sct.scrollTop; - - //determine if we're on IE or IE8 - var isIE = document.documentElement.classList.contains('ie'); - var isIE8 = document.documentElement.classList.contains('ie8'); - - //get element current style - var css = el.currentStyle || window.getComputedStyle(el); - - // default values - var ops = { - from : { - opacity : 1, // integer - width : '', // integer/px/% - height : '', // integer/px/% - color : '', //hex/rgb - backgroundColor : '', //hex/rgb - position : {top:'',right:'',bottom:'',left:''}, // integer/% - backgroundPosition: {x:'',y:''}, // integer/%/string[left,center,bottom,etc] - translate : {x:0, y:0, z:0}, // integer only - rotate : {x:0, y:0, z:0}, // integer only - scale : 1, // integer only - scroll : crs, // integer only - }, - to : { - opacity : '', - width : '', - height : '', - color : '', - backgroundColor : '', - position : {top:'',right:'',bottom:'',left:''}, - backgroundPosition: {x: '', y: ''}, - translate : {x:'', y:'', z:''}, - rotate : {x:'', y:'', z:''}, - scale : '', - scroll : '', - }, - easing : KUTE.Easing.Linear.None, //pe('linear') - delay : 0, - duration : 500, - start : null, // run function when tween starts - finish : null, // run function when tween finishes - special : null // run function while tween runing - }; - - //override the default values with option values - for (var x in options) { - if(typeof(options[x]) === 'object'){ - for (var y in options[x]){ - ops[x][y] = options[x][y]; - } - }else{ - ops[x] = options[x]; - } - } - - //create shorthand for all properties - var ofo = ops.from.opacity; - var ofw = ops.from.width; - var ofh = ops.from.height; - var ofc = ops.from.color; - var ofbc = ops.from.backgroundColor; - var oft = ops.from.position.top; - var ofr = ops.from.position.right; - var ofb = ops.from.position.bottom; - var ofl = ops.from.position.left; - var ofbx = ops.from.backgroundPosition.x; - var ofby = ops.from.backgroundPosition.y; - var oftx = ops.from.translate.x; - var ofty = ops.from.translate.y; - var oftz = ops.from.translate.z; - var ofrx = ops.from.rotate.x; - var ofry = ops.from.rotate.y; - var ofrz = ops.from.rotate.z; - var ofs = ops.from.scale; - var ofsc = ops.from.scroll; - - var oto = ops.to.opacity; - var otw = ops.to.width; - var oth = ops.to.height; - var otc = ops.to.color; - var otbc = ops.to.backgroundColor; - var ott = ops.to.position.top; - var otr = ops.to.position.right; - var otb = ops.to.position.bottom; - var otl = ops.to.position.left; - var otbx = ops.to.backgroundPosition.x; - var otby = ops.to.backgroundPosition.y; - var ottx = ops.to.translate.x; - var otty = ops.to.translate.y; - var ottz = ops.to.translate.z; - var otrx = ops.to.rotate.x; - var otry = ops.to.rotate.y; - var otrz = ops.to.rotate.z; - var ots = ops.to.scale; - var otsc = ops.to.scroll; - - //process easing - var pes = typeof ops.easing === 'string' ? pe(ops.easing) : ops.easing; - - //from/initial values - var icor = (cv(ofc) ? parseInt(pc(ofc)[0]) : '') || parseInt(pc(truC(css.color))[0]); - var icog = (cv(ofc) ? parseInt(pc(ofc)[1]) : '') || parseInt(pc(truC(css.color))[1]); - var icob = (cv(ofc) ? parseInt(pc(ofc)[2]) : '') || parseInt(pc(truC(css.color))[2]); - - var ibcr = (cv(ofbc) ? parseInt(pc(ofbc)[0]) : '') || parseInt(pc(truC(css.backgroundColor))[0]); - var ibcg = (cv(ofbc) ? parseInt(pc(ofbc)[1]) : '') || parseInt(pc(truC(css.backgroundColor))[1]); - var ibcb = (cv(ofbc) ? parseInt(pc(ofbc)[2]) : '') || parseInt(pc(truC(css.backgroundColor))[2]); - - var iwi = cv(ofw) ? truD(ofw)[0] : truD( css.width )[0]; - var ihe = cv(ofh) ? truD(ofh)[0] : truD( css.height )[0]; - - var ito = cv(oft) ? truD(oft)[0] : ''; - var iri = cv(ofr) ? truD(ofr)[0] : ''; - var ibo = cv(ofb) ? truD(ofb)[0] : ''; - var ile = cv(ofl) ? truD(ofl)[0] : ''; - - var ibx, iby, bx, by; - if ( cv( otbx ) || cv( otby ) ) { - ibx = cv( ofbx ) ? truX(ofbx) : bPos(el)[0]; - iby = cv( ofby ) ? truY(ofby) : bPos(el)[1]; - } else { - ibx = ''; - iby = ''; - } - - var tr3d,tx,ty,tz,itx,ity,itz; - if ( cv( ottx ) || cv( otty ) || cv( ottz ) ) { - itx = cv(oftx) ? truD(oftx)[0] : 0; - ity = cv(ofty) ? truD(ofty)[0] : 0; - itz = cv(oftz) ? truD(oftz)[0] : 0; - } else { - itx = ''; ity = ''; itz = ''; - } - - var irx = cv(ofrx) ? parseInt(ofrx) :''; //always deg - var iry = cv(ofry) ? parseInt(ofry) :''; - var irz = cv(ofrz) ? parseInt(ofrz) :''; - - var isa = parseFloat(ofs); // scale can be float - var iop = parseFloat(ofo); // opacity - var isc = parseInt(ofsc); // scroll - - - //target values - var cor = cv(otc) ? parseInt(pc(otc)[0]) : ''; - var cog = cv(otc) ? parseInt(pc(otc)[1]) : ''; - var cob = cv(otc) ? parseInt(pc(otc)[2]) : ''; - - var bcr = cv(otbc) ? parseInt(pc(otbc)[0]) : ''; - var bcg = cv(otbc) ? parseInt(pc(otbc)[1]) : ''; - var bcb = cv(otbc) ? parseInt(pc(otbc)[2]) : ''; - - var wi = cv( otw ) ? truD(otw)[0] : ''; - var he = cv( oth ) ? truD(oth)[0] : ''; - - var top = cv(ott) ? truD(ott)[0] : ''; - var ri = cv(otr) ? truD(otr)[0] : ''; - var bo = cv(otb) ? truD(otb)[0] : ''; - var le = cv(otl) ? truD(otl)[0] : ''; - - if ( cv( otbx ) || cv( otby ) ) { - bx = cv( otbx ) ? truX(otbx) : ibx; - by = cv( otby ) ? truY(otby) : iby; - } else { - bx = ''; - by = ''; - } - - if ( cv( ottx ) || cv( otty ) || cv( ottz ) ) { // translate 3d - tx = cv( ottx ) ? truD(ottx)[0] : 0; - ty = cv( otty ) ? truD(otty)[0] : 0; - tz = cv( ottz ) ? truD(ottz)[0] : 0; - } else { - tx = ''; ty = ''; tz = ''; - } - - var rx = cv( otrx ) ? parseInt(otrx) : ''; // rotate - var ry = cv( otry ) ? parseInt(otry) : ''; - var rz = cv( otrz ) ? parseInt(otrz) : ''; - - var sa = cv( ots ) ? parseFloat(ots) : ''; // scale values below 1 need to be reformated - var op = cv( oto ) ? parseFloat(oto) : ''; // opacity - var sc = cv( otsc ) ? parseInt(otsc) : ''; // scroll - - //check unit - var wiu = cv( wi ) ? truD(otw)[1] : ''; - var heu = cv( he ) ? truD(oth)[1] : ''; - - var tou = cv( ott ) ? truD(ott)[1] : ''; - var riu = cv( otr ) ? truD(otr)[1] : ''; - var bou = cv( otb ) ? truD(otb)[1] : ''; - var leu = cv( otl ) ? truD(otl)[1] : ''; - - var txu = cv( tx ) ? truD(ottx)[1] : ''; - var tyu = cv( ty ) ? truD(otty)[1] : ''; - var tzu = cv( tz ) ? truD(ottz)[1] : ''; - - var from = { w: iwi, h: ihe, t: ito, r: iri, b: ibo, l: ile, colr: icor, colg: icog, colb: icob, bgr: ibcr, bgg: ibcg, bgb: ibcb, bgX: ibx, bgY: iby, scale: isa, trX: itx, trY: ity, trZ: itz, roX: irx, roY: iry, roZ: irz, opacity: iop, scroll: isc }; - var target = { w: wi, h: he, t: top, r: ri, b: bo, l: le, colr: cor, colg: cog, colb: cob, bgr: bcr, bgg: bcg, bgb: bcb, bgX: bx, bgY: by, scale: sa, trX: tx, trY: ty, trZ: tz, roX: rx, roY: ry, roZ: rz, opacity: op, scroll: sc }; - - return new KUTE.Tween( from ) - .to( target, ops.duration ) - .delay( ops.delay ) - .easing( pes ) - .onStart( runStart ) - .onUpdate( - function () { - - //color and background-color - if ( cv(cor) ) { el.style.color = rth( parseInt(this.colr),parseInt(this.colg),parseInt(this.colb) ); } - if ( cv(bcr) ) { el.style.backgroundColor = rth( parseInt(this.bgr),parseInt(this.bgg),parseInt(this.bgb)); } - - //translate3d - if ( cv(tx) || cv(ty) || cv(tz) ) { - tr3d = 'translate3d(' + ((this.trX + txu) || 0) + ',' + ((this.trY + tyu) || 0) + ',' + ((this.trZ + tzu) || 0) + ')'; - } else { tr3d = ''; } - - var roxt = cv(rx) ? ' rotateX(' + this.roX + 'deg)' : ''; - var royt = cv(ry) ? ' rotateY(' + this.roY + 'deg)' : ''; - var rozt = cv(rz) ? ' rotateZ(' + this.roZ + 'deg)' : ''; - - //scale - var sca = cv(sa) ? ' scale(' + this.scale + ')' : ''; - //do a zoom for IE8 - if (isIE8 && cv(sa)) { - el.style.zoom = this.scale; - } - //sum all transform - var transform = sca + tr3d + roxt + royt + rozt; - var perspective = parseInt(css.perspective)||''; - if ( cv(transform) ) { tr(transform,perspective) } - - //dimensions - if ( cv(wi) ) { el.style.width = this.w + wiu; } - if ( cv(he) ) { el.style.height = this.h + heu; } - - //positioning - if ( cv(top) ) { el.style.top = this.t + tou; } - if ( cv(ri ) ) { el.style.right = this.r + riu; } - if ( cv(bo ) ) { el.style.bottom = this.b + bou; } - if ( cv(le ) ) { el.style.left = this.l + leu; } - - // scrolling - if ( cv(sc) ) { sct.scrollTop = this.scroll; } - - //background position - if ( cv(bx) || cv(by) ) { - var bXX = this.bgX; - var bYY = this.bgY; - el.style.backgroundPosition = bXX.toString()+'% '+bYY.toString()+'%'; - } - - //opacity - if ( cv(op) ) { el.style.opacity = (this.opacity).toFixed(2); } - //do a filter opacity for IE8 - if (isIE8 && cv(op)) { - el.style.filter = "alpha(opacity=" + parseInt(100 * this.opacity) + ")" - } - - //run special function onUpdate - if ( ops.special && typeof ops.special === "function") { ops.special(); } - } - ) - .onComplete( runFinished ) - .start(); - - //callback when tween is finished - function runFinished() { - if ( ops.finish && typeof ops.finish === "function") { - ops.finish(); - } - if ( cv(otsc) ) { - document.body.removeAttribute('data-tweening') - } - } - - //callback when tween just started - function runStart() { - if ( ops.start && typeof ops.start === "function") { - ops.start(); - } - //fix the scrolling being interrupted via mousewheel - if ( cv(otsc) ) { - if ( !document.body.getAttribute('data-tweening') && document.body.getAttribute('data-tweening') !== 'scroll' ) - document.body.setAttribute('data-tweening','scroll'); - } - } - - /* Process values utils - ----------------------------*/ - - //process easing 31 - function pe(e) { - if ( e === 'linear' ) return KUTE.Easing.Linear.None; - if ( e === 'quadraticIn' ) return KUTE.Easing.Quadratic.In; - if ( e === 'quadraticOut' ) return KUTE.Easing.Quadratic.Out; - if ( e === 'quadraticInOut' ) return KUTE.Easing.Quadratic.InOut; - if ( e === 'cubicIn' ) return KUTE.Easing.Cubic.In; - if ( e === 'cubicOut' ) return KUTE.Easing.Cubic.Out; - if ( e === 'cubicInOut' ) return KUTE.Easing.Cubic.InOut; - if ( e === 'quarticIn' ) return KUTE.Easing.Quartic.In; - if ( e === 'quarticOut' ) return KUTE.Easing.Quartic.Out; - if ( e === 'quarticInOut' ) return KUTE.Easing.Quartic.InOut; - if ( e === 'quinticIn' ) return KUTE.Easing.Quintic.In; - if ( e === 'quinticOut' ) return KUTE.Easing.Quintic.Out; - if ( e === 'quinticInOut' ) return KUTE.Easing.Quintic.InOut; - if ( e === 'sinusoidalIn' ) return KUTE.Easing.Sinusoidal.In; - if ( e === 'sinusoidalOut' ) return KUTE.Easing.Sinusoidal.Out; - if ( e === 'sinusoidalInOut' ) return KUTE.Easing.Sinusoidal.InOut; - if ( e === 'exponentialIn' ) return KUTE.Easing.Exponential.In; - if ( e === 'exponentialOut' ) return KUTE.Easing.Exponential.Out; - if ( e === 'exponentialInOut' ) return KUTE.Easing.Exponential.InOut; - if ( e === 'circularIn' ) return KUTE.Easing.Circular.In; - if ( e === 'circularOut' ) return KUTE.Easing.Circular.Out; - if ( e === 'circularInOut' ) return KUTE.Easing.Circular.InOut; - if ( e === 'elasticIn' ) return KUTE.Easing.Elastic.In; - if ( e === 'elasticOut' ) return KUTE.Easing.Elastic.Out; - if ( e === 'elasticInOut' ) return KUTE.Easing.Elastic.InOut; - if ( e === 'backIn' ) return KUTE.Easing.Back.In; - if ( e === 'backOut' ) return KUTE.Easing.Back.Out; - if ( e === 'backInOut' ) return KUTE.Easing.Back.InOut; - if ( e === 'bounceIn' ) return KUTE.Easing.Bounce.In; - if ( e === 'bounceOut' ) return KUTE.Easing.Bounce.Out; - if ( e === 'bounceInOut' ) return KUTE.Easing.Bounce.InOut; - //default - return KUTE.Easing.Exponential.InOut; - } - - // value checker - function cv(v) { - if ( v !== undefined && v !== '' && v !== 'NaN' ) return true; - } - - // get true w/h - function truD(d){ - var v,u; - if (/px/i.test(d)) { - u = 'px'; v = parseInt( d ); - } else if (/%/i.test(d)) { - u = '%'; v = parseInt( d ); - } else { - v = d; u = 'px'; - } - return [v,u]; - } - - // get background position true values - function truX(x) { - if ( x == 'left' ) { - return 0; - } else if ( x == 'center' ) { - return 50; - } else if ( x == 'right' ) { - return 100; - } else { - return parseInt( x ); - } - } - function truY(y) { - if ( y == 'top' ) { - return 0; - } else if ( y == 'center' ) { - return 50; - } else if ( y == 'bottom' ) { - return 100; - } else { - return parseInt( y ); - } - } - - // get current background position - function bPos(elem) { - var sty = css.backgroundPosition,x,y; - var pos = sty.split(" "); - x = truX(pos[0]); - if ( cv(pos[1]) ) { - y = truY(pos[1]); - } else { - y = 0; - } - return [ x, y ]; - } - - // convert transparent to rgba() - function truC(c) { - if ( c === 'transparent' ) { - return c.replace('transparent','rgba(0,0,0,0)'); - } else if ( cv(c) ) { - return c; - } - } - - // process color - function pc(c) { - if ( cv(c) && /#/i.test(c) ) { return [htr(c).r,htr(c).g,htr(c).b]; } else { return c.replace(/[^\d,]/g, '').split(','); } - } - - // transform rgb to hex or vice-versa - function rth(r, g, b) { - return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); - } - function htr(hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var shr = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shr, function(m, r, g, b) { - return r + r + g + g + b + b; - }); - - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; - } - - // process transform - function tr(p,pp) { - el.style.transform = p; - el.style.msTransform = (cv(pp)?'perspective('+pp+'px) ':'') + p; - el.style.MozTransform = p; - el.style.webkitTransform = p; - } -}; - -KUTE.Tween = function ( object ) { - - var _object = object; - var _valuesStart = {}; - var _valuesEnd = {}; - var _valuesStartRepeat = {}; - var _duration = 700; - var _isPlaying = false; - var _delayTime = 0; - var _startTime = null; - var _easingFunction = KUTE.Easing.Linear.None; - var _onStartCallback = null; - var _onStartCallbackFired = false; - var _onUpdateCallback = null; - var _onCompleteCallback = null; - var _onStopCallback = null; - - // Set all starting values present on the target object - for ( var field in object ) { - _valuesStart[ field ] = parseFloat(object[field], 10); - } - - this.to = function ( properties, duration ) { - - if ( duration !== undefined ) { - _duration = duration; - } - - _valuesEnd = properties; - return this; - }; - - this.start = function ( time ) { - - KUTE.add( this ); - _isPlaying = true; - _onStartCallbackFired = false; - _startTime = time !== undefined ? time : window.performance.now(); - _startTime += _delayTime; - - for ( var property in _valuesEnd ) { - // check if an Array was provided as property value - if ( _valuesEnd[ property ] instanceof Array ) { - if ( _valuesEnd[ property ].length === 0 ) { - continue; - } - - // create a local copy of the Array with the start value at the front - _valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] ); - } - - if( ( _valuesEnd[ property ] instanceof Array ) === false ) { - _valuesEnd[ property ] *= 1.0; // Ensures we're using numbers, not strings - } - - _valuesStart[ property ] = _object[ property ]; - - if( ( _valuesStart[ property ] instanceof Array ) === false ) { - _valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings - } - } - return this; - }; - - this.stop = function () { - if ( !_isPlaying ) { - return this; - } - - KUTE.remove( this ); - _isPlaying = false; - - if ( _onStopCallback !== null ) { - _onStopCallback.call( _object ); - } - - return this; - - }; - - this.delay = function ( amount ) { - _delayTime = amount; - return this; - }; - - this.easing = function ( easing ) { - _easingFunction = easing; - return this; - }; - - this.onStart = function ( callback ) { - _onStartCallback = callback; - return this; - }; - - this.onUpdate = function ( callback ) { - _onUpdateCallback = callback; - return this; - }; - - this.onComplete = function ( callback ) { - _onCompleteCallback = callback; - return this; - }; - - this.onStop = function ( callback ) { - _onStopCallback = callback; - return this; - }; - - this.update = function ( time ) { - var property; - - if ( time < _startTime ) { - return true; - } - - if ( _onStartCallbackFired === false ) { - if ( _onStartCallback !== null ) { - _onStartCallback.call( _object ); - } - _onStartCallbackFired = true; - } - - var elapsed = ( time - _startTime ) / _duration; - elapsed = elapsed > 1 ? 1 : elapsed; - var value = _easingFunction( elapsed ); - - for ( property in _valuesEnd ) { - - var start = _valuesStart[ property ] || 0; - var end = _valuesEnd[ property ]; - - // Parses relative end values with start as base (e.g.: +10, -3) - if ( typeof(end) === "string" ) { - end = start + parseFloat(end, 10); - } - - // protect against non numeric properties. - if ( typeof(end) === "number" ) { - _object[ property ] = start + ( end - start ) * value; - } - } - - if ( _onUpdateCallback !== null ) { - _onUpdateCallback.call( _object, value ); - } - - if ( elapsed == 1 ) { - - if ( _onCompleteCallback !== null ) { - _onCompleteCallback.call( _object ); - } - return false; - } - return true; - }; -}; - -KUTE.process(0); - -KUTE.Easing = { - Linear: { - None: function ( k ) { - return k; - } - }, - Quadratic: { - In: function ( k ) { - return k * k; - }, - - Out: function ( k ) { - return k * ( 2 - k ); - }, - - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k; - return - 0.5 * ( --k * ( k - 2 ) - 1 ); - } - }, - Cubic: { - In: function ( k ) { - return k * k * k; - }, - Out: function ( k ) { - return --k * k * k + 1; - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k + 2 ); - } - }, - Quartic: { - In: function ( k ) { - return k * k * k * k; - }, - Out: function ( k ) { - return 1 - ( --k * k * k * k ); - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k; - return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 ); - } - }, - Quintic: { - In: function ( k ) { - return k * k * k * k * k; - }, - - Out: function ( k ) { - return --k * k * k * k * k + 1; - }, - - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 ); - } - }, - Sinusoidal: { - In: function ( k ) { - return 1 - Math.cos( k * Math.PI / 2 ); - }, - Out: function ( k ) { - return Math.sin( k * Math.PI / 2 ); - }, - InOut: function ( k ) { - return 0.5 * ( 1 - Math.cos( Math.PI * k ) ); - } - }, - - Exponential: { - In: function ( k ) { - return k === 0 ? 0 : Math.pow( 1024, k - 1 ); - }, - Out: function ( k ) { - return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k ); - }, - InOut: function ( k ) { - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 ); - return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 ); - } - }, - Circular: { - In: function ( k ) { - return 1 - Math.sqrt( 1 - k * k ); - }, - Out: function ( k ) { - return Math.sqrt( 1 - ( --k * k ) ); - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1); - return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1); - } - }, - Elastic: { - In: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); - }, - Out: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 ); - }, - InOut: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); - return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1; - } - }, - Back: { - In: function ( k ) { - var s = 1.70158; - return k * k * ( ( s + 1 ) * k - s ); - }, - Out: function ( k ) { - var s = 1.70158; - return --k * k * ( ( s + 1 ) * k + s ) + 1; - }, - InOut: function ( k ) { - var s = 1.70158 * 1.525; - if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) ); - return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 ); - } - }, - Bounce: { - In: function ( k ) { - return 1 - KUTE.Easing.Bounce.Out( 1 - k ); - }, - Out: function ( k ) { - if ( k < ( 1 / 2.75 ) ) { - return 7.5625 * k * k; - } else if ( k < ( 2 / 2.75 ) ) { - return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; - } else if ( k < ( 2.5 / 2.75 ) ) { - return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; - } else { - return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; - } - }, - InOut: function ( k ) { - if ( k < 0.5 ) return KUTE.Easing.Bounce.In( k * 2 ) * 0.5; - return KUTE.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5; - } - } -}; - - -// prevent mousewheel or touch events while tweening scroll -document.addEventListener('mousewheel', preventScroll, false); -document.addEventListener('touchstart', preventScroll, false); -function preventScroll(e){ - var data = document.body.getAttribute('data-tweening'); - if ( data && data === 'scroll' ) { - e.preventDefault(); - } -}; diff --git a/kute.js b/kute.js index 5b69831..d20c73e 100644 --- a/kute.js +++ b/kute.js @@ -1,675 +1,855 @@ -// kute.js - The Light Tweening Engine | by dnp_theme -// http://themeforest.net/user/dnp_theme -// License - MIT - -// KUTE MAIN OBJECT -var KUTE = KUTE || ( function () { - var _tweens = []; - return { - getAll: function () { - return _tweens; - }, - removeAll: function () { - _tweens = []; - }, - add: function ( tween ) { - _tweens.push( tween ); - }, - remove: function ( tween ) { - var i = _tweens.indexOf( tween ); - if ( i !== -1 ) { - _tweens.splice( i, 1 ); +/* KUTE.js - The Light Tweening Engine + * by dnp_theme + * Licensed under MIT-License + */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['KUTE'], factory); // AMD. Register as an anonymous module. + } else if (typeof exports == 'object') { + module.exports = factory(); // Node, not strict CommonJS + } else { + // Browser globals + root.KUTE = root.KUTE || factory(); + } +}(this, function () { + var K = K || {}, _tws = [], _t, _stk = false, // _stoppedTick // _tweens // KUTE, _tween, _tick, + _pf = getPrefix(), // prefix + _rafR = _rafR || ((!('requestAnimationFrame' in window)) ? true : false), // is prefix required for requestAnimationFrame + _pfT = _pfT || ((!('transform' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for transform + _pfB = _pfB || ((!('border-radius' in document.getElementsByTagName('div')[0].style)) ? true : false), // is prefix required for border-radius + _tch = _tch || (('ontouchstart' in window || navigator.msMaxTouchPoints) || false), // support Touch? + _ev = _ev || (_tch ? 'touchstart' : 'mousewheel'), //event to prevent on scroll + + _bd = document.body, + _htm = document.getElementsByTagName('HTML')[0], + _sct = (/webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? _bd : _htm), + + _isIE = /ie/.test(document.documentElement.className), + _isIE8 = /ie8/.test(document.documentElement.className), + + //assign preffix to DOM properties + _pfp = _pfp || _pfT ? _pf + 'Perspective' : 'perspective', + _pfo = _pfo || _pfT ? _pf + 'PerspectiveOrigin' : 'perspectiveOrigin', + _tr = _tr || _pfT ? _pf + 'Transform' : 'transform', + _br = _br || _pfB ? _pf + 'BorderRadius' : 'borderRadius', + _brtl = _brtl || _pfB ? _pf + 'BorderTopLeftRadius' : 'borderTopLeftRadius', + _brtr = _brtr || _pfB ? _pf + 'BorderTopRightRadius' : 'borderTopRightRadius', + _brbl = _brbl || _pfB ? _pf + 'BorderBottomLeftRadius' : 'borderBottomLeftRadius', + _brbr = _brbr || _pfB ? _pf + 'BorderBottomRightRadius' : 'borderBottomRightRadius', + _raf = _raf || _rafR ? window[_pf + 'RequestAnimationFrame'] : window['requestAnimationFrame'], + _caf = _caf || _rafR ? window[_pf + 'CancelAnimationFrame'] : window['cancelAnimationFrame'], + + //supported properties + _cls = ['color', 'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'], // colors 'hex', 'rgb', 'rgba' -- #fff / rgb(0,0,0) / rgba(0,0,0,0) + _sc = ['scrollTop', 'scroll'], //scroll, it has no default value, it's calculated on tween start + _clp = ['clip'], // clip + _op = ['opacity'], // opacity + _rd = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomLeftRadius', 'borderBottomRightRadius'], // border radius px/any + _bm = ['top', 'left', 'right', 'bottom', + 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', + 'padding', 'margin', 'paddingTop','paddingBottom', 'paddingLeft', 'paddingRight', 'marginTop','marginBottom', 'marginLeft', 'marginRight', + 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'], // dimensions / box model + _tp = ['fontSize','lineHeight','letterSpacing'], // text properties + _bg = ['backgroundPosition'], // background position + _3d = ['rotateX', 'rotateY','translateZ'], // transform properties that require perspective + _tf = ['translate3d', 'translateX', 'translateY', 'translateZ', 'rotate', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scale'], // transform + _all = _cls.concat(_sc, _clp, _op, _rd, _bm, _tp, _bg, _tf), al = _all.length, + _tfS = {}, _tfE = {}, _tlS = {}, _tlE = {}, _rtS = {}, _rtE = {}, //internal temp + _d = _d || {}; //all properties default values + + //populate default values object + for ( var i=0; i< al; i++){ + var p = _all[i]; + if (_cls.indexOf(p) !== -1){ + _d[p] = 'rgba(0,0,0,0)'; // _d[p] = {r:0,g:0,b:0,a:1}; + } else if ( _rd.indexOf(p) !== -1 || _bm.indexOf(p) !== -1 || _tp.indexOf(p) !== -1) { + _d[p] = 0; + } else if ( _bg.indexOf(p) !== -1 ){ + _d[p] = [50,50]; + } else if ( p === 'clip' ){ + _d[p] = [0,0,0,0]; + } else if ( p === 'translate3d' ){ + _d[p] = [0,0,0]; + } else if ( p === 'translate' ){ + _d[p] = [0,0]; + } else if ( p === 'rotate' || /X|Y|Z/.test(p) ){ + _d[p] = 0; + } else if ( p === 'scale' || p === 'opacity' ){ + _d[p] = 1; + } + } + + //more internals + K.getAll = function () { return _tws; }; + K.removeAll = function () { _tws = []; }; + K.add = function (tw) { _tws.push(tw); }; + K.remove = function (tw) { + var i = _tws.indexOf(tw); + if (i !== -1) { + _tws.splice(i, 1); + } + }; + + // internal ticker + K.t = function (t) { + _t = _raf(K.t); + var i = 0, l = _tws.length; + while ( i < l ) { + if (!_tws[i]) { return false; } + if (_tws[i].u(t)) { + i++; + } else { + _tws.splice(i, 1); } - }, - update: function ( time ) { - if ( _tweens.length === 0 ) return false; - var i = 0; - time = time !== undefined ? time : window.performance.now(); - while ( i < _tweens.length ) { - if ( _tweens[ i ].update( time ) ) { - i++; + } + _stk = false; + return true; + }; + + // internal stopTick + K.s = function () { + if ( _stk === false ) { + _caf(_t); + _stk = true; + _t = null; + } + }; + + //main methods + K.to = function (el, to, o) { + if ( o === undefined ) { o = {}; } + var _el = _el || typeof el === 'object' ? el : document.querySelector(el), + _o = _o || o; + _o.rpr = true; + _o.easing = _o && K.pe(_o.easing) || K.Easing.linear; + + var _vS = to, // we're gonna have to build this object at start + _vE = K.prP(to, true), + _tw = new K.Tween(_el, _vS, _vE, _o); + return _tw; + }; + + K.fromTo = function (el, f, to, o) { + if ( o === undefined ) { o = {}; } + var _el = _el || typeof el === 'object' ? el : document.querySelector(el); + var _o = o; + + _o.easing = _o && K.pe(_o.easing) || K.Easing.linear; + + var _vS = K.prP(f, false), + _vE = K.prP(to, true), + _tw = new K.Tween(_el, _vS, _vE, _o); + return _tw; + }; + // fallback method for previous versions + K.Animate = function (el, f, to, o) { + return K.fromTo(el, f, to, o); + }; + + // render for each property + K.r = function (w,v) { + var p, css = w._el && w._el.style, opp = _isIE8 ? 'filter':'opacity', + ets = (w._el === undefined || w._el === null) ? _sct : w._el; + for (p in w._vE) { + + var _start = w._vS[p], + _end = w._vE[p], + v1 = _start.value, + v2 = _end.value, + tv = v1 + (v2 - v1) * v, + u = _end.unit, + // checking array on every frame takes time so let's cache these + cls = _cls.indexOf(p) !== -1, + bm = _tp.indexOf(p) !== -1 || _bm.indexOf(p) !== -1, + rd = _rd.indexOf(p) !== -1 && !_isIE8, + sc = _sc.indexOf(p) !== -1, + bg = _bg.indexOf(p) !== -1, + clp = _clp.indexOf(p) !== -1, + op = _op.indexOf(p) !== -1, + tf = p === 'transform' && !_isIE8; + + //process styles by property / property type + if ( rd ) { + if (p === 'borderRadius') { + css[_br] = tv + u; + } else if (p === 'borderTopLeftRadius') { + css[_brtl] = tv + u; + } else if (p === 'borderTopRightRadius') { + css[_brtr] = tv + u; + } else if (p === 'borderBottomLeftRadius') { + css[_brbl] = tv + u; + } else if (p === 'borderBottomRightRadius') { + css[_brbr] = tv + u; + } + + } else if (tf) { + var _tS = '', tP, rps, pps = 'perspective('+w._pp+'px) '; //transform style & property + + for (tP in _end) { + var t1 = _start[tP], t2 = _end[tP]; + rps = _3d.indexOf(tP) !== -1 && !_isIE; + + if ( tP === 'translate' ) { + var tls = '', ts = {}, ax; + + for (ax in t2){ + var x1 = t1[ax].value || 0, x2 = t2[ax].value || 0, xu = t2[ax].unit || 'px'; + ts[ax] = x1===x2 ? x2+xu : (x1 + ( x2 - x1 ) * v) + xu; + } + tls = t2.x ? 'translate(' + ts.x + ',' + ts.y + ')' : + 'translate3d(' + ts.translateX + ',' + ts.translateY + ',' + ts.translateZ + ')'; + + _tS = (_tS === '') ? tls : (tls + ' ' + _tS); + } else if ( tP === 'rotate' ) { + var rt = '', rS = {}, rx; + + for ( rx in t2 ){ + if ( t1[rx] ) { + var a1 = t1[rx].value, a2 = t2[rx].value, au = t2[rx].unit||'deg', + av = a1 + (a2 - a1) * v; + rS[rx] = rx ==='z' ? 'rotate('+av+au+')' : rx + '(' + av + au + ') '; + } + } + rt = t2.z ? rS.z : (rS.rotateX||'') + (rS.rotateY||'') + (rS.rotateZ||''); + + _tS = (_tS === '') ? rt : (_tS + ' ' + rt); + } else if (tP==='skew') { + var sk = '', sS = {}; + for ( var sx in t2 ){ + if ( t1[sx] ) { + var s1 = t1[sx].value, s2 = t2[sx].value, su = t2[sx].unit||'deg', + sv = s1 + (s2 - s1) * v; + sS[sx] = sx + '(' + sv + su + ') '; + } + } + sk = (sS.skewX||'') + (sS.skewY||''); + _tS = (_tS === '') ? sk : (_tS + ' ' + sk); + } else if (tP === 'scale') { + var sc1 = t1.value, sc2 = t2.value, + s = sc1 + (sc2 - sc1) * v, scS = tP + '(' + s + ')'; + _tS = (_tS === '') ? scS : (_tS + ' ' + scS); + } + } + css[_tr] = rps || ( w._pp !== undefined && w._pp !== 0 ) ? pps + _tS : _tS; + } else if ( cls ) { + var _c = {}, c; + + for (c in v2) { + if ( c !== 'a' ){ + _c[c] = parseInt(v1[c] + (v2[c] - v1[c]) * v)||0; + } else { + _c[c] = (v1[c] && v2[c]) ? parseFloat(v1[c] + (v2[c] - v1[c]) * v) : null; + } + } + + if ( w._hex ) { + css[p] = K.rth( parseInt(_c.r), parseInt(_c.g), parseInt(_c.b) ); } else { - _tweens.splice( i, 1 ); + css[p] = !_c.a || _isIE8 ? 'rgb(' + _c.r + ',' + _c.g + ',' + _c.b + ')' : 'rgba(' + _c.r + ',' + _c.g + ',' + _c.b + ',' + _c.a + ')'; + } + } else if ( bm ) { + css[p] = tv+u; + } else if ( sc ) { + ets.scrollTop = v1 + ( v2 - v1 ) * v; + } else if ( bg ) { + var px1 = _start.x.v, px2 = _end.x.v, py1 = _start.y.v, py2 = _end.y.v, + px = (px1 + ( px2 - px1 ) * v), pxu = '%', + py = (py1 + ( py2 - py1 ) * v), pyu = '%'; + css[p] = px + pxu + ' ' + py + pyu; + } else if ( clp ) { + var h = 0, cl = []; + for (h;h<4;h++){ + var c1 = _start[h].v, c2 = _end[h].v, cu = _end[h].u || 'px'; + cl[h] = ((c1 + ( c2 - c1 ) * v)) + cu; + } + css[p] = 'rect('+cl+')'; + } else if ( op ) { + css[opp] = !_isIE8 ? tv : "alpha(opacity=" + parseInt(tv*100) + ")"; + } + } + }; + + K.perspective = function (l,w) { + if ( w._ppo !== undefined ) { l.style[_pfo] = w._ppo; } // element perspective origin + if ( w._ppp !== undefined ) { l.parentNode.style[_pfp] = w._ppp + 'px'; } // parent perspective + if ( w._pppo !== undefined ) { l.parentNode.style[_pfo] = w._pppo; } // parent perspective origin + }; + + K.Tween = function (_el, _vS, _vE, _o) { + this._el = this._el || _el; // element animation is applied to + this._dr = this._dr || _o&&_o.duration || 700; //duration + this._r = this._r || _o&&_o.repeat || 0; // _repeat + this._vSR = {}; // internal valuesStartRepeat + this._vS = _vS; // valuesStart + this._vE = _vE; // valuesEnd + this._y = this._y || _o&&_o.yoyo || false; // _yoyo + this.playing = false; // _isPlaying + this.reversed = false; // _reversed + this._rD = this._rD || _o&&_o.repeatDelay || 0; // _repeatDelay + this._dl = this._dl || _o&&_o.delay || 0; //delay + this._sT = null; // startTime + this.paused = false; //_paused + this._pST = null; //_pauseStartTime + this._pp = this._pp || _o.perspective; // perspective + this._ppo = this._ppo || _o.perspectiveOrigin; // perspective origin + this._ppp = this._ppp || _o.parentPerspective; // parent perspective + this._pppo = this._pppo || _o.parentPerspectiveOrigin; // parent perspective origin + this._rpr = this._rpr || _o.rpr || false; // internal option to process inline/computed style at start instead of init true/false + this._hex = this._hex || _o.keepHex || false; // option to keep hex for color tweens true/false + this._e = this._e || _o.easing; // _easing + this._cT = this._cT || []; //_chainedTweens + this._sC = this._sC || _o&&_o.start || null; // _on StartCallback + this._sCF = false; //_on StartCallbackFIRED + this._uC = _o&&_o.update || null; // _on UpdateCallback + this._cC = _o&&_o.complete || null; // _on CompleteCallback + this._pC = _o&&_o.pause || null; // _on PauseCallback + this._rC = _o&&_o.play || null; // _on ResumeCallback + this._stC = _o&&_o.stop || null; // _on StopCallback + this.repeat = this._r; // we cache the number of repeats to be able to put it back after all cycles finish + }; + + var w = K.Tween.prototype; + + w.start = function (t) { + this.scrollIn(); + var f = {}; + + K.perspective(this._el,this); // apply the perspective + + if ( this._rpr ) { // on start we reprocess the valuesStart for TO() method + f = this.prS(); + this._vS = {}; + this._vS = K.prP(f,false); + + for ( p in this._vS ) { + if ( p === 'transform' && (p in this._vE) ){ + for ( var sp in this._vS[p]) { + if (!(sp in this._vE[p])) { this._vE[p][sp] = {}; } + for ( var spp in this._vS[p][sp] ) { // 3rd level + if ( this._vS[p][sp][spp].value !== undefined ) { + if (!(spp in this._vE[p][sp])) { this._vE[p][sp][spp] = {}; } + for ( var sppp in this._vS[p][sp][spp]) { // spp = translateX | rotateX | skewX | rotate2d + if ( !(sppp in this._vE[p][sp][spp])) { + this._vE[p][sp][spp][sppp] = this._vS[p][sp][spp][sppp]; // sppp = unit | value + } + } + } + } + if ( 'value' in this._vS[p][sp] && (!('value' in this._vE[p][sp])) ) { // 2nd level + for ( var spp in this._vS[p][sp] ) { // scale + if (!(spp in this._vE[p][sp])) { + this._vE[p][sp][spp] = this._vS[p][sp][spp]; // spp = unit | value + } + } + } + } } } - return true; - }, - process : function ( time ) { - requestAnimationFrame(KUTE.process); - KUTE.update( time ); } + + for ( p in this._vE ) { + this._vSR[p] = this._vS[p]; + } + + // now it's a good time to start + K.add(this); + this.playing = true; + this.paused = false; + this._sCF = false; + this._sT = t || window.performance.now(); + this._sT += this._dl; + if (!_t) K.t(); + return this; }; -} )(); + + //main worker, doing update on tick + w.u = function(t) { + t = t || window.performance.now(); + if (t < this._sT && this.playing && !this.paused) { return true; } -KUTE.Animate = function( object, options ) { - - //element to animate - var el = typeof object === 'object' ? object : document.querySelector(object); - - //get true scroll container and current scroll - var bd = document.body, - htm = document.getElementsByTagName('HTML')[0], - sct = /webkit/i.test(navigator.userAgent) || document.compatMode == 'BackCompat' ? bd : htm, - crs = window.pageYOffset || sct.scrollTop; - - //determine if we're on IE or IE8 - var isIE = document.documentElement.classList.contains('ie'); - var isIE8 = document.documentElement.classList.contains('ie8'); - - //get element current style - var css = el.currentStyle || window.getComputedStyle(el); - - // default values - var ops = { - from : { - opacity : 1, // integer - width : '', // integer/px/% - height : '', // integer/px/% - position : {top:'', left:''}, // integer/% - translate : {x:0, y:0, z:0}, // integer only - rotate : {x:0, y:0, z:0}, // integer only - scale : 1, // integer only - scroll : crs, // integer only - }, - to : { - opacity : '', - width : '', - height : '', - position : {top:'',left:''}, - translate : {x:'', y:'', z:''}, - rotate : {x:'', y:'', z:''}, - scale : '', - scroll : '', - }, - easing : KUTE.Easing.Linear.None, //pe('linear') - delay : 0, - duration : 500, - start : null, // run function when tween starts - finish : null, // run function when tween finishes - special : null // run function while tween runing - }; + if (!this._sCF) { + if (this._sC) { this._sC.call(); } + this._sCF = true; + } - //override the default values with option values - for (var x in options) { - if(typeof(options[x]) === 'object'){ - for (var y in options[x]){ - ops[x][y] = options[x][y]; - } - }else{ - ops[x] = options[x]; - } - } + var e = ( t - this._sT ) / this._dr; //elapsed + e = e > 1 ? 1 : e; + + //render the CSS update + K.r(this,this._e(e)); + + if (this._uC) { this._uC.call(); } - //create shorthand for all properties - var ofo = ops.from.opacity; - var ofw = ops.from.width; - var ofh = ops.from.height; - var oft = ops.from.position.top; - var ofl = ops.from.position.left; - var oftx = ops.from.translate.x; - var ofty = ops.from.translate.y; - var oftz = ops.from.translate.z; - var ofrx = ops.from.rotate.x; - var ofry = ops.from.rotate.y; - var ofrz = ops.from.rotate.z; - var ofs = ops.from.scale; - var ofsc = ops.from.scroll; - - var oto = ops.to.opacity; - var otw = ops.to.width; - var oth = ops.to.height; - var ott = ops.to.position.top; - var otl = ops.to.position.left; - var ottx = ops.to.translate.x; - var otty = ops.to.translate.y; - var ottz = ops.to.translate.z; - var otrx = ops.to.rotate.x; - var otry = ops.to.rotate.y; - var otrz = ops.to.rotate.z; - var ots = ops.to.scale; - var otsc = ops.to.scroll; - - - //process easing - var pes = typeof ops.easing === 'string' ? pe(ops.easing) : ops.easing; - - //from/initial values - var iwi = cv(ofw) ? truD(ofw)[0] : truD( css.width )[0]; // width - var ihe = cv(ofh) ? truD(ofh)[0] : truD( css.height )[0]; // height - - var ito = cv(oft) ? truD(oft)[0] : ''; // move - var ile = cv(ofl) ? truD(ofl)[0] : ''; - - var tr3d,tx,ty,tz,itx,ity,itz; // translate - if ( cv( ottx ) || cv( otty ) || cv( ottz ) ) { - itx = cv(oftx) ? truD(oftx)[0] : 0; - ity = cv(ofty) ? truD(ofty)[0] : 0; - itz = cv(oftz) ? truD(oftz)[0] : 0; - } else { - itx = ''; ity = ''; itz = ''; - } - - var irx = cv(ofrx) ? parseInt(ofrx) :''; //always deg - var iry = cv(ofry) ? parseInt(ofry) :''; - var irz = cv(ofrz) ? parseInt(ofrz) :''; - - var isa = parseFloat(ofs); // scale can be float - var iop = parseFloat(ofo); // opacity - var isc = parseInt(ofsc); // scroll - - - //target values - var wi = cv( otw ) ? truD(otw)[0] : ''; // width - var he = cv( oth ) ? truD(oth)[0] : ''; // height - - var top = cv(ott) ? truD(ott)[0] : ''; // pos top - var le = cv(otl) ? truD(otl)[0] : ''; //pos left - - if ( cv( ottx ) || cv( otty ) || cv( ottz ) ) { // translate 3d - tx = cv( ottx ) ? truD(ottx)[0] : 0; - ty = cv( otty ) ? truD(otty)[0] : 0; - tz = cv( ottz ) ? truD(ottz)[0] : 0; - } else { - tx = ''; ty = ''; tz = ''; - } - - var rx = cv( otrx ) ? parseInt(otrx) : ''; // rotate - var ry = cv( otry ) ? parseInt(otry) : ''; - var rz = cv( otrz ) ? parseInt(otrz) : ''; - - var sa = cv( ots ) ? parseFloat(ots) : ''; // scale values below 1 need to be reformated - var op = cv( oto ) ? parseFloat(oto) : ''; // opacity - var sc = cv( otsc ) ? parseInt(otsc) : ''; // scroll - - //check measurement unit - var wiu = cv( wi ) ? truD(otw)[1] : ''; // width - var heu = cv( he ) ? truD(oth)[1] : ''; // height - - var tou = cv( ott ) ? truD(ott)[1] : ''; // pos top - var leu = cv( otl ) ? truD(otl)[1] : ''; // pos left - - var txu = cv( tx ) ? truD(ottx)[1] : ''; // translate - var tyu = cv( ty ) ? truD(otty)[1] : ''; - var tzu = cv( tz ) ? truD(ottz)[1] : ''; - - var from = { w: iwi, h: ihe, t: ito, l: ile, scale: isa, trX: itx, trY: ity, trZ: itz, roX: irx, roY: iry, roZ: irz, opacity: iop, scroll: isc }; - var target = { w: wi, h: he, t: top, l: le, scale: sa, trX: tx, trY: ty, trZ: tz, roX: rx, roY: ry, roZ: rz, opacity: op, scroll: sc }; - - return new KUTE.Tween( from ) - .to( target, ops.duration ) - .delay( ops.delay ) - .easing( pes ) - .onStart( runStart ) - .onUpdate( - function () { + if (e === 1) { + if (this._r > 0) { + if ( this._r !== Infinity ) { this._r--; } - //translate3d - if ( cv(tx) || cv(ty) || cv(tz) ) { - tr3d = 'translate3d(' + ((this.trX + txu) || 0) + ',' + ( (this.trY + tyu) || 0) + ',' + ( (this.trZ + tzu) || 0) + ')'; - } else { tr3d = ''; } - - //rotate - var roxt = cv(rx) ? ' rotateX(' + this.roX + 'deg)' : ''; - var royt = cv(ry) ? ' rotateY(' + this.roY + 'deg)' : ''; - var rozt = cv(rz) ? ' rotateZ(' + this.roZ + 'deg)' : ''; - - //scale - var sca = cv(sa) ? ' scale(' + this.scale + ')' : ''; + if (this._y) { this.reversed = !this.reversed; this.reverse(); } // handle yoyo + + this._sT = (this._y && !this.reversed) ? t + this._rD : t; //set the right time for delay + return true; + } else { - //do a zoom for IE8 - if (isIE8 && cv(sa)) { - el.style.zoom = this.scale; + if (this._cC) { this._cC.call(); } + + //stop preventing scroll when scroll tween finished + this.scrollOut(); + var i = 0, ctl = this._cT.length; + for (i; i < ctl; i++) { + this._cT[i].start(this._sT + this._dr); } - //sum all transform - var perspective = parseInt(css.perspective)||''; - var transform = sca + tr3d + roxt + royt + rozt; - if ( cv(transform) ) { tr(transform,perspective) } - - - //dimensions width / height - if ( cv(wi) ) { el.style.width = this.w + wiu; } - if ( cv(he) ) { el.style.height = this.h + heu; } - - //position - if ( cv(top) ) { el.style.top = this.t + tou; } - if ( cv(le ) ) { el.style.left = this.l + leu; } - - // scrolling - if ( cv(sc) ) { sct.scrollTop = this.scroll; } - - //opacity - if ( cv(op) ) { el.style.opacity = (this.opacity).toFixed(2); } - - //do a filter opacity for IE8 - if (isIE8 && cv(op)) { - el.style.filter = "alpha(opacity=" + parseInt(100 * this.opacity) + ")" - } - - //run special function onUpdate - if ( ops.special && typeof ops.special === "function") { ops.special(); } + //stop ticking when finished + this.close(); + return false; } - ) - .onComplete( runFinished ) - .start(); - - //callback when tween is finished - function runFinished() { - if ( ops.finish && typeof ops.finish === "function") { - ops.finish(); - } - if ( cv(otsc) ) { - document.body.removeAttribute('data-tweening') - } - } - - //callback when tween just started - function runStart() { - if ( ops.start && typeof ops.start === "function") { - ops.start(); - } - //fix the scrolling being interrupted via mousewheel - if ( cv(otsc) ) { - if ( !document.body.getAttribute('data-tweening') && document.body.getAttribute('data-tweening') !== 'scroll' ) - document.body.setAttribute('data-tweening','scroll'); - } - } - - /* Process values utils - ----------------------------*/ - - //process easing 31 - function pe(e) { - if ( e === 'linear' ) return KUTE.Easing.Linear.None; - if ( e === 'quadraticIn' ) return KUTE.Easing.Quadratic.In; - if ( e === 'quadraticOut' ) return KUTE.Easing.Quadratic.Out; - if ( e === 'quadraticInOut' ) return KUTE.Easing.Quadratic.InOut; - if ( e === 'cubicIn' ) return KUTE.Easing.Cubic.In; - if ( e === 'cubicOut' ) return KUTE.Easing.Cubic.Out; - if ( e === 'cubicInOut' ) return KUTE.Easing.Cubic.InOut; - if ( e === 'quarticIn' ) return KUTE.Easing.Quartic.In; - if ( e === 'quarticOut' ) return KUTE.Easing.Quartic.Out; - if ( e === 'quarticInOut' ) return KUTE.Easing.Quartic.InOut; - if ( e === 'quinticIn' ) return KUTE.Easing.Quintic.In; - if ( e === 'quinticOut' ) return KUTE.Easing.Quintic.Out; - if ( e === 'quinticInOut' ) return KUTE.Easing.Quintic.InOut; - if ( e === 'sinusoidalIn' ) return KUTE.Easing.Sinusoidal.In; - if ( e === 'sinusoidalOut' ) return KUTE.Easing.Sinusoidal.Out; - if ( e === 'sinusoidalInOut' ) return KUTE.Easing.Sinusoidal.InOut; - if ( e === 'exponentialIn' ) return KUTE.Easing.Exponential.In; - if ( e === 'exponentialOut' ) return KUTE.Easing.Exponential.Out; - if ( e === 'exponentialInOut' ) return KUTE.Easing.Exponential.InOut; - if ( e === 'circularIn' ) return KUTE.Easing.Circular.In; - if ( e === 'circularOut' ) return KUTE.Easing.Circular.Out; - if ( e === 'circularInOut' ) return KUTE.Easing.Circular.InOut; - if ( e === 'elasticIn' ) return KUTE.Easing.Elastic.In; - if ( e === 'elasticOut' ) return KUTE.Easing.Elastic.Out; - if ( e === 'elasticInOut' ) return KUTE.Easing.Elastic.InOut; - if ( e === 'backIn' ) return KUTE.Easing.Back.In; - if ( e === 'backOut' ) return KUTE.Easing.Back.Out; - if ( e === 'backInOut' ) return KUTE.Easing.Back.InOut; - if ( e === 'bounceIn' ) return KUTE.Easing.Bounce.In; - if ( e === 'bounceOut' ) return KUTE.Easing.Bounce.Out; - if ( e === 'bounceInOut' ) return KUTE.Easing.Bounce.InOut; - //default - return KUTE.Easing.Exponential.InOut; - } - - // value checker - function cv(v) { - if ( v !== undefined && v !== '' && v !== 'NaN' ) return true; - } - - // get true w/h - function truD(d){ - var v,u; - if (/px/i.test(d)) { - u = 'px'; v = parseInt( d ); - } else if (/%/i.test(d)) { - u = '%'; v = parseInt( d ); - } else { - v = d; u = 'px'; - } - return [v,u]; - } - - // process transform - function tr(p,pp) { - el.style.transform = p; - el.style.msTransform = (cv(pp)?'perspective('+pp+'px) ':'') + p; - el.style.MozTransform = p; - el.style.webkitTransform = p; - } -}; - -KUTE.Tween = function ( object ) { - - var _object = object; - var _valuesStart = {}; - var _valuesEnd = {}; - var _valuesStartRepeat = {}; - var _duration = 700; - var _isPlaying = false; - var _delayTime = 0; - var _startTime = null; - var _easingFunction = KUTE.Easing.Linear.None; - var _onStartCallback = null; - var _onStartCallbackFired = false; - var _onUpdateCallback = null; - var _onCompleteCallback = null; - var _onStopCallback = null; - - // Set all starting values present on the target object - for ( var field in object ) { - _valuesStart[ field ] = parseFloat(object[field], 10); - } - - this.to = function ( properties, duration ) { - - if ( duration !== undefined ) { - _duration = duration; - } - - _valuesEnd = properties; - return this; - }; - - this.start = function ( time ) { - - KUTE.add( this ); - _isPlaying = true; - _onStartCallbackFired = false; - _startTime = time !== undefined ? time : window.performance.now(); - _startTime += _delayTime; - - for ( var property in _valuesEnd ) { - // check if an Array was provided as property value - if ( _valuesEnd[ property ] instanceof Array ) { - if ( _valuesEnd[ property ].length === 0 ) { - continue; - } - - // create a local copy of the Array with the start value at the front - _valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] ); - } - - if( ( _valuesEnd[ property ] instanceof Array ) === false ) { - _valuesEnd[ property ] *= 1.0; // Ensures we're using numbers, not strings - } - - _valuesStart[ property ] = _object[ property ]; - - if( ( _valuesStart[ property ] instanceof Array ) === false ) { - _valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings - } - } - return this; - }; - - this.stop = function () { - if ( !_isPlaying ) { - return this; - } - - KUTE.remove( this ); - _isPlaying = false; - - if ( _onStopCallback !== null ) { - _onStopCallback.call( _object ); - } - - return this; - - }; - - this.delay = function ( amount ) { - _delayTime = amount; - return this; - }; - - this.easing = function ( easing ) { - _easingFunction = easing; - return this; - }; - - this.onStart = function ( callback ) { - _onStartCallback = callback; - return this; - }; - - this.onUpdate = function ( callback ) { - _onUpdateCallback = callback; - return this; - }; - - this.onComplete = function ( callback ) { - _onCompleteCallback = callback; - return this; - }; - - this.onStop = function ( callback ) { - _onStopCallback = callback; - return this; - }; - - this.update = function ( time ) { - var property; - - if ( time < _startTime ) { - return true; - } - - if ( _onStartCallbackFired === false ) { - if ( _onStartCallback !== null ) { - _onStartCallback.call( _object ); - } - _onStartCallbackFired = true; - } - - var elapsed = ( time - _startTime ) / _duration; - elapsed = elapsed > 1 ? 1 : elapsed; - var value = _easingFunction( elapsed ); - - for ( property in _valuesEnd ) { - - var start = _valuesStart[ property ] || 0; - var end = _valuesEnd[ property ]; - - // Parses relative end values with start as base (e.g.: +10, -3) - if ( typeof(end) === "string" ) { - end = start + parseFloat(end, 10); - } - - // protect against non numeric properties. - if ( typeof(end) === "number" ) { - _object[ property ] = start + ( end - start ) * value; - } - } - - if ( _onUpdateCallback !== null ) { - _onUpdateCallback.call( _object, value ); - } - - if ( elapsed == 1 ) { - - if ( _onCompleteCallback !== null ) { - _onCompleteCallback.call( _object ); - } - return false; } return true; }; -}; + + w.stop = function () { + if (!this.paused && this.playing) { + K.remove(this); + this.playing = false; + this.paused = false; + this.scrollOut(); + + if (this._stC !== null) { + this._stC.call(); + } + this.stopChainedTweens(); + this.close(); + } + return this; + }; -KUTE.process(0); - -KUTE.Easing = { - Linear: { - None: function ( k ) { - return k; - } - }, - Quadratic: { - In: function ( k ) { - return k * k; - }, - - Out: function ( k ) { - return k * ( 2 - k ); - }, - - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k; - return - 0.5 * ( --k * ( k - 2 ) - 1 ); - } - }, - Cubic: { - In: function ( k ) { - return k * k * k; - }, - Out: function ( k ) { - return --k * k * k + 1; - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k + 2 ); - } - }, - Quartic: { - In: function ( k ) { - return k * k * k * k; - }, - Out: function ( k ) { - return 1 - ( --k * k * k * k ); - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k; - return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 ); - } - }, - Quintic: { - In: function ( k ) { - return k * k * k * k * k; - }, - - Out: function ( k ) { - return --k * k * k * k * k + 1; - }, - - InOut: function ( k ) { - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 ); - } - }, - Sinusoidal: { - In: function ( k ) { - return 1 - Math.cos( k * Math.PI / 2 ); - }, - Out: function ( k ) { - return Math.sin( k * Math.PI / 2 ); - }, - InOut: function ( k ) { - return 0.5 * ( 1 - Math.cos( Math.PI * k ) ); - } - }, - - Exponential: { - In: function ( k ) { - return k === 0 ? 0 : Math.pow( 1024, k - 1 ); - }, - Out: function ( k ) { - return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k ); - }, - InOut: function ( k ) { - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 ); - return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 ); - } - }, - Circular: { - In: function ( k ) { - return 1 - Math.sqrt( 1 - k * k ); - }, - Out: function ( k ) { - return Math.sqrt( 1 - ( --k * k ) ); - }, - InOut: function ( k ) { - if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1); - return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1); - } - }, - Elastic: { - In: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); - }, - Out: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 ); - }, - InOut: function ( k ) { - var s, a = 0.1, p = 0.4; - if ( k === 0 ) return 0; - if ( k === 1 ) return 1; - if ( !a || a < 1 ) { a = 1; s = p / 4; } - else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); - if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); - return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1; - } - }, - Back: { - In: function ( k ) { - var s = 1.70158; - return k * k * ( ( s + 1 ) * k - s ); - }, - Out: function ( k ) { - var s = 1.70158; - return --k * k * ( ( s + 1 ) * k + s ) + 1; - }, - InOut: function ( k ) { - var s = 1.70158 * 1.525; - if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) ); - return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 ); - } - }, - Bounce: { - In: function ( k ) { - return 1 - KUTE.Easing.Bounce.Out( 1 - k ); - }, - Out: function ( k ) { - if ( k < ( 1 / 2.75 ) ) { - return 7.5625 * k * k; - } else if ( k < ( 2 / 2.75 ) ) { - return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; - } else if ( k < ( 2.5 / 2.75 ) ) { - return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; - } else { - return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + w.pause = function() { + if (!this.paused && this.playing) { + K.remove(this); + this.paused = true; + this._pST = window.performance.now(); + if (this._pC !== null) { + this._pC.call(); } - }, - InOut: function ( k ) { - if ( k < 0.5 ) return KUTE.Easing.Bounce.In( k * 2 ) * 0.5; - return KUTE.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5; } - } -}; + return this; + }; + w.play = function () { + if (this.paused && this.playing) { + this.paused = false; + if (this._rC !== null) { + this._rC.call(); + } + this._sT += window.performance.now() - this._pST; + K.add(this); + if (!_t) K.t(); // restart ticking if stopped + } + return this; + }; -// prevent mousewheel or touch events while tweening scroll -document.addEventListener('mousewheel', preventScroll, false); -document.addEventListener('touchstart', preventScroll, false); -function preventScroll(e){ - var data = document.body.getAttribute('data-tweening'); - if ( data && data === 'scroll' ) { - e.preventDefault(); + w.resume = function () { this.play(); return this; }; + + w.reverse = function () { + if (this._y) { + for (var p in this._vE) { + var tmp = this._vSR[p]; + this._vSR[p] = this._vE[p]; + this._vE[p] = tmp; + this._vS[p] = this._vSR[p]; + } + } + return this; + }; + + w.chain = function () { this._cT = arguments; return this; }; + + w.stopChainedTweens = function () { + var i = 0, ctl =this._cT.length; + for (i; i < ctl; i++) { + this._cT[i].stop(); + } + }; + + w.scrollOut = function(){ //prevent scroll when tweening scroll + if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { + this.removeListeners(); + document.body.removeAttribute('data-tweening'); + } + }; + + w.scrollIn = function(){ + if ( 'scroll' in this._vE || 'scrollTop' in this._vE ) { + if (!document.body.getAttribute('data-tweening') ) { + document.body.setAttribute('data-tweening', 'scroll'); + this.addListeners(); + } + } + }; + + w.addListeners = function () { + document.addEventListener(_ev, K.preventScroll, false); + }; + + w.removeListeners = function () { + document.removeEventListener(_ev, K.preventScroll, false); + }; + + w.prS = function () { //prepare valuesStart for .to() method + var f = {}, el = this._el, to = this._vS, cs = this.gIS('transform'), deg = ['rotate','skew'], ax = ['X','Y','Z']; + + for (var p in to){ + if ( _tf.indexOf(p) !== -1 ) { + var r2d = (p === 'rotate' || p === 'translate' || p === 'scale'); + if ( /translate/.test(p) && p !== 'translate' ) { + f['translate3d'] = cs['translate3d'] || _d[p]; + } else if ( r2d ) { // 2d transforms + f[p] = cs[p] || _d[p]; + } else if ( !r2d && /rotate|skew/.test(p) ) { // all angles + for (var d=0; d<2; d++) { + for (var a = 0; a<3; a++) { + var s = deg[d]+ax[a]; + if (_tf.indexOf(s) !== -1 && (s in to) ) { f[s] = cs[s] || _d[s]; } + } + } + } + } else { + if ( _sc.indexOf(p) === -1 ) { + if (p === 'opacity' && _isIE8 ) { // handle IE8 opacity + var co = this.gCS('filter'); + f['opacity'] = typeof co === 'number' ? co : _d['opacity']; + } else { + f[p] = this.gCS(p) || _d[p]; + } + } else { + f[p] = (el === null || el === undefined) ? (window.pageYOffset || _sct.scrollTop) : el.scrollTop; + } + } + } + for ( var p in cs ){ // also add to _vS values from previous tweens + if ( _tf.indexOf(p) !== -1 && (!( p in to )) ) { + f[p] = cs[p] || _d[p]; + } + } + return f; + }; + + w.gIS = function(p) { // gIS = get transform style for element from cssText for .to() method, the sp is for transform property + if (!this._el) return; // if the scroll applies to `window` it returns as it has no styling + var l = this._el, cst = l.style.cssText,//the cssText + trsf = {}; //the transform object + // if we have any inline style in the cssText attribute, usually it has higher priority + var css = cst.replace(/\s/g,'').split(';'), i=0, csl = css.length; + for ( i; i 0) { self._r = self.repeat; } + if (self._y && self.reversed===true) { self.reverse(); self.reversed = false; } + self.playing = false; + },100) + }; + + // process properties + K.prP = function (t, e) { // process tween properties for .fromTo() method + var _st = {}, + tr = e === true ? _tfE : _tfS, + tl = e === true ? _tlE : _tlS, + rt = e === true ? _rtE : _rtS; + + tl = {}; tr = {}; + + for (var x in t) { + if (_tf.indexOf(x) !== -1) { + + if (x !== 'translate' && /translate/.test(x)) { //process translate3d + var ta = ['X', 'Y', 'Z'], f = 0; //coordinates // translate[x] = pp(x, t[x]); + + for (f; f < 3; f++) { + var a = ta[f]; + if ( /3d/.test(x) ) { + tl['translate' + a] = K.pp('translate' + a, t[x][f]); + } else { + tl['translate' + a] = ('translate' + a in t) ? K.pp('translate' + a, t['translate' + a]) : { value: 0, unit: 'px' }; + } + } + + tr['translate'] = tl; + } else if ( x !== 'rotate' && /rotate|skew/.test(x)) { //process rotation + var ap = /rotate/.test(x) ? 'rotate' : 'skew', ra = ['X', 'Y', 'Z'], r = 0, + _rt = {}, _sk = {}, rt = ap === 'rotate' ? _rt : _sk; + for (r; r < 3; r++) { + var v = ra[r]; + if ( t[ap+v] !== undefined && x !== 'skewZ' ) { + rt[ap+v] = K.pp(ap + v, t[ap+v]); + } + } + + tr[ap] = rt; + } else if ( x === 'translate' || x === 'rotate' || x === 'scale' ) { //process 2d translation / rotation + tr[x] = K.pp(x, t[x]); + } + + _st['transform'] = tr; + + } else if (_tf.indexOf(x) === -1) { + _st[x] = K.pp(x, t[x]); + } + } + return _st; + }; + + // _cls _sc _op _bm _tp _bg _tf + K.pp = function(p, v) {//process single property + if (_tf.indexOf(p) !== -1) { + var t = p.replace(/X|Y|Z/, ''), tv; + if (p === 'translate3d') { + tv = v.split(','); + return { + translateX : { value: K.truD(tv[0]).v, unit: K.truD(tv[0]).u }, + translateY : { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u }, + translateZ : { value: K.truD(tv[2]).v, unit: K.truD(tv[2]).u } + }; + } else if (p !== 'translate' && t === 'translate') { + return { value: K.truD(v).v, unit: (K.truD(v).u||'px') }; + } else if (p !== 'rotate' && (t === 'skew' || t === 'rotate') && p !== 'skewZ' ) { + return { value: K.truD(v).v, unit: (K.truD(v,p).u||'deg') }; + } else if (p === 'translate') { + tv = typeof v === 'string' ? v.split(',') : v; var t2d = {}; + if (tv instanceof Array) { + t2d.x = { value: K.truD(tv[0]).v, unit: K.truD(tv[0]).u }, + t2d.y = { value: K.truD(tv[1]).v, unit: K.truD(tv[1]).u } + } else { + t2d.x = { value: K.truD(tv).v, unit: K.truD(tv).u }, + t2d.y = { value: 0, unit: 'px' } + } + return t2d; + } else if (p === 'rotate') { + var r2d = {}; + r2d.z = { value: parseInt(v, 10), unit: (K.truD(v,p).u||'deg') }; + return r2d; + } else if (p === 'scale') { + return { value: parseFloat(v, 10) }; + } + } + if (_tp.indexOf(p) !== -1 || _bm.indexOf(p) !== -1) { + return { value: K.truD(v).v, unit: K.truD(v).u }; + } + if (_op.indexOf(p) !== -1) { + return { value: parseFloat(v, 10) }; + } + if (_sc.indexOf(p) !== -1) { + return { value: parseFloat(v, 10) }; + } + if (_clp.indexOf(p) !== -1) { + if ( v instanceof Array ){ + return [ K.truD(v[0]), K.truD(v[1]), K.truD(v[2]), K.truD(v[3]) ]; + } else { + var ci; + if ( /rect/.test(v) ) { + ci = v.replace(/rect|\(|\)/g,'').split(/\s|\,/); + } else if ( /auto|none|initial/.test(v) ){ + ci = _d[p]; + } + return [ K.truD(ci[0]), K.truD(ci[1]), K.truD(ci[2]), K.truD(ci[3]) ]; + } + } + if (_cls.indexOf(p) !== -1) { + return { value: K.truC(v) }; + } + if (_bg.indexOf(p) !== -1) { + if ( v instanceof Array ){ + return { x: K.truD(v[0])||{ v: 50, u: '%' }, y: K.truD(v[1])||{ v: 50, u: '%' } }; + } else { + var posxy = v.replace(/top|left/g,0).replace(/right|bottom/g,100).replace(/center|middle/,50).split(/\s|\,/g), + xp = K.truD(posxy[0]), yp = K.truD(posxy[1]); + return { x: xp, y: yp }; + } + } + if (_rd.indexOf(p) !== -1) { + var rad = K.truD(v); + return { value: rad.v, unit: rad.u }; + } + }; + + K.truD = function (d,p) { //true dimension returns { v = value, u = unit } + var x = parseInt(d) || 0, mu = ['px','%','deg','rad','em','rem','vh','vw'], l = mu.length, + y = getU(); + function getU() { + var u,i=0; + for (i;i