UNPKG

immaterial-design-ripple

Version:
282 lines (242 loc) 13.2 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <base data-ice="baseUrl" href="../../"> <title data-ice="title">src/index.js | API Document</title> <link type="text/css" rel="stylesheet" href="css/style.css"> <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css"> <script src="script/prettify/prettify.js"></script> <script src="script/manual.js"></script> </head> <body class="layout-container" data-ice="rootContainer"> <header> <a href="./">Home</a> <a href="identifiers.html">Reference</a> <a href="source.html">Source</a> <a data-ice="repoURL" href="https://github.com/immaterial-design/immaterial-design-ripple" class="repo-url-github">Repository</a> <div class="search-box"> <span> <img src="./image/search.png"> <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span> </span> <ul class="search-result"></ul> </div> </header> <nav class="navigation" data-ice="nav"><div> <ul> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/index.js~ImdRipple.html">ImdRipple</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-createContext2d">createContext2d</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-createRenderSchedule">createRenderSchedule</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getImageData">getImageData</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getPixelColor">getPixelColor</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getTimingFunction">getTimingFunction</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-promiseEvent">promiseEvent</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-requestAnimationFrame">requestAnimationFrame</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-transparentize">transparentize</a></span></span></li> </ul> </div> </nav> <div class="content" data-ice="content"><h1 data-ice="title">src/index.js</h1> <pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import EventEmitter from &apos;events&apos;; import Promise from &apos;bluebird&apos;; import * as util from &apos;./utility&apos;; import JSON5 from &apos;json5&apos;; import objectAssign from &apos;object-assign&apos;; export default class ImdRipple extends EventEmitter { /** * &#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3067;&#x4F7F;&#x7528;&#x3059;&#x308B;&#x30E6;&#x30FC;&#x30C6;&#x30A3;&#x30EA;&#x30C6;&#x30A3;&#x95A2;&#x6570;&#x7FA4;&#x306E;&#x53C2;&#x7167; * * @static * @public * @property ImdRipple.util */ static get util() { return util; } /** * &#x30DA;&#x30FC;&#x30B8;&#x306E;&#x8AAD;&#x307F;&#x8FBC;&#x307F;&#x6642;&#x306B;&#x30A4;&#x30F3;&#x30B9;&#x30BF;&#x30F3;&#x30B9;&#x3092;&#x81EA;&#x52D5;&#x3067;&#x751F;&#x6210;&#x3059;&#x308B; * * @static * @public * @method ImdRipple.bindOnLoad */ static bindOnLoad(selector, options = {}) { return new Promise((resolve) =&gt; { window.addEventListener(&apos;load&apos;, () =&gt; { const elements = [].slice.call(document.querySelectorAll(selector)); resolve(elements.map((element) =&gt; new ImdRipple(element, options))); }); }); } /** * &#x6307;&#x5B9A;&#x306E;&#x8981;&#x7D20;&#x306E;&#x30AF;&#x30EA;&#x30C3;&#x30AF;&#x6642;&#x306B;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3059;&#x308B;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3092;&#x8FFD;&#x52A0;&#x3059;&#x308B; * * @class ImdRipple * @constructor * @param {Element} element - &#x30AF;&#x30EA;&#x30C3;&#x30AF;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3092;&#x76E3;&#x8996;&#x3059;&#x308B;&#x8981;&#x7D20;&#x3002;&#x30A2;&#x30CB;&#x30E1;&#x6642;&#x5B50;&#x8981;&#x7D20;&#x3068;&#x3057;&#x3066;Canvas&#x3092;&#x8FFD;&#x52A0;&#x3059;&#x308B; * @param {Object} [options] - this.play&#x306E;&#x5F15;&#x6570; */ constructor(element, options = {}) { super(); /** * @public * @property {HTMLElement} element */ this.element = element; // &#x89AA;&#x8981;&#x7D20;&#x3068;&#x5168;&#x304F;&#x540C;&#x3058;&#x5927;&#x304D;&#x3055;&#x306E;canvas&#x8981;&#x7D20;&#x3067;&#x3042;&#x308B;&#x3053;&#x3068;&#x3092;&#x671F;&#x5F85;&#x3059;&#x308B; // &#x305D;&#x306E;&#x305F;&#x3081;&#x3001;position:static&#x30D7;&#x30ED;&#x30D1;&#x30C6;&#x30A3;&#x3092;&#x4F7F;&#x7528;&#x3057;&#x306A;&#x3044; const position = window.getComputedStyle(element).getPropertyValue(&apos;position&apos;); if (position === &apos;static&apos;) { this.element.style.position = &apos;relative&apos;; } // mouseup&#xFF0F;touchend&#x3067;&#x30AD;&#x30E3;&#x30F3;&#x30D0;&#x30B9;&#x306E;&#x900F;&#x660E;&#x5316;&#x3092;&#x958B;&#x59CB;&#x3059;&#x308B; this.element.addEventListener(&apos;mousedown&apos;, (event) =&gt; { if (event.which !== 1) {// only left click return; } const { left, top } = this.element.getBoundingClientRect(); const x = Math.floor(event.clientX - left); const y = Math.floor(event.clientY - top); this.emit(&apos;begin&apos;); this.play(x, y, objectAssign({ exitBefore: &apos;mouseup&apos; }, options)) .then(() =&gt; { this.emit(&apos;end&apos;); }); }); this.element.addEventListener(&apos;touchstart&apos;, (event) =&gt; { const { left, top } = this.element.getBoundingClientRect(); const x = Math.floor(event.changedTouches[0].clientX - left); const y = Math.floor(event.changedTouches[0].clientY - top); this.emit(&apos;begin&apos;); this.play(x, y, objectAssign({ exitBefore: &apos;touchend&apos; }, options)) .then(() =&gt; { this.emit(&apos;end&apos;); }); }); } /** * this.element&#x306B;&#x76F4;&#x63A5;&#x5B9A;&#x7FA9;&#x3057;&#x305F;&#x30AA;&#x30D7;&#x30B7;&#x30E7;&#x30F3;&#x3092;&#x8FD4;&#x3059; * * @public * @method getOptions * @param {String} attrName &#x53D6;&#x5F97;&#x3057;&#x3001;json5&#x3068;&#x3057;&#x3066;&#x30D1;&#x30FC;&#x30B9;&#x3059;&#x308B;&#x5C5E;&#x6027;&#x540D; * @return {Object} options &#x30AA;&#x30D7;&#x30B7;&#x30E7;&#x30F3; */ getOptions(attrName = &apos;imd-options&apos;) { return JSON5.parse(this.element.getAttribute(attrName) || &apos;{}&apos;); } /** * &#x30B3;&#x30F3;&#x30B9;&#x30C8;&#x30E9;&#x30AF;&#x30BF;&#x306E;&#x8981;&#x7D20;&#x5185;&#x3067;&#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3092;&#x518D;&#x751F;&#x3059;&#x308B; * * @public * @method ImdRipple#play * @param {Number} [x=auto] &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x59CB;&#x70B9;x * @param {Number} [y=auto] &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x59CB;&#x70B9;y * @param {Object} [options] ImdRipple.ripple&#x3067;&#x4F7F;&#x7528;&#x3059;&#x308B;&#x5F15;&#x6570; * @param {String|Bool} [options.exitBefore] canvas&#x3092;&#x7834;&#x68C4;&#x3059;&#x308B;&#x30BF;&#x30A4;&#x30DF;&#x30F3;&#x30B0;&#x306E;&#x6307;&#x5B9A; * @return {Promise} ImdRipple.play&#x53C2;&#x7167; */ play(x, y, options = {}) { const opts = objectAssign({ exitBefore: true, // auto }, this.getOptions(), options); const { width, height } = this.element.getBoundingClientRect(); const playX = x === undefined ? Math.floor(width / 2) : x; const playY = y === undefined ? Math.floor(height / 2) : y; const animation = ImdRipple.play(playX, playY, width, height, opts); this.element.appendChild(animation.context.canvas); let exit; if (typeof opts.exitBefore === &apos;string&apos;) { exit = util.promiseEvent(window, opts.exitBefore); } else if (opts.exitBefore === true) { exit = animation;// &#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x7D42;&#x4E86;&#x6642;&#x306B;&#x4E8B;&#x5F8C;&#x51E6;&#x7406; } return exit .then(() =&gt; util.transparentize(animation.context.canvas, opts)) .then(() =&gt; animation.stop()); } /** * CanvasRenderingContext2D&#x3092;&#x4F5C;&#x6210;&#x3057;&#x3066;&#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3092;&#x518D;&#x751F;&#x3059;&#x308B; * &#x5168;&#x3066;&#x306E;&#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x306E;&#x63CF;&#x5199;&#x3092;&#x7D42;&#x3048;&#x308B;&#x307E;&#x3067;canvas&#x3092;&#x66F4;&#x65B0;&#x3057;&#x7D9A;&#x3051;&#x308B; * &#x30AD;&#x30E3;&#x30F3;&#x30D0;&#x30B9;&#x304C;&#x5927;&#x304D;&#x3044;&#x307B;&#x3069;&#x8CA0;&#x8377;&#x304C;&#x9AD8;&#x3044;&#x306E;&#x3067;&#x3001;&#x66F4;&#x65B0;&#x306E;&#x5FC5;&#x8981;&#x304C;&#x306A;&#x3051;&#x308C;&#x3070;&#x505C;&#x6B62;&#x3059;&#x308B; * &#x5168;&#x3066;&#x306E;&#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x304C;&#x63CF;&#x5199;&#x3057;&#x305F;&#x6642;&#x304B;&#x3001;promise.stop&#x3092;&#x5B9F;&#x884C;&#x3057;&#x305F;&#x6642;&#x306B;&#x3001;fulfill&#x3059;&#x308B; * * @static * @public * @method ImdRipple.play * @param {Number} x &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x59CB;&#x70B9;x * @param {Number} y &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x59CB;&#x70B9;y * @param {Number} width &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x5E45; * @param {Number} height &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x9AD8;&#x3055; * @param {Object} [options] * @param {Number} [options.pixelSize=height/15] &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#xFF11;&#x7C92;&#x306E;&#x5927;&#x304D;&#x3055; * @return {Promise&lt;CanvasRenderingContext2D&gt;} animation &#x72EC;&#x81EA;&#x306E;&#xFF12;&#x30D7;&#x30ED;&#x30D1;&#x30C6;&#x30A3;&#x3092;&#x6301;&#x3064; */ static play(x, y, width, height, options = {}) { const opts = objectAssign({ pixelSize: Math.floor(height / 10), bitCrash: 7, pixelated: true, }, options); const context = util.createContext2d(width, height, opts); const schedule = util.createRenderSchedule(x, y, width, height, opts); const imageData = util.getImageData(context.canvas); const [r, g, b, a] = util.getPixelColor(opts.color); const promise = new Promise((resolve) =&gt; { let frame = 0; const render = () =&gt; { if (promise.disabled) { return resolve(context); } let rendered = true; let index = 0; for (let i = 0; i &lt; context.canvas.height; i++) { for (let j = 0; j &lt; context.canvas.width; j++) { const pixelX = Math.floor(j / schedule.pixelSize); const pixelY = Math.floor(i / schedule.pixelSize); const show = schedule.data[pixelY][pixelX] &lt;= frame; if (show === false) { rendered = false; } imageData.data[index + 0] = r; imageData.data[index + 1] = g; imageData.data[index + 2] = b; imageData.data[index + 3] = show ? a : 0; index += 4; } } context.putImageData(imageData, 0, 0); if (rendered) { return resolve(context); } frame += 1; return util.requestAnimationFrame(render); }; util.requestAnimationFrame(render); }); // FIXME: // Promise&#x3068;context&#x3092;&#x540C;&#x6642;&#x8FD4;&#x3057;&#x305F;&#x3044;&#x3002; // &#xFF08;mouseup&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3067;&#x900F;&#x660E;&#x5316;&#x3092;&#x59CB;&#x3081;&#x305F;&#x3044;&#x306E;&#x3067;&#xFF09; promise.context = context; promise.stop = function stopAnimation() { promise.disabled = true; return this; }; return promise; } } </code></pre> </div> <footer class="footer"> Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(0.4.7)</span></a> </footer> <script src="script/search_index.js"></script> <script src="script/search.js"></script> <script src="script/pretty-print.js"></script> <script src="script/inherited-summary.js"></script> <script src="script/test-summary.js"></script> <script src="script/inner-link.js"></script> <script src="script/patch-for-local.js"></script> </body> </html>