├── .npmignore
├── entry.js
├── .gitignore
├── package.json
├── LICENSE
├── .github
└── workflows
│ └── npmpublish.yml
├── webpack.config.js
├── readme.md
├── docs
└── index.html
├── dist
├── kinet.min.js
└── kinet.js
└── src
└── index.js
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | entry.js
3 | webpack.config.js
4 | .idea
5 | index.html
6 | docs
--------------------------------------------------------------------------------
/entry.js:
--------------------------------------------------------------------------------
1 | // this is here for webpack to expose Kinet as window.Kinet
2 | import Kinet from './src/index.js'
3 | module.exports = Kinet
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.DS_Store
3 | !.gitignore
4 | !.htaccess
5 | !web.config
6 | node_modules
7 | bower_components
8 | Thumbs.db
9 | wiki-common
10 | wiki-images files
11 | wiki-wishlist
12 | *.sublime-project
13 | *.sublime-workspace
14 | .editorconfig
15 | .idea
16 | lib
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kinet",
3 | "version": "2.2.1",
4 | "description": "Animate stuff with kinetic force.",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "compile": "babel --presets es2015,stage-0 -d lib/ src/",
9 | "build": "webpack-cli",
10 | "prepublish": "npm run compile && npm run build"
11 | },
12 | "author": "Georgy Marchuk",
13 | "license": "MIT",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/gmrchk/kinet.git"
17 | },
18 | "keywords": [
19 | "kinetic",
20 | "animation"
21 | ],
22 | "dependencies": {},
23 | "devDependencies": {
24 | "babel-cli": "^6.26.0",
25 | "babel-loader": "^7.1.4",
26 | "babel-preset-es2015": "^6.24.1",
27 | "babel-preset-stage-0": "^6.24.1",
28 | "uglifyjs-webpack-plugin": "^1.2.5",
29 | "webpack": "^4.8.3",
30 | "webpack-cli": "^2.1.3"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Georgy Marchuk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.github/workflows/npmpublish.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 | push:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v1
16 | - uses: actions/setup-node@v1
17 | with:
18 | node-version: 12
19 | - run: npm ci
20 | - run: npm test
21 |
22 | publish-npm:
23 | needs: build
24 | runs-on: ubuntu-latest
25 | steps:
26 | - uses: actions/checkout@v1
27 | - uses: actions/setup-node@v1
28 | with:
29 | node-version: 12
30 | registry-url: https://registry.npmjs.org/
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34 |
35 | publish-gpr:
36 | needs: build
37 | runs-on: ubuntu-latest
38 | steps:
39 | - uses: actions/checkout@v1
40 | - uses: actions/setup-node@v1
41 | with:
42 | node-version: 12
43 | registry-url: https://npm.pkg.github.com/
44 | - run: npm publish
45 | env:
46 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
47 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
3 |
4 | const baseConfig = {
5 | mode: "production",
6 | module: {
7 | rules: [
8 | {
9 | test: /\.js$/,
10 | loader: 'babel-loader',
11 | exclude: /node_modules/,
12 | options: {
13 | presets: ['es2015', 'stage-0'],
14 | }
15 | }
16 | ]
17 | },
18 | optimization: {
19 | minimizer: [
20 | // we specify a custom UglifyJsPlugin here to get source maps in production
21 | new UglifyJsPlugin({
22 | uglifyOptions: {
23 | compress: false,
24 | ecma: 6,
25 | mangle: true
26 | },
27 | include: /\.min\.js$/
28 | })
29 | ]
30 | }
31 | }
32 |
33 | const config = Object.assign({}, baseConfig, {
34 | entry: {
35 | "kinet": "./entry.js",
36 | "kinet.min": "./entry.js",
37 | },
38 | output: {
39 | path: __dirname + "/dist/",
40 | library: "Kinet",
41 | libraryTarget: "umd",
42 | filename: "[name].js",
43 | },
44 | })
45 |
46 | module.exports = config
47 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Kinet
2 | Kind of a most lightweight animation library of all. Kinet lets you animate with that spring effect so you can use the values wherever you need to.
3 |
4 | ## Installation
5 | Include Kinet with scripts tag
6 |
7 | ```html
8 |
9 | ```
10 | or with *npm* and *import*
11 | ```shell
12 | npm install kinet --save
13 | ```
14 | ```javascript
15 | // import needed modules from npm
16 | import Kinet from 'kinet';
17 | ```
18 |
19 | ## Options
20 | Kinet accepts several options defined as follows.
21 | ```javascript
22 | var options = { option: "value" }
23 | var kinet = new Kinet(options);
24 | ```
25 |
26 | ### friction
27 | Recommended value 0-1. Default value is `0.3`.
28 |
29 | ### acceleration
30 | Recommended value 0-1. Default value is `0.04`.
31 |
32 | ### initialValue
33 | Sets the initial value of `current` and `target` variables in animated instances.
34 |
35 | ### names
36 | Array of names (strings). Kinet creates animated instance for each name. Defaults to single `x` value in array.
37 |
38 | ### test
39 | Function testing whether the animation has finished. Function gets and animated instance as an argument.
40 | When test function returns false for all animated instances, Kinet stops the animation and sets values to target values.
41 |
42 | ```javascript
43 | // default value
44 | test: function (instance) {
45 | return Math.abs(instance.current - instance.target) > 0.1;
46 | }
47 | ```
48 |
49 | ## Methods
50 | ```javascript
51 | var kinet = new Kinet({name: ["x", "y"]});
52 | ```
53 |
54 | ### set
55 | Sets value of current and target of animated instance to required value without animating.
56 | ```javascript
57 | var kinet = new Kinet();
58 | kinet.set("x", 10); // sets to number 10
59 | ```
60 |
61 | ### animate
62 | Animates value of current variable of animated instance to target value without animating.
63 | ```javascript
64 | var kinet = new Kinet();
65 | kinet.animate("x", 10); // animates to number 10
66 | ```
67 |
68 | ### on
69 | Sets handler for event. Available events are `start` (called at start of animation), `end` (called at the end of animation) and `tick` (called for every tick of animation).
70 | Tick is called with `requestAnimationFrame` as the `current` value progresses to `target` value.
71 | ```javascript
72 | // init
73 | var kinet = new Kinet();
74 |
75 | // set handler
76 | kinet.on('tick', function () {
77 | // do something on every animation tick
78 | });
79 | ```
80 |
81 |
82 | ### off
83 | Removes handler.
84 | ```javascript
85 | kinet.off('tick', handler); // removes single handler
86 | kinet.off('tick'); // removes all handlers for 'tick' event
87 | kinet.off(); // removes all handlers
88 | ```
89 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Kinet
9 |
63 |
64 |
65 |
66 |
73 |
74 |
75 |
76 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/dist/kinet.min.js:
--------------------------------------------------------------------------------
1 | (function t(e,n){if(typeof exports==="object"&&typeof module==="object")module.exports=n();else if(typeof define==="function"&&define.amd)define([],n);else if(typeof exports==="object")exports["Kinet"]=n();else e["Kinet"]=n()})(window,function(){return function(t){var e={};function n(i){if(e[i]){return e[i].exports}var r=e[i]={i,l:false,exports:{}};t[i].call(r.exports,r,r.exports,n);r.l=true;return r.exports}n.m=t;n.c=e;n.d=function(t,e,i){if(!n.o(t,e)){Object.defineProperty(t,e,{enumerable:true,get:i})}};n.r=function(t){if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(t,"__esModule",{value:true})};n.t=function(t,e){if(e&1)t=n(t);if(e&8)return t;if(e&4&&typeof t==="object"&&t&&t.__esModule)return t;var i=Object.create(null);n.r(i);Object.defineProperty(i,"default",{enumerable:true,value:t});if(e&2&&typeof t!="string")for(var r in t)n.d(i,r,function(e){return t[e]}.bind(null,r));return i};n.n=function(t){var e=t&&t.__esModule?function e(){return t["default"]}:function e(){return t};n.d(e,"a",e);return e};n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};n.p="";return n(n.s=0)}([function(t,e,n){"use strict";var i=n(1);var r=s(i);function s(t){return t&&t.__esModule?t:{default:t}}t.exports=r.default},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:true});var i=Object.assign||function(t){for(var e=1;e.1}};this._options=i({},r,e);if(e&&e.friction){this._options.friction=1-e.friction}this._instances={};this._options.names.forEach(function(t){n._instances[t]=new o(n._options.initialValue,n._options.acceleration,n._options.friction)});this._raf=null}r(t,[{key:"set",value:function t(e,n){var i=this;if(n==null){console.warn("Define a value.");return}if(this._instances[e]==null){console.warn('Instance "'+e+"\" doesn't exist.");return}this._instances[e].current=n;this._instances[e].target=n;if(!this._raf){this._handlers["set"].forEach(function(t){return t(i._instances)});this._handlers["tick"].forEach(function(t){return t(i._instances)})}}},{key:"animate",value:function t(e,n){var i=this;if(n==null){console.warn("Define a value.");return}if(this._instances[e]==null){console.warn("Instance "+e+" doesn't exist.");return}if(this._instances[e].target!==n){this._instances[e].target=n;if(!this._raf){this._handlers["start"].forEach(function(t){return t(i._instances,i._instances)});this._animateValues()}return n}return false}},{key:"_animateValues",value:function t(){var e=this;var n=true;Object.keys(this._instances).forEach(function(t){e._instances[t].update();if(e._options.test(e._instances[t])){n=false}});if(!n){this._raf=requestAnimationFrame(this._animateValues.bind(this));this._handlers["tick"].forEach(function(t){return t(e._instances)})}else{Object.keys(this._instances).forEach(function(t){e._instances[t].current=e._instances[t].target;e._instances[t].velocity=0});this._handlers["tick"].forEach(function(t){return t(e._instances)});this._handlers["end"].forEach(function(t){return t(e._instances)});this._raf=null}}},{key:"on",value:function t(e,n){if(this._handlers[e]){this._handlers[e].push(n)}else{console.warn("Unsupported event "+e+".")}}},{key:"off",value:function t(e,n){var i=this;if(e!=null){if(n!=null){if(this._handlers[e]&&this._handlers[e].filter(function(t){return t===n}).length){var r=this._handlers[e].filter(function(t){return t===n})[0];var s=this._handlers[e].indexOf(r);if(s>-1){this._handlers[e].splice(s,1)}}else{console.warn("Handler for event "+e+" no found.")}}else{this._handlers[e]=[]}}else{Object.keys(this._handlers).forEach(function(t){i._handlers[t]=[]})}}}]);return t}();e.default=a;var o=function(){function t(e,n,i){s(this,t);this.current=e;this.target=e;this._acceleration=n;this._friction=i;this.velocity=0}r(t,[{key:"update",value:function t(){var e=this.target-this.current;var n=e*this._acceleration;this.applyForce(n);this.velocity*=this._friction;this.current+=this.velocity;return e}},{key:"applyForce",value:function t(e){this.velocity+=e}}]);return t}()}])});
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export default class Kinet {
2 |
3 | constructor(options) {
4 | this._handlers = {
5 | set: [],
6 | start: [],
7 | tick: [],
8 | end: [],
9 | };
10 |
11 | let dafaults = {
12 | friction: 1 - 0.3,
13 | acceleration: 0.04,
14 | initialValue: 0,
15 | names: ["x"],
16 | test: function (instance) {
17 | return Math.abs(instance.current - instance.target) > 0.1;
18 | },
19 | };
20 |
21 | this._options = {
22 | ...dafaults,
23 | ...options,
24 | };
25 |
26 | // to set correct value (1 - x)
27 | if (options && options.friction) {
28 | this._options.friction = 1 - options.friction;
29 | }
30 |
31 | this._instances = {};
32 | this._options.names.forEach(name => {
33 | this._instances[name] = new KinetItem(this._options.initialValue, this._options.acceleration, this._options.friction);
34 | });
35 |
36 | this._raf = null;
37 | }
38 |
39 | set(name, num) {
40 | if (num == null) {
41 | console.warn('Define a value.');
42 | return;
43 | }
44 | if (this._instances[name] == null) {
45 | console.warn(`Instance "${name}" doesn't exist.`);
46 | return;
47 | }
48 | this._instances[name].current = num;
49 | this._instances[name].target = num;
50 | if (!this._raf) {
51 | this._handlers['set'].forEach(handler => handler(this._instances));
52 | this._handlers['tick'].forEach(handler => handler(this._instances));
53 | }
54 | }
55 |
56 | animate(name, num) {
57 | if (num == null) {
58 | console.warn('Define a value.');
59 | return;
60 | }
61 | if (this._instances[name] == null) {
62 | console.warn(`Instance ${name} doesn't exist.`);
63 | return;
64 | }
65 | if (this._instances[name].target !== num) {
66 | this._instances[name].target = num;
67 | if (!this._raf) {
68 | this._handlers['start'].forEach(handler => handler(this._instances, this._instances));
69 | this._animateValues();
70 | }
71 | return num;
72 | }
73 |
74 | return false;
75 | }
76 |
77 | _animateValues() {
78 | let done = true;
79 |
80 | Object.keys(this._instances).forEach(key => {
81 | this._instances[key].update();
82 |
83 | if (this._options.test(this._instances[key])) {
84 | done = false;
85 | }
86 | });
87 |
88 | if (!done) {
89 | this._raf = requestAnimationFrame(this._animateValues.bind(this));
90 | this._handlers['tick'].forEach(handler => handler(this._instances));
91 | } else {
92 | // set to final values
93 | Object.keys(this._instances).forEach(key => {
94 | this._instances[key].current = this._instances[key].target;
95 | this._instances[key].velocity = 0;
96 | });
97 |
98 | this._handlers['tick'].forEach(handler => handler(this._instances));
99 | this._handlers['end'].forEach(handler => handler(this._instances));
100 | this._raf = null;
101 | }
102 | }
103 |
104 | on(event, handler) {
105 | if (this._handlers[event]) {
106 | this._handlers[event].push(handler);
107 | } else {
108 | console.warn(`Unsupported event ${event}.`);
109 | }
110 | }
111 |
112 | off(event, handler) {
113 | if (event != null) {
114 | if (handler != null) {
115 | if (this._handlers[event] && this._handlers[event].filter(savedHandler => savedHandler === handler).length) {
116 | let toRemove = this._handlers[event].filter(savedHandler => savedHandler === handler)[0];
117 | let index = this._handlers[event].indexOf(toRemove);
118 | if (index > -1) {
119 | this._handlers[event].splice(index, 1);
120 | }
121 | } else {
122 | console.warn(`Handler for event ${event} no found.`);
123 | }
124 | } else {
125 | this._handlers[event] = [];
126 | }
127 | } else {
128 | Object.keys(this._handlers).forEach(keys => {
129 | this._handlers[keys] = [];
130 | });
131 | }
132 | }
133 |
134 | }
135 |
136 | class KinetItem {
137 | constructor(intitalValue, acceleration, friction) {
138 | this.current = intitalValue;
139 | this.target = intitalValue;
140 | this._acceleration = acceleration;
141 | this._friction = friction;
142 | this.velocity = 0;
143 | }
144 |
145 | update() {
146 | const distance = this.target - this.current;
147 | const attraction = distance * this._acceleration;
148 |
149 | this.applyForce(attraction);
150 |
151 | this.velocity *= this._friction;
152 | this.current += this.velocity;
153 |
154 | return distance;
155 | }
156 |
157 | applyForce(force) {
158 | this.velocity += force;
159 | }
160 | }
--------------------------------------------------------------------------------
/dist/kinet.js:
--------------------------------------------------------------------------------
1 | (function webpackUniversalModuleDefinition(root, factory) {
2 | if(typeof exports === 'object' && typeof module === 'object')
3 | module.exports = factory();
4 | else if(typeof define === 'function' && define.amd)
5 | define([], factory);
6 | else if(typeof exports === 'object')
7 | exports["Kinet"] = factory();
8 | else
9 | root["Kinet"] = factory();
10 | })(window, function() {
11 | return /******/ (function(modules) { // webpackBootstrap
12 | /******/ // The module cache
13 | /******/ var installedModules = {};
14 | /******/
15 | /******/ // The require function
16 | /******/ function __webpack_require__(moduleId) {
17 | /******/
18 | /******/ // Check if module is in cache
19 | /******/ if(installedModules[moduleId]) {
20 | /******/ return installedModules[moduleId].exports;
21 | /******/ }
22 | /******/ // Create a new module (and put it into the cache)
23 | /******/ var module = installedModules[moduleId] = {
24 | /******/ i: moduleId,
25 | /******/ l: false,
26 | /******/ exports: {}
27 | /******/ };
28 | /******/
29 | /******/ // Execute the module function
30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31 | /******/
32 | /******/ // Flag the module as loaded
33 | /******/ module.l = true;
34 | /******/
35 | /******/ // Return the exports of the module
36 | /******/ return module.exports;
37 | /******/ }
38 | /******/
39 | /******/
40 | /******/ // expose the modules object (__webpack_modules__)
41 | /******/ __webpack_require__.m = modules;
42 | /******/
43 | /******/ // expose the module cache
44 | /******/ __webpack_require__.c = installedModules;
45 | /******/
46 | /******/ // define getter function for harmony exports
47 | /******/ __webpack_require__.d = function(exports, name, getter) {
48 | /******/ if(!__webpack_require__.o(exports, name)) {
49 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
50 | /******/ }
51 | /******/ };
52 | /******/
53 | /******/ // define __esModule on exports
54 | /******/ __webpack_require__.r = function(exports) {
55 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
56 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
57 | /******/ }
58 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
59 | /******/ };
60 | /******/
61 | /******/ // create a fake namespace object
62 | /******/ // mode & 1: value is a module id, require it
63 | /******/ // mode & 2: merge all properties of value into the ns
64 | /******/ // mode & 4: return value when already ns object
65 | /******/ // mode & 8|1: behave like require
66 | /******/ __webpack_require__.t = function(value, mode) {
67 | /******/ if(mode & 1) value = __webpack_require__(value);
68 | /******/ if(mode & 8) return value;
69 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
70 | /******/ var ns = Object.create(null);
71 | /******/ __webpack_require__.r(ns);
72 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
73 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
74 | /******/ return ns;
75 | /******/ };
76 | /******/
77 | /******/ // getDefaultExport function for compatibility with non-harmony modules
78 | /******/ __webpack_require__.n = function(module) {
79 | /******/ var getter = module && module.__esModule ?
80 | /******/ function getDefault() { return module['default']; } :
81 | /******/ function getModuleExports() { return module; };
82 | /******/ __webpack_require__.d(getter, 'a', getter);
83 | /******/ return getter;
84 | /******/ };
85 | /******/
86 | /******/ // Object.prototype.hasOwnProperty.call
87 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
88 | /******/
89 | /******/ // __webpack_public_path__
90 | /******/ __webpack_require__.p = "";
91 | /******/
92 | /******/
93 | /******/ // Load entry module and return exports
94 | /******/ return __webpack_require__(__webpack_require__.s = 0);
95 | /******/ })
96 | /************************************************************************/
97 | /******/ ([
98 | /* 0 */
99 | /***/ (function(module, exports, __webpack_require__) {
100 |
101 | "use strict";
102 |
103 |
104 | var _index = __webpack_require__(1);
105 |
106 | var _index2 = _interopRequireDefault(_index);
107 |
108 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
109 |
110 | module.exports = _index2.default; // this is here for webpack to expose Kinet as window.Kinet
111 |
112 | /***/ }),
113 | /* 1 */
114 | /***/ (function(module, exports, __webpack_require__) {
115 |
116 | "use strict";
117 |
118 |
119 | Object.defineProperty(exports, "__esModule", {
120 | value: true
121 | });
122 |
123 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
124 |
125 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
126 |
127 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
128 |
129 | var Kinet = function () {
130 | function Kinet(options) {
131 | var _this = this;
132 |
133 | _classCallCheck(this, Kinet);
134 |
135 | this._handlers = {
136 | set: [],
137 | start: [],
138 | tick: [],
139 | end: []
140 | };
141 |
142 | var dafaults = {
143 | friction: 1 - 0.3,
144 | acceleration: 0.04,
145 | initialValue: 0,
146 | names: ["x"],
147 | test: function test(instance) {
148 | return Math.abs(instance.current - instance.target) > 0.1;
149 | }
150 | };
151 |
152 | this._options = _extends({}, dafaults, options);
153 |
154 | // to set correct value (1 - x)
155 | if (options && options.friction) {
156 | this._options.friction = 1 - options.friction;
157 | }
158 |
159 | this._instances = {};
160 | this._options.names.forEach(function (name) {
161 | _this._instances[name] = new KinetItem(_this._options.initialValue, _this._options.acceleration, _this._options.friction);
162 | });
163 |
164 | this._raf = null;
165 | }
166 |
167 | _createClass(Kinet, [{
168 | key: 'set',
169 | value: function set(name, num) {
170 | var _this2 = this;
171 |
172 | if (num == null) {
173 | console.warn('Define a value.');
174 | return;
175 | }
176 | if (this._instances[name] == null) {
177 | console.warn('Instance "' + name + '" doesn\'t exist.');
178 | return;
179 | }
180 | this._instances[name].current = num;
181 | this._instances[name].target = num;
182 | if (!this._raf) {
183 | this._handlers['set'].forEach(function (handler) {
184 | return handler(_this2._instances);
185 | });
186 | this._handlers['tick'].forEach(function (handler) {
187 | return handler(_this2._instances);
188 | });
189 | }
190 | }
191 | }, {
192 | key: 'animate',
193 | value: function animate(name, num) {
194 | var _this3 = this;
195 |
196 | if (num == null) {
197 | console.warn('Define a value.');
198 | return;
199 | }
200 | if (this._instances[name] == null) {
201 | console.warn('Instance ' + name + ' doesn\'t exist.');
202 | return;
203 | }
204 | if (this._instances[name].target !== num) {
205 | this._instances[name].target = num;
206 | if (!this._raf) {
207 | this._handlers['start'].forEach(function (handler) {
208 | return handler(_this3._instances, _this3._instances);
209 | });
210 | this._animateValues();
211 | }
212 | return num;
213 | }
214 |
215 | return false;
216 | }
217 | }, {
218 | key: '_animateValues',
219 | value: function _animateValues() {
220 | var _this4 = this;
221 |
222 | var done = true;
223 |
224 | Object.keys(this._instances).forEach(function (key) {
225 | _this4._instances[key].update();
226 |
227 | if (_this4._options.test(_this4._instances[key])) {
228 | done = false;
229 | }
230 | });
231 |
232 | if (!done) {
233 | this._raf = requestAnimationFrame(this._animateValues.bind(this));
234 | this._handlers['tick'].forEach(function (handler) {
235 | return handler(_this4._instances);
236 | });
237 | } else {
238 | // set to final values
239 | Object.keys(this._instances).forEach(function (key) {
240 | _this4._instances[key].current = _this4._instances[key].target;
241 | _this4._instances[key].velocity = 0;
242 | });
243 |
244 | this._handlers['tick'].forEach(function (handler) {
245 | return handler(_this4._instances);
246 | });
247 | this._handlers['end'].forEach(function (handler) {
248 | return handler(_this4._instances);
249 | });
250 | this._raf = null;
251 | }
252 | }
253 | }, {
254 | key: 'on',
255 | value: function on(event, handler) {
256 | if (this._handlers[event]) {
257 | this._handlers[event].push(handler);
258 | } else {
259 | console.warn('Unsupported event ' + event + '.');
260 | }
261 | }
262 | }, {
263 | key: 'off',
264 | value: function off(event, handler) {
265 | var _this5 = this;
266 |
267 | if (event != null) {
268 | if (handler != null) {
269 | if (this._handlers[event] && this._handlers[event].filter(function (savedHandler) {
270 | return savedHandler === handler;
271 | }).length) {
272 | var toRemove = this._handlers[event].filter(function (savedHandler) {
273 | return savedHandler === handler;
274 | })[0];
275 | var index = this._handlers[event].indexOf(toRemove);
276 | if (index > -1) {
277 | this._handlers[event].splice(index, 1);
278 | }
279 | } else {
280 | console.warn('Handler for event ' + event + ' no found.');
281 | }
282 | } else {
283 | this._handlers[event] = [];
284 | }
285 | } else {
286 | Object.keys(this._handlers).forEach(function (keys) {
287 | _this5._handlers[keys] = [];
288 | });
289 | }
290 | }
291 | }]);
292 |
293 | return Kinet;
294 | }();
295 |
296 | exports.default = Kinet;
297 |
298 | var KinetItem = function () {
299 | function KinetItem(intitalValue, acceleration, friction) {
300 | _classCallCheck(this, KinetItem);
301 |
302 | this.current = intitalValue;
303 | this.target = intitalValue;
304 | this._acceleration = acceleration;
305 | this._friction = friction;
306 | this.velocity = 0;
307 | }
308 |
309 | _createClass(KinetItem, [{
310 | key: 'update',
311 | value: function update() {
312 | var distance = this.target - this.current;
313 | var attraction = distance * this._acceleration;
314 |
315 | this.applyForce(attraction);
316 |
317 | this.velocity *= this._friction;
318 | this.current += this.velocity;
319 |
320 | return distance;
321 | }
322 | }, {
323 | key: 'applyForce',
324 | value: function applyForce(force) {
325 | this.velocity += force;
326 | }
327 | }]);
328 |
329 | return KinetItem;
330 | }();
331 |
332 | /***/ })
333 | /******/ ]);
334 | });
--------------------------------------------------------------------------------