UNPKG

immaterial-design-ripple

Version:
307 lines (269 loc) 14.4 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <base data-ice="baseUrl" href="../../"> <title data-ice="title">src/utility.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/utility.js</h1> <pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import Promise from &apos;bluebird&apos;; import easingJs from &apos;easing-js&apos;; import objectAssign from &apos;object-assign&apos;; /** * &#x5229;&#x7528;&#x53EF;&#x80FD;&#x306A;&#x975E;&#x540C;&#x671F;&#x95A2;&#x6570;&#x3067;callback&#x3092;&#x5B9F;&#x884C;&#x3059;&#x308B; * * @function requestAnimationFrame * @param {Function} [callback] * @return undefined */ export function requestAnimationFrame(callback) { return window.requestAnimationFrame(callback); } /** * &#x6307;&#x5B9A;&#x3057;&#x305F;&#x8981;&#x7D20;&#x306E;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3092;&#x5F85;&#x3064;&#x30D7;&#x30ED;&#x30DF;&#x30B9;&#x3092;&#x8FD4;&#x3059; * * @function promiseEvent * @param {Element} target &#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3092;&#x53D6;&#x5F97;&#x3059;&#x308B;&#x8981;&#x7D20; * @param {String} eventName &#x53D6;&#x5F97;&#x3059;&#x308B;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x540D; * @return {Promise&lt;EventTarget&gt;} deferredEvent &#x53D6;&#x5F97;&#x3057;&#x305F;&#x30A4;&#x30D9;&#x30F3;&#x30C8; */ export function promiseEvent(target, eventName) { return new Promise((resolve) =&gt; { const onceListener = (event) =&gt; { target.removeEventListener(eventName, onceListener); resolve(event); }; target.addEventListener(eventName, onceListener); }); } /** * &#x6307;&#x5B9A;&#x3057;&#x305F;&#x5927;&#x304D;&#x3055;&#x306E;context2d&#x3092;&#x8FD4;&#x3059; * * @function createContext2d * @param {Number} width context&#x306E;&#x5E45; * @param {Number} height context&#x306E;&#x9AD8;&#x3055; * @param {Object} [options] * @param {Object} [options.pixelated=true] &#x30A2;&#x30F3;&#x30C1;&#x30A8;&#x30A4;&#x30EA;&#x30A2;&#x30B9;&#x3092;&#x5207;&#x308B; * @return {CanvasRenderingContext2D} */ export function createContext2d(width, height, options = {}) { const canvas = document.createElement(&apos;canvas&apos;); canvas.width = width; canvas.height = height; canvas.style.position = &apos;absolute&apos;; canvas.style.top = 0; canvas.style.right = 0; canvas.style.bottom = 0; canvas.style.left = 0; const context = canvas.getContext(&apos;2d&apos;); if (options.pixelated) { context.mozImageSmoothingEnabled = false; context.msImageSmoothingEnabled = false; context.imageSmoothingEnabled = false; } return context; } /** * context&#x3068;&#x540C;&#x3058;&#x5927;&#x304D;&#x3055;&#x306E;&#x7A7A;&#x306E;imageData&#x3092;&#x8FD4;&#x3059; * * @function getImageData * @param {HTMLCanvasElement} canvas &#x5927;&#x304D;&#x3055;&#x306E;&#x57FA;&#x6E96;&#x3068;&#x306A;&#x308B;canvas * @return {ImageData} */ export function getImageData(canvas) { const { width, height } = canvas; const newContext = document.createElement(&apos;canvas&apos;).getContext(&apos;2d&apos;); newContext.canvas.width = width; newContext.canvas.height = height; return newContext.getImageData(0, 0, width, height); } /** * canvas&#x3092;&#x900F;&#x660E;&#x5316;&#x3001;opacity:0&#x3067;canvas&#x3092;&#x7834;&#x68C4; * * @function transparentize * @param {Element} element &#x900F;&#x660E;&#x5316;&#x3055;&#x305B;&#x3001;&#x7834;&#x68C4;&#x3059;&#x308B;&#x8981;&#x7D20; * @param {Object} [options] * @param {Number} [options.opacityStep=0.02] 1&#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x306E;&#x900F;&#x660E;&#x5316;&#x9032;&#x884C;&#x5EA6; * @return {Promise&lt;null&gt;} animation &#x8981;&#x7D20;&#x7834;&#x68C4;&#x6642;&#x306B;fullfill */ export function transparentize(element, options = {}) { const elementStyle = element.style; const opts = objectAssign({ opacityStep: 0.02, }, options); return new Promise((resolve) =&gt; { let opacity = 1; const render = () =&gt; { opacity -= opts.opacityStep; if (opacity &lt;= 0) { elementStyle.opacity = 0; return resolve(); } elementStyle.opacity = opacity; return requestAnimationFrame(render); }; requestAnimationFrame(render); }).then(() =&gt; { if (element.parentNode) { element.parentNode.removeChild(element); } }); } /** * easingJs&#x3067;&#x5B9A;&#x7FA9;&#x3055;&#x308C;&#x305F;&#x95A2;&#x6570;&#x540D;&#x3067;&#x3042;&#x308C;&#x3070;&#x3001;&#x305D;&#x306E;&#x95A2;&#x6570;&#x3092;&#x8FD4;&#x3057; * &#x5F15;&#x6570;&#x304C;&#x95A2;&#x6570;&#x3067;&#x3042;&#x308C;&#x3070;&#x3001;&#x305D;&#x306E;&#x307E;&#x307E;&#x8FD4;&#x3059; * &#x305D;&#x308C;&#x4EE5;&#x5916;&#x306F;null * * @function getTimingFunction * @param {String|Function} name EasingJs&#x306E;&#x95A2;&#x6570;&#x540D;&#x304B;&#x3001;&#x72EC;&#x81EA;&#x3067;&#x95A2;&#x6570;&#x3092;&#x5B9A;&#x7FA9; * @return {Function|null} timingFunction (t,b,c,d)&#x3092;&#x53D7;&#x3051;&#x53D6;&#x308B;&#x30A4;&#x30FC;&#x30B8;&#x30F3;&#x30B0;&#x95A2;&#x6570;&#x3002;&#x672A;&#x5B9A;&#x7FA9;&#x306E;&#x95A2;&#x6570;&#x540D;&#x306A;&#x3089;null */ export function getTimingFunction(name = &apos;easeInBack&apos;) { if (typeof name === &apos;function&apos;) { return name; } if (easingJs[name]) { return easingJs[name]; } return null; } /** * &#x6307;&#x5B9A;&#x3057;&#x305F;&#x5927;&#x304D;&#x3055;&#x306E;imageData&#x3092;&#x4F5C;&#x6210;&#x3057; * &#x6CE2;&#x5F62;&#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3068;&#x3057;&#x3066;&#x8868;&#x793A;&#x3059;&#x308B;&#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x756A;&#x53F7;&#x3092;&#x8A08;&#x7B97;&#x3059;&#x308B; * x,y&#x3092;&#x59CB;&#x70B9;&#x3068;&#x3059;&#x308B; * * &#x8FD4;&#x3055;&#x308C;&#x308B;&#x914D;&#x5217;&#x306E;&#x5024;&#x306F;&#x5927;&#x304D;&#x3055;&#x304B;&#x3089;pixelSize&#x3092;&#x5272;&#x3063;&#x305F;&#x3082;&#x306E;&#x3002; * * @function createRenderSchedule * @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] &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#xFF11;&#x7C92;&#x306E;&#x5927;&#x304D;&#x3055; * @param {Number} [options.bitCrash=null] &#x5883;&#x754C;&#x306B;&#x30CE;&#x30A4;&#x30BA;&#x3092;&#x5165;&#x308C;&#x308B;&#x3001;&#x5024;&#x306F;&#x30CE;&#x30A4;&#x30BA;&#x306E;&#x5F37;&#x3055; * @param {String|Function} [options.timingFunction=&apos;easeInQuint&apos;] &#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x756A;&#x53F7;&#x306E;&#x30A4;&#x30FC;&#x30B8;&#x30F3;&#x30B0;&#x95A2;&#x6570;&#x540D; * @return {Object} RenderSchedule * @return {Array} RenderSchedule.data y&#x3068;x&#x304B;&#x3089;&#x306A;&#x308B;&#x4E8C;&#x6B21;&#x5143;&#x914D;&#x5217;&#x3002;&#x8868;&#x793A;&#x3059;&#x308B;&#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x756A;&#x53F7;&#x3092;&#x5024;&#x306B;&#x6301;&#x3064; * @return {Number} RenderSchedule.width &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x306E;&#x6A2A;&#x306E;&#x500B;&#x6570; * @return {Number} RenderSchedule.height &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x306E;&#x7E26;&#x306E;&#x500B;&#x6570; * @return {Number} RenderSchedule.pixelSize &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#xFF11;&#x7C92;&#x306E;&#x5927;&#x304D;&#x3055; * @return {Function|null} RenderSchedule.easedBy &#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x756A;&#x53F7;&#x306E;&#x8ABF;&#x6574;&#x306B;&#x4F7F;&#x7528;&#x3057;&#x305F;&#x95A2;&#x6570; */ export function createRenderSchedule(x, y, width, height, options = {}) { const opts = Object.create(options); if (opts.pixelSize === undefined) { opts.pixelSize = 1; } const dataWidth = Math.ceil(width / opts.pixelSize); const dataHeight = Math.ceil(height / opts.pixelSize); const data = []; // &#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x3054;&#x3068;&#x306E;&#x8868;&#x793A;&#x3092;&#x958B;&#x59CB;&#x3059;&#x308B;&#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x756A;&#x53F7;&#x3092;&#x5B9A;&#x7FA9;&#x3059;&#x308B; let c = 0;// maxFrame for (let i = 0; i &lt; dataHeight; i++) { if (data[i] === undefined) { data[i] = []; } for (let j = 0; j &lt; dataWidth; j++) { const originalX = opts.pixelSize * j; const originalY = opts.pixelSize * i; // x, y&#x304B;&#x3089;&#x306E;&#x8DDD;&#x96E2;&#x3092;&#x30D4;&#x30AF;&#x30BB;&#x30EB;&#x57FA;&#x6E96;&#x3067;&#x6C42;&#x3081;&#x308B; const distanceX = Math.abs(originalX - x); const distanceY = Math.abs(originalY - y); const distance = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2)); const showFrame = Math.floor(distance / opts.pixelSize); if (c &lt; showFrame) { c = showFrame; } data[i].push(showFrame); } } // &#x30A2;&#x30CB;&#x30E1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x306E;&#x7DE9;&#x6025;&#x3092;&#x5909;&#x66F4;&#x3059;&#x308B; // http://d.hatena.ne.jp/nakamura001/20111117/1321539246 const timingFunction = getTimingFunction(opts.timingFunction); if (timingFunction) { const d = 1; for (let i = 0; i &lt; data.length; i++) { for (let j = 0; j &lt; data[i].length; j++) { const b = data[i][j];// showFrame const t = c &gt; 0 ? (b / c) : 0;// distanceRate data[i][j] = Math.floor(timingFunction(t, b, c, d)); // &#xFF15;&#x30D5;&#x30EC;&#x30FC;&#x30E0;&#x4EE5;&#x964D;&#x306F;&#x5883;&#x754C;&#x90E8;&#x5206;&#x306E;&#x30B8;&#x30E3;&#x30AE;&#x30FC;&#x3092;&#x76EE;&#x7ACB;&#x305F;&#x305B;&#x308B;&#xFF08;&#x3055;&#x3055;&#x304F;&#x308C;&#x3055;&#x305B;&#x308B;&#xFF09; if (opts.bitCrash &gt; 1 &amp;&amp; b &gt; 5) { data[i][j] += Math.floor(opts.bitCrash * Math.random()); } } } } return { data, width: dataWidth, height: dataHeight, pixelSize: opts.pixelSize, easedBy: timingFunction, }; } /** * &#x6307;&#x5B9A;&#x3057;&#x305F;colorName&#x306E;rgba&#x3092;&#x8FD4;&#x3059;&#xFF08;CanvasRenderingContext2D&#x7D4C;&#x7531;&#xFF09; * * @function getPixelColor * @param {String} colorName CanvasRenderingContext2D.fillStyle&#x306E;&#x5024; * @return {Array} color [r,g,b,a] */ export function getPixelColor(colorName = &apos;rgba(0,0,0,.3)&apos;) { const context = document.createElement(&apos;canvas&apos;).getContext(&apos;2d&apos;); context.canvas.width = 1; context.canvas.width = 1; context.fillStyle = colorName; context.fillRect(0, 0, 1, 1); // splat&#x69CB;&#x6587;&#x3092;&#x4F7F;&#x7528;&#x3059;&#x308B;&#x3068;&#x30A8;&#x30E9;&#x30FC;&#x306B;&#x306A;&#x308B;&#x306E;&#x3067;&#x3001;&#x914D;&#x5217;&#x306B;&#x5909;&#x63DB;&#x3059;&#x308B; // const [r,g,b,a] = document.createElement(&apos;canvas&apos;).getContext(&apos;2d&apos;).getImagedata(...).data // =&gt; TypeError: Invalid attempt to destructure non-iterable instance return [].slice.call(context.getImageData(0, 0, 1, 1).data); } </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>