10 |
11 |
12 |
13 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/morphr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goessner/morphr/72bb7cae3ea7e201a9010584d477c8e6afd7545f/morphr.gif
--------------------------------------------------------------------------------
/morphr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Morphr (c) 2016 Stefan Goessner
3 | * @license
4 | * MIT License
5 | */
6 |
7 | "use strict";
8 |
9 | /**
10 | * `Morphr` is a tiny class for simultaneously morphing numerical object values in a given time interval.
11 | * Use case is most often parameter animation of plain javascript objects. So it works excellently with
12 | * canvas. `Morphr` depends on `requestAnimationFrame`.
13 | *
14 | * Do not use `new Morphr()`, call `Morphr.create()` instead for creating instances.
15 | * @class
16 | */
17 | var Morphr = {
18 | /**
19 | * Create a `Morphr` instance by start time, duration and timing function for morphing. A couple of predefined
20 | * timing functions are available [s. VDI2143]:
21 | * * `linear`
22 | * * `quadratic`
23 | * * `sinoid`
24 | * * `poly5`
25 | * @returns {object} `Morphr` instance.
26 | * @param {float} [dt=2] Duration in [s].
27 | * @param {float} [t0=0] Start time in [s] relative to first time call of `start` method.
28 | * @param {function|string} [fn="linear"] Timing function as `function` object or name of predefined function.
29 | */
30 | create: function() { var o = Object.create(this.prototype); o.constructor.apply(o,arguments); return o; },
31 | prototype: {
32 | constructor: function(dt,t0,fn) {
33 | this.dt = (dt || 2)*1000; // use ms ...
34 | this.t0 = (t0 || 0)*1000; // use ms ...
35 | this.fn = typeof fn === "string" && Morphr[fn] ? Morphr[fn]
36 | : typeof fn === "function" ? fn : Morphr.linear;
37 | this.handlers = [];
38 | this.animateHdl = Morphr.prototype.animate.bind(this);
39 | },
40 | /**
41 | * Register morphing handler function.
42 | * @returns {object} this.
43 | * @param {function} hdl Callback function `hdl(q){}`, where `q` is the - via `fn` - normalized time or the boolean value `false` to reset for a new start.
44 | */
45 | register: function(hdl) {
46 | if (hdl) {
47 | var idx = this.handlers.indexOf(hdl);
48 | if (idx === -1) // not registered, so add ..
49 | this.handlers.push(hdl);
50 | else // already registered, so remove ..
51 | this.handlers.splice(idx,1);
52 | }
53 | return this;
54 | },
55 | /**
56 | * Start morphing process.
57 | * @returns {object} this.
58 | */
59 | start: function() {
60 | this.tbeg = false;
61 | for (var i=this.handlers.length-1; i>=0; --i) // reset handlers ...
62 | this.handlers[i](false);
63 | this.animate(0);
64 | return this;
65 | },
66 | /**
67 | * @private
68 | */
69 | animate: function animate(time) {
70 | var t = 0, tbeg = this.tbeg || (this.tbeg = time) || false;
71 | if (tbeg && (t = time - tbeg - this.t0) >= 0) {
72 | var q = this.fn(t/this.dt); // get normalized value by timing function.
73 | for (var i=this.handlers.length-1; i>=0; --i) // migrate to for (.. of ..) in near future ..
74 | this.handlers[i](q);
75 | }
76 | if (t <= this.dt)
77 | requestAnimationFrame(this.animateHdl);
78 | }
79 | },
80 | // some simple motion laws (timing functions) from cam design (VDI 2143) ... all in interval [0,1]
81 | // penner functions
82 | linear: function(q) { return q; },
83 | inQuad: function (q) { return q*q; },
84 | outQuad: function (q) { return 1 - (--q)*q; },
85 | inOutQuad: function (q) { return q < 0.5 ? 2*q*q : 1 - 2*(--q)*q; },
86 | inCubic: function (q) { return q*q*q; },
87 | outCubic: function (q) { return 1 + (--q)*q*q; },
88 | inOutCubic: function (q) { return q < 0.5 ? 4*q*q*q : 1 + 4*(--q)*q*q; },
89 | inQuart: function (q) { return q*q*q*q; },
90 | outQuart: function (q) { return 1 - (--q)*q*q*q; },
91 | inOutQuart: function (q) { return q < 0.5 ? 8*q*q*q*q : 1 - 8*(--q)*q*q*q; },
92 | inQuint: function (q) { return q*q*q*q*q; },
93 | outQuint: function (q) { return 1 + (--q)*q*q*q*q; },
94 | inOutQuint: function (q) { return q < 0.5 ? 16*q*q*q*q*q : 1 - 16*(--q)*q*q*q*q; },
95 | easeInQuart: function (t) { return t*t*t*t },
96 | easeOutQuart: function (t) { return 1-(--t)*t*t*t },
97 | easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
98 | easeInQuint: function (t) { return t*t*t*t*t },
99 | easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
100 | easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t },
101 |
102 |
103 | quadratic: function(z) { return z <= 0.5 ? 2*z*z : -2*z*z + 4*z - 1; },
104 | sinoid: function(z) { return z - Math.sin(2*Math.PI*z)/2/Math.PI; },
105 | poly5: function(z) { return 10*z*z*z - 15*z*z*z*z +6*z*z*z*z*z; }
106 | }
107 |
108 | // see http://greweb.me/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/
109 |
--------------------------------------------------------------------------------
/morphr.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Morphr (c) 2016 Stefan Goessner
3 | * @license
4 | * MIT License
5 | */
6 | "use strict";var Morphr={create:function(){var o=Object.create(this.prototype);o.constructor.apply(o,arguments);return o},prototype:{constructor:function(dt,t0,fn){this.dt=(dt||2)*1e3;this.t0=(t0||0)*1e3;this.fn=typeof fn==="string"&&Morphr[fn]?Morphr[fn]:typeof fn==="function"?fn:Morphr.linear;this.handlers=[];this.animateHdl=Morphr.prototype.animate.bind(this)},register:function(hdl){if(hdl){var idx=this.handlers.indexOf(hdl);if(idx===-1)this.handlers.push(hdl);else this.handlers.splice(idx,1)}return this},start:function(){this.tbeg=false;for(var i=this.handlers.length-1;i>=0;--i)this.handlers[i](false);this.animate(0);return this},animate:function animate(time){var t=0,tbeg=this.tbeg||(this.tbeg=time)||false;if(tbeg&&(t=time-tbeg-this.t0)>=0){var q=this.fn(t/this.dt);for(var i=this.handlers.length-1;i>=0;--i)this.handlers[i](q)}if(t<=this.dt)requestAnimationFrame(this.animateHdl)}},linear:function(q){return q},inQuad:function(q){return q*q},outQuad:function(q){return 1- --q*q},inOutQuad:function(q){return q<.5?2*q*q:1-2*--q*q},inCubic:function(q){return q*q*q},outCubic:function(q){return 1+--q*q*q},inOutCubic:function(q){return q<.5?4*q*q*q:1+4*--q*q*q},inQuart:function(q){return q*q*q*q},outQuart:function(q){return 1- --q*q*q*q},inOutQuart:function(q){return q<.5?8*q*q*q*q:1-8*--q*q*q*q},inQuint:function(q){return q*q*q*q*q},outQuint:function(q){return 1+--q*q*q*q*q},inOutQuint:function(q){return q<.5?16*q*q*q*q*q:1-16*--q*q*q*q*q},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return 1- --t*t*t*t},easeInOutQuart:function(t){return t<.5?8*t*t*t*t:1-8*--t*t*t*t},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return 1+--t*t*t*t*t},easeInOutQuint:function(t){return t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t},quadratic:function(z){return z<=.5?2*z*z:-2*z*z+4*z-1},sinoid:function(z){return z-Math.sin(2*Math.PI*z)/2/Math.PI},poly5:function(z){return 10*z*z*z-15*z*z*z*z+6*z*z*z*z*z}};
--------------------------------------------------------------------------------
/morphr2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goessner/morphr/72bb7cae3ea7e201a9010584d477c8e6afd7545f/morphr2.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "morphr",
3 | "version": "0.7.9",
4 | "description": "Morphr - lightweight morphing numerical object values in a given time interval",
5 | "keywords": [
6 | "morphing",
7 | "animation",
8 | "javascript",
9 | "transition",
10 | "canvas"
11 | ],
12 | "main": "morphr.js",
13 | "scripts": {
14 | "build": "npm run minify && npm run jsdoc && npm run cpsamp",
15 | "jsdoc": "jsdoc2md ./morphr.js > ./api.md",
16 | "minify": "uglifyjs --comments -o ./morphr.min.js ./morphr.js",
17 | "cpsamp": "copyfiles -f ./examples/*.html ../goessner.github.io/morphr/examples"
18 | },
19 | "author": "Stefan Goessner ",
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/goessner/morphr.git"
23 | },
24 | "license": "MIT",
25 | "devDependencies": {
26 | "jsdoc-to-markdown": "^1.3.2",
27 | "uglifyjs": "^2.4.10"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/goessner/g2/license.txt)
2 | [](https://www.npmjs.com/package/morphr)
3 |
4 | # Morphr
5 |
6 | Morphr is a tiny and lightweight javascript class for morphing numerical values of
7 | arbitrary, mostly plain javascript objects in a given time interval `dt` along a given range `dval`.
8 | Most often you will want to use it for animation. So it works excellently in combination with Html canvas.
9 |
10 | ## Example
11 | 
12 |
13 | (animated gif)
14 | see [example](https://goessner.github.io/morphr/examples/simple.html)
15 |
16 | ```html
17 |
Morphr Example
18 |
19 |
20 |
21 |
42 | ```
43 | Sequential morphing is easily achieved via multiple Morphr objects. DOM element attributes are morphable as well.
44 |
45 | see [sequential](https://goessner.github.io/morphr/examples/sequential.html)
46 |
47 | Here is a more complex canvas based [Crank-Rocker animation](https://goessner.github.io/morphr/examples/complex.html) using
48 | a [g2](https://github.com/goessner/g2) command queue for vector graphics.
49 |
50 | Maybe you want to learn a bit more about [Crank-Rockers](https://github.com/goessner/crocker).
51 |
52 | ## GitCDN
53 | Use the link [https://gitcdn.xyz/repo/goessner/g2/master/morphr.min.js](https://gitcdn.xyz/repo/goessner/morphr/master/morphr.min.js)
54 | for getting the latest commit as a raw file.
55 |
56 | In HTML use ...
57 | ```html
58 |
59 | ```
60 |
61 | ## API Reference
62 |
63 | `Morphr` is a tiny class for simultaneously morphing numerical object values in a given time interval.
64 | Use case is most often parameter animation of plain javascript objects. So it works excellently with
65 | canvas. `Morphr` depends on `requestAnimationFrame`.
66 |
67 | Do not use `new Morphr()`, call `Morphr.create()` instead for creating instances.
68 |
69 | * [Morphr](#Morphr)
70 | * _static_
71 | * [.create([dt], [t0], [fn])](#Morphr.create) ⇒ object
72 | * _instance_
73 | * [.register(hdl)](#Morphr+register) ⇒ object
74 | * [.start()](#Morphr+start) ⇒ object
75 |
76 |
77 | ### Morphr.create([dt], [t0], [fn]) ⇒ object
78 | Create a `Morphr` instance by start time, duration and timing function for morphing. A couple of predefined
79 | timing functions are available [s. VDI2143]:
80 | * `linear`
81 | * `quadratic`
82 | * `sinoid`
83 | * `poly5`
84 |
85 | **Kind**: static method of [Morphr](#Morphr)
86 | **Returns**: object - `Morphr` instance.
87 |
88 | | Param | Type | Default | Description |
89 | | --- | --- | --- | --- |
90 | | [dt] | float | 2 | Duration in [s]. |
91 | | [t0] | float | 0 | Start time in [s] relative to first time call of `start` method. |
92 | | [fn] | function | string | "linear" | Timing function as `function` object or name of predefined function. |
93 |
94 |
95 | ### morphr.register(hdl) ⇒ object
96 | Register morphing handler function.
97 |
98 | **Kind**: instance method of [Morphr](#Morphr)
99 | **Returns**: object - this.
100 |
101 | | Param | Type | Description |
102 | | --- | --- | --- |
103 | | hdl | function | Callback function `hdl(q){}`, where `q` is the - via `fn` - normalized time or the boolean value `false` to reset for a new start. |
104 |
105 |
106 | ### morphr.start() ⇒ object
107 | Start morphing process.
108 |
109 | **Kind**: instance method of [Morphr](#Morphr)
110 | **Returns**: object - this.
111 |
112 |
113 | #Change Log
114 |
115 | All notable changes to this project will be documented here. This project adheres to Semantic Versioning.
116 |
117 | ## 0.7.0 - 2016-03-27
118 |
119 | ### First Commit to Github
120 |
--------------------------------------------------------------------------------