UNPKG

66.1 kBJavaScriptView Raw
1/************************************
2
3 RADIX
4 - Version : 4.1.8
5
6 Copyright 2021 shoalwave and other contributors.
7 Released under the MIT License.
8 https://radix.shoalwave.net/LICENSE
9
10************************************/
11
12let DOMLoaded = false;
13let windowLoaded = false;
14window.addEventListener('DOMContentLoaded', () => { DOMLoaded = true });
15window.addEventListener('load', () => { windowLoaded = true });
16
17/**
18 * 本体クラス
19 * @typedef radix
20 * @type class
21 * @property {object} option オプション値を格納
22 * @property {object} modalParts モーダルウィンドウ機能で生成しているエレメントノードたち
23 * @property {object} events 各操作に対して発火しているイベントフックたち
24 * @property {object} icons SVGアイコンの全ノード
25 * @property {boolean} isMobile モバイル端末(タッチ操作可能)か否か
26 * @property {boolean} navState ナビゲーションの開閉状態
27 * @property {boolean} modalState モーダルウィンドウの開閉状態
28 * @property {boolean} initialized init() 関数の実行が完了したか
29 * @property {function} init radixの初期化を行う関数
30 * @property {function} toggleNav ナビゲーション開閉を実行する関数
31 * @property {function} smoothScroll スムーススクロールを実行する関数
32 * @property {function} replaceIcon SVGアイコンにエレメントを置換する関数
33 * @property {function} dragDown ドラッグスクロールのマウスダウン
34 * @property {function} dragMove ドラッグスクロールのマウスムーブ
35 * @property {function} dragUp ドラッグスクロールのマウスアップ
36 * @property {function} modalOpen モーダルウィンドウを開く関数
37 * @property {function} modalClose モーダルウィンドウを閉じる関数
38 * @property {function} modalResize モーダルウィンドウの拡縮をする関数
39 * @property {function} floatRound 浮動小数点数の文字列変換関数
40 * @property {function} floatCeil 浮動小数点数の文字列変換関数
41 * @property {function} floatFloor 浮動小数点数の文字列変換関数
42 * @property {function} preventScroll ページ全体の縦方向スクロール禁止を操作する関数
43 * @property {function} getEasing イージング関数を取得する関数
44 */
45class Radix {
46 /**
47 * コンストラクタ
48 * @constructor
49 */
50 constructor(option, mode) {
51 this.version = '4.1.8'
52 const defOption = {
53 timeFrame: 10,
54 preload: {
55 active: false,
56 selector: '',
57 class: 'hide',
58 delay: 200,
59 preventScroll: false
60 },
61 smoothScroll: {
62 active: true,
63 duration: 600,
64 easing: 'easeInOutExpo',
65 header: '',
66 },
67 fixExtLink: {
68 active: true
69 },
70 toggleNav: {
71 active: false,
72 trigger: '',
73 target: '',
74 class: 'opened',
75 preventScroll: false
76 },
77 icons: {
78 active: true,
79 selector: '.radix-icon'
80 },
81 dragScroll: {
82 active: true,
83 selector: '.radix-drag',
84 hint: true
85 },
86 flexFix: {
87 active: true,
88 selector: '.radix-flexfix',
89 inherit: true,
90 min: 0
91 },
92 modal: {
93 active: true,
94 selector: '.radix-modal',
95 class: 'white',
96 resizeDuration: 300,
97 resizeEasing: 'easeInOutBack',
98 scaleStep: [0.2, 0.4, 0.6, 0.8, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5],
99 fit: true,
100 drag: true,
101 magnify: true,
102 wrap: false
103 },
104 scrollAppear: {
105 active: true,
106 selector: '.radix-appear',
107 delay: 200,
108 reset: true,
109 class: 'active'
110 }
111 }
112 const argFlg = this.typeJudge(option) == 'object' ? true : false;
113 Object.keys(defOption).forEach(key => {
114 if (mode === false && key != 'timeFrame') {
115 defOption[key].active = false;
116 }
117 if (argFlg) {
118 Object.assign(defOption[key], option[key]);
119 }
120 });
121 this.option = defOption;
122 // インスタンス変数
123 this.navState = false;
124 this.modalState = false;
125 this.initialized = false;
126 this.isMobile = typeof window.ontouchstart === "undefined" ? false : true;
127 this.DOM_ROOTS = document.querySelectorAll('html,body');
128 this.events = {
129 beforeInitialize: new CustomEvent('_radixInit'),
130 afterInitialize: new CustomEvent('radixInit_'),
131 beforeScroll: new CustomEvent('_radixScroll'),
132 afterScroll: new CustomEvent('radixScroll_'),
133 beforeNavOpen: new CustomEvent('_radixNavOpen'),
134 afterNavOpen: new CustomEvent('radixNavOpen_'),
135 beforeNavClose: new CustomEvent('_radixNavClose'),
136 afterNavClose: new CustomEvent('radixNavClose_'),
137 beforeModalOpen: new CustomEvent('_radixModalOpen'),
138 afterModalOpen: new CustomEvent('radixModalOpen_'),
139 beforeModalClose: new CustomEvent('_radixModalClose'),
140 afterModalClose: new CustomEvent('radixModalClose_'),
141 }
142 }
143 /**
144 * DOMロード時に実行し初期化する関数
145 */
146 init() {
147 const self = this;
148 new Promise(resolve => {
149 // Speed 0
150 document.dispatchEvent(self.events.beforeInitialize);
151 if (DOMLoaded) {
152 resolve();
153 } else {
154 window.addEventListener('DOMContentLoaded', resolve);
155 }
156 }).then(() => {
157 // Speed 1
158 return new Promise(resolve => {
159 // preload display
160 if (self.option.preload.active) {
161 if (self.option.preload.preventScroll) self.preventScroll(true);
162 let preloader = self.option.preload.selector.length > 0 ? document.querySelectorAll(self.option.preload.selector) : [];
163 window.addEventListener('load', () => {
164 if (self.option.preload.active && preloader && self.initialized) {
165 setTimeout(() => {
166 if (self.option.preload.preventScroll) self.preventScroll(false);
167 preloader.forEach(pl => {
168 pl.classList.add(self.option.preload.class);
169 });
170 }, self.option.preload.delay);
171 }
172 });
173 document.addEventListener('radixInit_', () => {
174 self.initialized = true;
175 if (self.option.preload.active && preloader.length > 0 && windowLoaded) {
176 setTimeout(() => {
177 if (self.option.preload.preventScroll) self.preventScroll(false);
178 preloader.forEach(pl => {
179 pl.classList.add(self.option.preload.class);
180 });
181 }, self.option.preload.delay);
182 }
183 });
184 }
185 // SVG insert
186 if (self.option.icons.active) {
187 const iconSources = {
188 cross: {
189 viewbox: '0 0 100 100',
190 path: 'M 2 17 L 17 2 L 50 35 L 83 2 L 98 17 L 65 50 L 98 83 L 83 98 L 50 65 L 17 98 L 2 83 L 35 50 L 2 17 Z',
191 fill: true,
192 stroke: 0,
193 linejoin: 'miter',
194 linecap: 'butt'
195 },
196 angle_top: {
197 viewbox: '0 0 100 100',
198 path: 'M 50 19 L 97 66 L 84 79 L 50 45 L 16 79 L 3 66 L 50 19 Z',
199 fill: true,
200 stroke: 0
201 },
202 angle_right: {
203 viewbox: '0 0 100 100',
204 path: 'M 81 50 L 34 97 L 21 84 L 55 50 L 21 16 L 34 3 L 81 50 Z',
205 fill: true,
206 stroke: 0
207 },
208 angle_bottom: {
209 viewbox: '0 0 100 100',
210 path: 'M 50 81 L 97 34 L 84 21 L 50 55 L 16 21 L 3 34 L 50 81 Z',
211 fill: true,
212 stroke: 0
213 },
214 angle_left: {
215 viewbox: '0 0 100 100',
216 path: 'M 19 50 L 66 3 L 79 16 L 45 50 L 79 84 L 66 97 L 19 50 Z',
217 fill: true,
218 stroke: 0
219 },
220 arrow_lr: {
221 viewbox: '0 0 100 100',
222 path: 'M 10 50 L 35 20 L 35 42 L 65 42 L 65 20 L 90 50 L 65 80 L 65 58 L 35 58 L 35 80 L 10 50 Z',
223 fill: true,
224 stroke: 0
225 },
226 arrow_tb: {
227 viewbox: '0 0 100 100',
228 path: 'M 50 10 L 80 35 L 58 35 L 58 65 L 80 65 L 50 90 L 20 65 L 42 65 L 42 35 L 20 35 L 50 10 Z',
229 fill: true,
230 stroke: 0
231 },
232 magnifying_glass: {
233 viewbox: '0 0 500 500',
234 path: 'M 120 195 C 120 92.896 202.896 10 305 10 C 407.104 10 490 92.896 490 195 C 490 297.104 407.104 380 305 380 C 202.896 380 120 297.104 120 195 Z M 180 195 C 179.99 186.52 180.85 178.06 182.55 169.75 C 184.18 161.76 186.61 153.94 189.8 146.42 C 196.1 131.55 205.21 118.05 216.64 106.64 C 228.05 95.21 241.55 86.1 256.42 79.8 C 263.94 76.61 271.76 74.18 279.76 72.54 C 288.07 70.85 296.52 69.99 305 70 C 313.48 69.99 321.93 70.85 330.24 72.54 C 338.24 74.18 346.06 76.61 353.58 79.8 C 368.45 86.1 381.95 95.21 393.36 106.64 C 404.79 118.05 413.9 131.55 420.2 146.42 C 423.39 153.94 425.82 161.76 427.46 169.76 C 429.15 178.07 430.01 186.52 430 195 C 430.01 203.48 429.15 211.93 427.46 220.24 C 425.82 228.24 423.39 236.06 420.2 243.58 C 413.9 258.45 404.79 271.95 393.36 283.36 C 381.95 294.79 368.45 303.9 353.58 310.2 C 346.06 313.39 338.24 315.82 330.24 317.46 C 321.93 319.15 313.48 320.01 305 320 C 296.52 320.01 288.07 319.15 279.76 317.46 C 271.76 315.82 263.94 313.39 256.42 310.2 C 241.55 303.9 228.05 294.79 216.64 283.36 C 205.21 271.95 196.1 258.45 189.8 243.58 C 186.61 236.06 184.18 228.24 182.54 220.24 C 180.85 211.93 179.99 203.48 180 195 Z M 13 490 L 13 413.148 L 126.148 300 L 203 376.852 L 89.852 490 L 13 490 Z',
235 fill: true,
236 fillRule: "evenodd",
237 stroke: 0
238 },
239 zoom_in: {
240 viewbox: '0 0 500 500',
241 path: 'M 120 195 C 120 92.896 202.896 10 305 10 C 407.104 10 490 92.896 490 195 C 490 297.104 407.104 380 305 380 C 202.896 380 120 297.104 120 195 Z M 180 195 C 179.99 186.52 180.85 178.06 182.55 169.75 C 184.18 161.76 186.61 153.94 189.8 146.42 C 196.1 131.55 205.21 118.05 216.64 106.64 C 228.05 95.21 241.55 86.1 256.42 79.8 C 263.94 76.61 271.76 74.18 279.76 72.54 C 288.07 70.85 296.52 69.99 305 70 C 313.48 69.99 321.93 70.85 330.24 72.54 C 338.24 74.18 346.06 76.61 353.58 79.8 C 368.45 86.1 381.95 95.21 393.36 106.64 C 404.79 118.05 413.9 131.55 420.2 146.42 C 423.39 153.94 425.82 161.76 427.46 169.76 C 429.15 178.07 430.01 186.52 430 195 C 430.01 203.48 429.15 211.93 427.46 220.24 C 425.82 228.24 423.39 236.06 420.2 243.58 C 413.9 258.45 404.79 271.95 393.36 283.36 C 381.95 294.79 368.45 303.9 353.58 310.2 C 346.06 313.39 338.24 315.82 330.24 317.46 C 321.93 319.15 313.48 320.01 305 320 C 296.52 320.01 288.07 319.15 279.76 317.46 C 271.76 315.82 263.94 313.39 256.42 310.2 C 241.55 303.9 228.05 294.79 216.64 283.36 C 205.21 271.95 196.1 258.45 189.8 243.58 C 186.61 236.06 184.18 228.24 182.54 220.24 C 180.85 211.93 179.99 203.48 180 195 Z M 13 490 L 13 413.148 L 126.148 300 L 203 376.852 L 89.852 490 L 13 490 Z M 205 160 L 270 160 L 270 95 L 340 95 L 340 160 L 405 160 L 405 230 L 340 230 L 340 295 L 270 295 L 270 230 L 205 230 L 205 160 Z',
242 fill: true,
243 fillRule: "evenodd",
244 stroke: 0
245 },
246 zoom_out: {
247 viewbox: '0 0 500 500',
248 path: 'M 120 195 C 120 92.896 202.896 10 305 10 C 407.104 10 490 92.896 490 195 C 490 297.104 407.104 380 305 380 C 202.896 380 120 297.104 120 195 Z M 180 195 C 179.99 186.52 180.85 178.06 182.55 169.75 C 184.18 161.76 186.61 153.94 189.8 146.42 C 196.1 131.55 205.21 118.05 216.64 106.64 C 228.05 95.21 241.55 86.1 256.42 79.8 C 263.94 76.61 271.76 74.18 279.76 72.54 C 288.07 70.85 296.52 69.99 305 70 C 313.48 69.99 321.93 70.85 330.24 72.54 C 338.24 74.18 346.06 76.61 353.58 79.8 C 368.45 86.1 381.95 95.21 393.36 106.64 C 404.79 118.05 413.9 131.55 420.2 146.42 C 423.39 153.94 425.82 161.76 427.46 169.76 C 429.15 178.07 430.01 186.52 430 195 C 430.01 203.48 429.15 211.93 427.46 220.24 C 425.82 228.24 423.39 236.06 420.2 243.58 C 413.9 258.45 404.79 271.95 393.36 283.36 C 381.95 294.79 368.45 303.9 353.58 310.2 C 346.06 313.39 338.24 315.82 330.24 317.46 C 321.93 319.15 313.48 320.01 305 320 C 296.52 320.01 288.07 319.15 279.76 317.46 C 271.76 315.82 263.94 313.39 256.42 310.2 C 241.55 303.9 228.05 294.79 216.64 283.36 C 205.21 271.95 196.1 258.45 189.8 243.58 C 186.61 236.06 184.18 228.24 182.54 220.24 C 180.85 211.93 179.99 203.48 180 195 Z M 13 490 L 13 413.148 L 126.148 300 L 203 376.852 L 89.852 490 L 13 490 Z M 205 160 L 405 160 L 405 230 L 205 230 L 205 160 Z',
249 fill: true,
250 fillRule: "evenodd",
251 stroke: 0
252 }
253 };
254 self.icons = {};
255 Object.keys(iconSources).forEach(iconName => {
256 let iconData = iconSources[iconName];
257 let svgIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
258 svgIcon.setAttribute('viewBox', iconData.viewbox);
259 svgIcon.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
260 svgIcon.classList.add('radix-icon');
261 svgIcon.classList.add('rdx-icon-' + iconName);
262 let iconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
263 iconPath.setAttribute('d', iconData.path);
264 if (iconData.fill) {
265 iconPath.setAttribute('fill', 'currentColor');
266 if (iconData.fillRule !== undefined) iconPath.setAttribute('fill-rule', iconData.fillRule);
267 } else {
268 iconPath.setAttribute('fill', 'none');
269 }
270 if (iconData.stroke === 0) {
271 iconPath.setAttribute('stroke', 'none');
272 } else {
273 iconPath.setAttribute('stroke', 'currentColor');
274 iconPath.setAttribute('stroke-linejoin', iconData.linejoin);
275 iconPath.setAttribute('stroke-linecap', iconData.linecap);
276 }
277 iconPath.setAttribute('stroke', 'none');
278 svgIcon.appendChild(iconPath);
279 self.icons[iconName] = svgIcon;
280 });
281 // hamburger Menu
282 let hmbgr = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
283 let hmbgrLine1 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
284 let hmbgrLine2 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
285 let hmbgrLine3 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
286 hmbgr.setAttribute('viewBox', '0 0 50 50');
287 hmbgr.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
288 hmbgr.classList.add('radix-icon');
289 hmbgr.classList.add('rdx-icon-hamburger');
290 hmbgrLine1.setAttribute('x1', 5);
291 hmbgrLine1.setAttribute('y1', 13);
292 hmbgrLine1.setAttribute('x2', 45);
293 hmbgrLine1.setAttribute('y2', 13);
294 hmbgrLine1.classList.add('bar1');
295 hmbgrLine2.setAttribute('x1', 5);
296 hmbgrLine2.setAttribute('y1', 25);
297 hmbgrLine2.setAttribute('x2', 45);
298 hmbgrLine2.setAttribute('y2', 25);
299 hmbgrLine2.classList.add('bar2');
300 hmbgrLine3.setAttribute('x1', 5);
301 hmbgrLine3.setAttribute('y1', 37);
302 hmbgrLine3.setAttribute('x2', 45);
303 hmbgrLine3.setAttribute('y2', 37);
304 hmbgrLine3.classList.add('bar3');
305 hmbgr.appendChild(hmbgrLine1);
306 hmbgr.appendChild(hmbgrLine2);
307 hmbgr.appendChild(hmbgrLine3);
308 self.icons.hamburger = hmbgr;
309 // svg insert
310 let iconCalls = document.querySelectorAll(self.option.icons.selector);
311 if (iconCalls) {
312 iconCalls.forEach(iconCall => {
313 let innerText = iconCall.textContent;
314 self.replaceIcon(iconCall, innerText);
315 });
316 }
317 }
318 resolve();
319 });
320 }).then(() => {
321 // Speed 2
322 return new Promise(resolve => {
323 // Smooth scroll and Fix external links
324 if (self.option.smoothScroll.active || self.option.fixExtLink.active) {
325 const links = document.querySelectorAll('a');
326 let scrollFrom = null;
327 let scrollTo = null;
328 links.forEach(link => {
329 if (!link.hasAttribute('href') || link.getAttribute('href').length == 0) {
330 link.setAttribute('href', '#');
331 }
332 let linkHref = link.getAttribute('href');
333 // Smooth scroll
334 if (self.option.smoothScroll.active) {
335 let firstLetter = linkHref.substring(0, 1);
336 let hrefTarget = linkHref.substring(1);
337 if (firstLetter === '#') {
338 link.addEventListener('click', event => {
339 event.preventDefault();
340 const target = hrefTarget.length > 0 ? document.getElementById(hrefTarget) : document.body;
341 const uniqueEasing = link.dataset.scrollEasing;
342 const uniqueDuration = link.dataset.scrollDuration;
343 const headerElm = !self.option.smoothScroll.header ? null : document.querySelector(self.option.smoothScroll.header);
344 const headerFixed = headerElm ? window.getComputedStyle(headerElm).getPropertyValue('position') : null;
345 const headerHeight = headerFixed === 'fixed' ? headerElm.offsetHeight : 0;
346 scrollFrom = window.scrollY;
347 scrollTo = window.scrollY + target.getBoundingClientRect().top - headerHeight;
348 self.smoothScroll(scrollFrom, scrollTo, uniqueDuration, uniqueEasing);
349 });
350 }
351 }
352 // Auto fill target blank
353 if (self.option.fixExtLink.active) {
354 let host = null;
355 if (linkHref.match(/.+\.pdf$/)) {
356 link.setAttribute('target', '_blank');
357 link.setAttribute('rel', 'noopener');
358 link.classList.add('rdx-pdf');
359 } else if (linkHref.match(/^http/)) {
360 host = window.location.hostname;
361 const linkHost = linkHref.replace(/\\/g, '/').match(/\/\/([^/]*)/)
362 if (host === '' || !!linkHost && linkHost[1] !== host) {
363 link.setAttribute('target', '_blank');
364 link.setAttribute('rel', 'noopener');
365 link.classList.add('rdx-extlink');
366 }
367 }
368 }
369 });
370 }
371 // Toggle menu
372 if (self.option.toggleNav.active && self.option.toggleNav.trigger !== '' && self.option.toggleNav.target !== '') {
373 self.navState = false;
374 let toggleTrigger = document.querySelectorAll(self.option.toggleNav.trigger);
375 toggleTrigger.forEach(t => {
376 t.addEventListener('click', () => { self.toggleNav(); });
377 });
378 }
379 // drag scroll
380 if (self.option.dragScroll.active && self.option.dragScroll.selector !== '') {
381 let dragScrollWrapper = Array.from(document.querySelectorAll(self.option.dragScroll.selector));
382 let scrollHint = document.createElement('div');
383 scrollHint.classList.add('rdx-drag-hint');
384 let scrollHintInner = document.createElement('div');
385 scrollHintInner.classList.add('rdx-drag-hint-inner');
386 scrollHint.appendChild(scrollHintInner);
387 scrollHintInner.innerHTML = '<div class="rdx-drag-hint-text">DRAG</div>';
388 scrollHintInner.prepend(self.icons.arrow_lr.cloneNode(true));
389 if (dragScrollWrapper.length > 0) {
390 dragScrollWrapper.forEach(e => {
391 e.style.overflow = 'auto';
392 e.style.position = 'relative';
393 e.addEventListener('mousedown', v => { self.dragDown(e, v) }, false);
394 if (e.scrollWidth > e.clientWidth && self.option.dragScroll.hint) {
395 e.appendChild(scrollHint.cloneNode(true));
396 e.addEventListener('scroll', () => {
397 let thisHint = e.querySelector('.rdx-drag-hint');
398 if (thisHint !== null) {
399 thisHint.classList.add('hide');
400 }
401 });
402 }
403 });
404 }
405 document.addEventListener('touchmove', v => { self.dragMove(v) }, false);
406 document.addEventListener('mousemove', v => { self.dragMove(v) }, false);
407 document.addEventListener('mouseup', v => { self.dragUp(v) }, false);
408 }
409 // flex fix
410 if (self.option.flexFix.active) {
411 let flexFix = document.querySelectorAll(self.option.flexFix.selector);
412 if (flexFix.length > 0) {
413 let inherit = self.option.flexFix.inherit;
414 flexFix.forEach(e => {
415 let childArr = Array.from(e.children);
416 let dummyChild = childArr[0].cloneNode(inherit);
417 dummyChild.classList.add('rdx-dummy-item');
418 let count = self.option.flexFix.min > childArr.length ? self.option.flexFix.min : childArr.length;
419 for (let i = 0; i < count; i++) {
420 let dummyClone = dummyChild.cloneNode(inherit);
421 e.appendChild(dummyClone);
422 }
423 });
424 }
425 }
426 // scroll appear
427 if (self.option.scrollAppear.active) {
428 const appearItems = document.querySelectorAll(self.option.scrollAppear.selector);
429 if (appearItems.length > 0) {
430 appearItems.forEach(item => {
431 item.classList.add('rdx-scroll-appear');
432 });
433 window.addEventListener('scroll', () => {
434 let windowHeight = window.innerHeight;
435 appearItems.forEach(appearItem => {
436 let resetFlg = appearItem.hasAttribute('data-appear-reset') ? appearItem.dataset.appearReset : self.option.scrollAppear.reset;
437 let activeClass = appearItem.hasAttribute('data-appear-class') ? appearItem.dataset.appearClass : self.option.scrollAppear.class;
438 let delay = appearItem.hasAttribute('data-appear-delay') ? appearItem.dataset.appearDelay : self.option.scrollAppear.delay;
439 let modeNum = appearItem.hasAttribute('data-appear-fixed') ? appearItem.dataset.appearFixed : null;
440
441 if (modeNum === null) {
442 let itemRect = appearItem.getBoundingClientRect();
443 let itemHeight = appearItem.offsetHeight;
444 if (itemRect.top < windowHeight * .9 && itemRect.top + itemHeight > windowHeight * .1) {
445 setTimeout(() => {
446 appearItem.classList.add(activeClass);
447 }, delay);
448 } else if (resetFlg) {
449 setTimeout(() => {
450 appearItem.classList.remove(activeClass);
451 }, delay);
452 }
453 } else {
454 if (window.pageYOffset > modeNum) {
455 setTimeout(() => {
456 appearItem.classList.add(activeClass);
457 }, delay);
458 } else if (resetFlg) {
459 setTimeout(() => {
460 appearItem.classList.remove(activeClass);
461 }, delay);
462 }
463 }
464 });
465 });
466 }
467 }
468 resolve();
469 });
470 }).then(() => {
471 // Speed 3
472 return new Promise(resolve => {
473 // modal
474 if (self.option.modal.active) {
475 let modals = document.querySelectorAll(self.option.modal.selector);
476 if (modals.length > 0) {
477 self.modalParts = {
478 viewport: document.createElement('div'),
479 area: document.createElement('div'),
480 wrapper: document.createElement('div'),
481 frame: document.createElement('div'),
482 content: document.createElement('div'),
483 closeButton: self.icons.cross.cloneNode(true),
484 toggles: document.createElement('div'),
485 magnifier: document.createElement('div'),
486 magnify: self.option.modal.magnify,
487 enlarge: self.icons.zoom_in.cloneNode(true),
488 shrink: self.icons.zoom_out.cloneNode(true),
489 scaleDisp: document.createElement('div'),
490 scaleSelector: document.createElement('ul'),
491 scale: self.option.modal.defaultScale,
492 size: {
493 width: 0,
494 height: 0
495 },
496 class: self.option.modal.class,
497 drag: self.option.modal.drag,
498 dragEvent: v => { self.dragDown(self.modalParts.wrapper, v) },
499 fit: self.option.modal.fit,
500 duration: self.option.modal.resizeDuration,
501 easing: self.option.modal.resizeEasing
502 }
503 self.modalParts.viewport.classList.add('rdx-modal-viewport');
504 self.modalParts.area.classList.add('rdx-modal-area');
505 self.modalParts.wrapper.classList.add('rdx-modal-wrapper');
506 self.modalParts.content.classList.add('rdx-modal-content');
507 self.modalParts.frame.classList.add('rdx-modal-frame');
508 self.modalParts.toggles.classList.add('rdx-modal-toggles');
509 self.modalParts.viewport.appendChild(self.modalParts.toggles);
510 self.modalParts.viewport.appendChild(self.modalParts.area);
511 self.modalParts.area.appendChild(self.modalParts.wrapper);
512 self.modalParts.wrapper.appendChild(self.modalParts.frame);
513 self.modalParts.frame.appendChild(self.modalParts.content);
514 self.modalParts.magnifier.classList.add('rdx-modal-magnifier');
515 self.modalParts.enlarge.classList.add('rdx-modal-enlarge');
516 self.modalParts.shrink.classList.add('rdx-modal-shrink');
517 self.modalParts.scaleDisp.classList.add('rdx-modal-scale');
518 self.modalParts.toggles.appendChild(self.modalParts.magnifier);
519 self.modalParts.magnifier.appendChild(self.modalParts.scaleDisp);
520 self.modalParts.magnifier.appendChild(self.modalParts.enlarge);
521 self.modalParts.magnifier.appendChild(self.modalParts.shrink);
522 self.modalParts.closeButton.classList.add('rdx-modal-close');
523 self.modalParts.toggles.appendChild(self.modalParts.closeButton);
524 self.modalParts.scaleSelector.classList.add('rdx-modal-scaler');
525 self.modalParts.magnifier.appendChild(self.modalParts.scaleSelector);
526 document.body.appendChild(self.modalParts.viewport);
527
528 self.modalParts.scaleDisp.addEventListener('click', event => {
529 event.preventDefault();
530 let i = self.option.modal.scaleStep.indexOf(self.modalParts.scale);
531 self.modalParts.scaleSelector.scrollTop = 40 * i;
532 self.modalParts.scaleSelector.classList.add('active');
533 });
534 self.option.modal.scaleStep.forEach(scale => {
535 let scaleItem = document.createElement('li');
536 scaleItem.innerHTML = self.floatRound(scale, 1) + 'x';
537 scaleItem.dataset.scale = scale;
538 self.modalParts.scaleSelector.appendChild(scaleItem);
539 scaleItem.addEventListener('click', event => {
540 event.preventDefault();
541 self.modalResize(scaleItem.dataset.scale);
542 self.modalParts.scale = scale;
543 });
544 });
545 self.modalParts.enlarge.addEventListener('click', event => {
546 event.preventDefault();
547 let i = self.option.modal.scaleStep.indexOf(self.modalParts.scale);
548 let aftScale = i < self.option.modal.scaleStep.length - 1 ? self.option.modal.scaleStep[i + 1] : self.option.modal.scaleStep[i];
549 self.modalResize(aftScale);
550 self.modalParts.scale = aftScale;
551 });
552 self.modalParts.shrink.addEventListener('click', event => {
553 event.preventDefault();
554 let i = self.option.modal.scaleStep.indexOf(self.modalParts.scale);
555 let aftScale = i > 0 ? self.option.modal.scaleStep[i - 1] : self.option.modal.scaleStep[i];
556 self.modalResize(aftScale);
557 self.modalParts.scale = aftScale;
558 });
559 modals.forEach(modal => {
560 let targets = [];
561 if (modal.hasAttribute('data-modal-target')) {
562 targets = document.querySelectorAll(modal.dataset.modalTarget);
563 if (targets) {
564 targets.forEach(target => {
565 target.classList.add('rdx-modal-source');
566 });
567 }
568 } else {
569 targets = [modal];
570 modal.classList.add('rdx-modal-source');
571 }
572 modal.addEventListener('click', event => {
573 event.preventDefault();
574 let duration = modal.hasAttribute('data-modal-duration') ? modal.dataset.modalDuration : null;
575 let easing = modal.hasAttribute('data-modal-easing') ? modal.dataset.modalEasing : null;
576 let scale = modal.hasAttribute('data-modal-scale') ? modal.dataset.modalScale : null;
577 let drag = modal.hasAttribute('data-modal-drag') ? modal.dataset.modalDrag : null;
578 let magnify = modal.hasAttribute('data-modal-magnify') ? modal.dataset.modalMagnify : null;
579 let fit = modal.hasAttribute('data-modal-fit') ? modal.dataset.modalFit : null;
580 let Class = modal.hasAttribute('data-modal-class') ? modal.dataset.modalClass : null;
581 let wrap = modal.hasAttribute('data-modal-wrap') ? modal.dataset.modalWrap : null;
582 self.modalOpen(targets, Class, duration, easing, scale, drag, magnify, fit, wrap);
583 });
584 });
585 self.modalParts.viewport.addEventListener('mouseup', event => {
586 let clicked = event.target;
587 if (!clicked.classList.contains('rdx-modal-item')) {
588 if (clicked.closest('.rdx-modal-content') === null && clicked.closest('.rdx-modal-toggles') === null) {
589 self.modalClose();
590 }
591 }
592 }, false);
593 self.modalParts.closeButton.addEventListener('click', () => { self.modalClose() }, false);
594 }
595 }
596 resolve();
597 });
598 }).then(() => {
599 // Speed 4
600 document.dispatchEvent(self.events.afterInitialize);
601 });
602 };
603 /**
604 * スムーススクロール
605 * @param {float} scrollFrom スクロールの始点
606 * @param {float} scrollTo スクロールの終点
607 * @param {int} duration スクロールにかける時間(ミリ秒)
608 * @param {string} easingName スクロールアニメーションのイージング
609 */
610 smoothScroll(scrollFrom, scrollTo, duration, easingName) {
611 const self = this;
612 scrollTo = scrollTo < 0 ? 0 : scrollTo;
613 const changeVal = scrollTo - scrollFrom;
614 duration = duration === undefined ? self.option.smoothScroll.duration : duration;
615 easingName = easingName === undefined ? self.option.smoothScroll.easing : easingName;
616 let easing = self.getEasing(easingName);
617 let cnt = 0;
618 let timer = null;
619
620 document.dispatchEvent(self.events.beforeScroll);
621
622 let moveAnimate = () => {
623 cnt++;
624 let elapsedTime = cnt * self.option.timeFrame;
625 let pos = easing(elapsedTime, scrollFrom, changeVal, duration);
626 window.scrollTo(0, pos);
627 if (elapsedTime > duration) {
628 window.scrollTo(0, scrollTo);
629 clearInterval(timer);
630 document.dispatchEvent(self.events.afterScroll);
631 }
632 }
633 timer = setInterval(moveAnimate, self.option.timeFrame);
634 };
635 /**
636 * ページスクロールのオンオフ
637 * @param {boolean} mode 禁止する(true)、禁止しない(false)
638 */
639 preventScroll(mode) {
640 this.DOM_ROOTS.forEach(e => {
641 if (mode) {
642 e.style.overflowY = 'hidden';
643 } else {
644 e.style.overflowY = 'initial';
645 }
646 });
647 };
648 /**
649 * ナビゲーション開閉
650 * @param {boolean | string} mode 開ける(false)か閉じる(true)か
651 */
652 toggleNav(mode) {
653 const self = this;
654 let toggleTrigger = document.querySelectorAll(self.option.toggleNav.trigger);
655 let toggleTarget = document.querySelectorAll(self.option.toggleNav.target);
656
657 if (mode === undefined) {
658 if (self.navState) {
659 document.dispatchEvent(self.events.beforeNavClose);
660 if (self.option.toggleNav.preventScroll) {
661 self.preventScroll(false);
662 }
663 self.navState = false;
664 toggleTrigger.forEach(t => {
665 t.classList.remove(self.option.toggleNav.class);
666 });
667 toggleTarget.forEach(t => {
668 t.classList.remove(self.option.toggleNav.class);
669 });
670 document.dispatchEvent(self.events.afterNavClose);
671 } else {
672 document.dispatchEvent(self.events.beforeNavOpen);
673 if (self.option.toggleNav.preventScroll) {
674 self.preventScroll(true);
675 }
676 self.navState = true;
677 toggleTrigger.forEach(t => {
678 t.classList.add(self.option.toggleNav.class);
679 });
680 toggleTarget.forEach(t => {
681 t.classList.add(self.option.toggleNav.class);
682 });
683 document.dispatchEvent(self.events.afterNavOpen);
684 }
685 } else {
686 if (mode === true || mode === 'close') {
687 document.dispatchEvent(self.events.beforeNavClose);
688 if (self.option.toggleNav.preventScroll) {
689 self.preventScroll(false);
690 }
691 self.navState = false;
692 toggleTrigger.forEach(t => {
693 t.classList.remove(self.option.toggleNav.class);
694 });
695 toggleTarget.forEach(t => {
696 t.classList.remove(self.option.toggleNav.class);
697 });
698 document.dispatchEvent(self.events.afterNavClose);
699 } else if (mode === false || mode === 'open') {
700 document.dispatchEvent(self.events.beforeNavOpen);
701 if (self.option.toggleNav.preventScroll) {
702 self.preventScroll(true);
703 }
704 self.navState = true;
705 toggleTrigger.forEach(t => {
706 t.classList.add(self.option.toggleNav.class);
707 });
708 toggleTarget.forEach(t => {
709 t.classList.add(self.option.toggleNav.class);
710 });
711 document.dispatchEvent(self.events.afterNavOpen);
712 }
713 }
714 };
715 /**
716 * SVG iconに置き換える
717 * @param {element} target SVGに置き換える対象
718 * @param {element} iconName アイコンの名前
719 */
720 replaceIcon(target, iconName) {
721 const self = this;
722 iconName = iconName === undefined ? target.innerText : iconName;
723 if (Object.keys(self.icons).includes(iconName)) {
724 target.replaceWith(self.icons[iconName].cloneNode(true));
725 } else {
726 console.log('' + iconName + ' is not icon name.');
727 }
728 };
729 /**
730 * ドラッグスクロールのマウスダウンイベント
731 * @param {elemnt} e スクロール領域のエレメント
732 * @param {event} v マウスダウンイベント
733 */
734 dragDown(e, v) {
735 if (!self.isMobile) {
736 e.style.cursor = 'move';
737 e.setAttribute('rdx-drag-on', true);
738 e.setAttribute('rdx-drag-scrolled-x', e.scrollLeft);
739 e.setAttribute('rdx-drag-scrolled-y', e.scrollTop);
740 e.setAttribute('rdx-drag-click-x', v.clientX);
741 e.setAttribute('rdx-drag-click-y', v.clientY);
742 }
743 };
744 /**
745 * ドラッグスクロールのマウスムーブイベント
746 * @param {event} v マウスムーブイベント
747 */
748 dragMove(v) {
749 let target = document.querySelector('[rdx-drag-on="true"]');
750 if (target !== null) {
751 v.preventDefault();
752 target.scrollLeft = Number(target.getAttribute('rdx-drag-scrolled-x')) + Number(target.getAttribute('rdx-drag-click-x')) - v.clientX;
753 target.scrollTop = Number(target.getAttribute('rdx-drag-scrolled-y')) + Number(target.getAttribute('rdx-drag-click-y')) - v.clientY;
754 }
755 };
756 /**
757 * ドラッグスクロールのマウスアップイベント
758 * @param {event} v マウスアップイベント
759 */
760 dragUp(v) {
761 v.preventDefault();
762 v.stopImmediatePropagation();
763 let target = document.querySelector('[rdx-drag-on="true"]');
764 if (target) {
765 target.style.cursor = '';
766 target.setAttribute('rdx-drag-on', false);
767 }
768 };
769 /**
770 * モーダルを開く
771 * @param {array} targets 開く対象のエレメントの配列
772 * @param {string} Class viewport に追加するCSSクラス
773 * @param {int} duration 拡縮にかける時間
774 * @param {string} easing 拡縮アニメーションのイージング
775 * @param {float} scale 開いたときの拡大率
776 * @param {boolean} drag ドラッグスクロールを可能にするか
777 * @param {boolean} magnify 拡縮ボタンを表示するか
778 * @param {boolean} fit 展開時にスケールを自動調整するか
779 * @param {boolean} wrap 折り返しモードで開くか
780 */
781 modalOpen(targets, Class, duration, easing, scale, drag, magnify, fit, wrap) {
782 const self = this;
783 if (self.modalState) return;
784 new Promise(resolve => {
785 document.dispatchEvent(self.events.beforeModalOpen);
786 resolve();
787 }).then(() => {
788 return new Promise(resolve => {
789 self.modalParts.content.innerHTML = '';
790 self.modalParts.magnify = magnify !== null ? magnify : self.option.modal.magnify;
791 self.modalParts.drag = drag !== null ? drag : self.option.modal.drag;
792 self.modalParts.fit = fit !== null ? fit : self.option.modal.fit;
793 self.modalParts.duration = duration === undefined ? self.option.modal.resizeDuration : duration;
794 self.modalParts.easing = easing === undefined ? self.option.modal.resizeEasing : easing;
795 self.modalParts.wrap = wrap === undefined ? self.option.modal.wrap : wrap;
796 let classArr = Class !== null ? Class : self.option.modal.class;
797 classArr = String(classArr).split(' ');
798 self.modalParts.class = classArr;
799 self.preventScroll(true);
800 resolve();
801 });
802 }).then(() => {
803 return new Promise(resolve => {
804 targets.forEach(target => {
805 let modalClone = target.cloneNode(true);
806 modalClone.classList.remove('rdx-modal-source');
807 modalClone.classList.add('rdx-modal-item');
808 self.modalParts.content.appendChild(modalClone);
809 });
810 resolve();
811 });
812 }).then(() => {
813 return new Promise(resolve => {
814 self.modalParts.magnifier.style.display = self.str2bool(self.modalParts.magnify) && !self.str2bool(self.modalParts.wrap) ? 'flex' : 'none';
815 self.modalParts.size = {
816 width: self.modalParts.content.offsetWidth,
817 height: self.modalParts.content.offsetHeight
818 };
819 resolve();
820 });
821 }).then(() => {
822 return new Promise(resolve => {
823 self.modalParts.scale = 1;
824 if (scale !== null) {
825 self.modalParts.scale = self.floatRound(scale, 1);
826 } else if (self.str2bool(self.modalParts.fit)) {
827 let areaHeight = self.modalParts.area.clientHeight;
828 let areaWidth = self.modalParts.area.clientWidth;
829 self.modalParts.scale = self.option.modal.scaleStep[0];
830 for (let i = 0; i < self.option.modal.scaleStep.length; i++) {
831 if (self.modalParts.size.width * self.option.modal.scaleStep[i] > areaWidth || self.modalParts.size.height * self.option.modal.scaleStep[i] > areaHeight) break;
832 self.modalParts.scale = self.option.modal.scaleStep[i];
833 }
834 }
835 if (self.str2bool(self.modalParts.drag) && !self.str2bool(self.modalParts.wrap)) {
836 self.modalParts.wrapper.addEventListener('mousedown', self.modalParts.dragEvent, false);
837 } else {
838 self.modalParts.wrapper.removeEventListener('mousedown', self.modalParts.dragEvent, false);
839 }
840 resolve();
841 });
842 }).then(() => {
843 return new Promise(resolve => {
844 if (self.str2bool(self.modalParts.wrap)) {
845 self.modalParts.content.style.maxHeight = '100%';
846 self.modalParts.content.style.maxWidth = '100%';
847 } else {
848 self.modalParts.content.style.transform = 'scale(' + self.modalParts.scale + ')';
849 self.modalParts.wrapper.style.height = 'min(' + self.floatCeil(self.modalParts.size.height * self.modalParts.scale, 0) + 'px, 100%)';
850 self.modalParts.wrapper.style.width = 'min(' + self.floatCeil(self.modalParts.size.width * self.modalParts.scale, 0) + 'px, 100%)';
851 self.modalParts.scaleDisp.innerHTML = self.floatRound(self.modalParts.scale, 1) + 'x';
852 self.modalParts.frame.style.height = self.floatCeil(self.modalParts.size.height * self.modalParts.scale, 0) + 'px';
853 self.modalParts.frame.style.width = self.floatCeil(self.modalParts.size.width * self.modalParts.scale, 0) + 'px';
854 }
855 self.modalParts.class.forEach(c => {
856 self.modalParts.viewport.classList.add(c);
857 });
858 self.modalParts.viewport.classList.add('active');
859 self.modalState = true;
860 resolve();
861 });
862 }).then(() => {
863 document.dispatchEvent(self.events.afterModalOpen);
864 });
865 };
866 /**
867 * モーダルを閉じる
868 */
869 modalClose() {
870 const self = this;
871 if (!self.modalState) return;
872 if (self.modalParts.wrapper.getAttribute('rdx-drag-on') === 'true') return;
873 new Promise(resolve => {
874 document.dispatchEvent(self.events.beforeModalClose);
875 resolve();
876 }).then(() => {
877 return new Promise(resolve => {
878 self.modalParts.scaleSelector.classList.remove('active');
879 self.modalParts.content.innerHTML = '';
880 self.preventScroll(false);
881 self.modalParts.content.style = '';
882 self.modalParts.frame.style = '';
883 self.modalParts.wrapper.style = '';
884 self.modalParts.viewport.classList.remove('active');
885 setTimeout(() => {
886 self.modalParts.class.forEach(c => {
887 self.modalParts.viewport.classList.remove(c);
888 });
889 }, 250);
890 self.modalState = false;
891 resolve();
892 });
893 }).then(() => {
894 document.dispatchEvent(self.events.afterModalClose);
895 });
896 };
897 /**
898 * モーダルウィンドウの拡縮
899 * @param {float} aftScale 操作後の倍率
900 */
901 modalResize(aftScale) {
902 const self = this;
903 if (!self.modalState) return;
904 let duration = self.option.modal.resizeDuration;
905 let frame = self.option.timeFrame;
906 let cnt = 0;
907 let timer = null;
908 let easing = self.getEasing(self.option.modal.resizeEasing);
909 let befScale = self.modalParts.scale;
910 let befWidth = self.modalParts.size.width * befScale;
911 let befHeight = self.modalParts.size.height * befScale;
912 aftScale = self.floatRound(aftScale, 1);
913 let aftWidth = self.modalParts.size.width * aftScale;
914 let aftHeight = self.modalParts.size.height * aftScale;
915 let difScale = aftScale - befScale;
916 let difWidth = self.modalParts.size.width * difScale;
917 let difHeight = self.modalParts.size.height * difScale;
918
919 self.modalParts.scaleDisp.innerHTML = self.floatRound(aftScale, 1) + 'x';
920 self.modalParts.scaleSelector.classList.remove('active');
921
922 let resizeAnimate = () => {
923 cnt++;
924 let elapsedTime = cnt * frame;
925 let nowWidth = easing(elapsedTime, befWidth, difWidth, duration);
926 let nowHeight = easing(elapsedTime, befHeight, difHeight, duration);
927 let nowScale = easing(elapsedTime, befScale, difScale, duration);
928 self.modalParts.content.style.transform = 'scale(' + nowScale + ')';
929 self.modalParts.wrapper.style.width = 'min(' + nowWidth + 'px, 100%)';
930 self.modalParts.wrapper.style.height = 'min(' + nowHeight + 'px, 100%)';
931 self.modalParts.frame.style.height = nowHeight + 'px';
932 self.modalParts.frame.style.width = nowWidth + 'px';
933 if (elapsedTime > duration) {
934 self.modalParts.content.style.transform = 'scale(' + self.floatRound(aftScale, 1) + ')';
935 self.modalParts.wrapper.style.height = 'min(' + self.floatCeil(aftHeight, 0) + 'px, 100%)';
936 self.modalParts.wrapper.style.width = 'min(' + self.floatCeil(aftWidth, 0) + 'px, 100%)';
937 self.modalParts.frame.style.height = self.floatCeil(aftHeight, 0) + 'px';
938 self.modalParts.frame.style.width = self.floatCeil(aftWidth, 0) + 'px';
939 clearInterval(timer);
940 }
941 }
942 if (difScale != 0) {
943 timer = setInterval(resizeAnimate, frame);
944 }
945 };
946 /**
947 * 型の判定
948 * @param {operand} obj 判定したいもの
949 * @return {string} 型名
950 */
951 typeJudge(obj) {
952 return toString.call(obj).slice(8, -1).toLowerCase();
953 };
954 /**
955 * 文字列のTF判定
956 * @param {string} str 判定したいもの
957 * @return {boolean}
958 */
959 str2bool(str) {
960 const trues = ['true', 'on', '1'];
961 if (str === true) return true;
962 if (trues.includes(String(str).toLocaleLowerCase())) return true;
963 return false;
964 };
965 /**
966 * 小数の桁変換
967 * @param {float} x 対象となる小数
968 * @param {int} digit 切り上げる小数点
969 * @return {string} フィックスされた小数文字列
970 */
971 floatRound(num, digit) {
972 digit = digit === undefined ? 2 : Number.parseInt(digit);
973 let fix = 10 ** digit;
974 let res = Math.round(num * fix) / fix;
975 return res.toFixed(digit);
976 };
977 floatCeil(num, digit) {
978 digit = digit === undefined ? 2 : Number.parseInt(digit);
979 let fix = 10 ** digit;
980 let res = Math.ceil(num * fix) / fix;
981 return res.toFixed(digit);
982 };
983 floatFloor(num, digit) {
984 digit = digit === undefined ? 2 : Number.parseInt(digit);
985 let fix = 10 ** digit;
986 let res = Math.floor(num * fix) / fix;
987 return res.toFixed(digit);
988 };
989 /**
990 * イージング関数を取得する関数
991 * @param {string} easingName イージング関数の名称
992 * @return {function} イージング関数
993 */
994 getEasing(easingName) {
995 let ease;
996 if (easingName == 'ease') {
997 easingName = 'easeInOutCirc';
998 } else if (easingName == 'ease-in' || easingName == 'easeIn') {
999 easingName = 'easeInQuad';
1000 } else if (easingName == 'ease-out' || easingName == 'easeOut') {
1001 easingName = 'easeOutQuad';
1002 } else if (easingName == 'ease-in-out' || easingName == 'easeInOut') {
1003 easingName = 'easeInOutQuad';
1004 }
1005 switch (easingName) {
1006 case 'linear':
1007 ease = function (t, b, c, d) {
1008 return c * t / d + b;
1009 };
1010 break;
1011 case 'easeInSine':
1012 ease = function (t, b, c, d) {
1013 return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
1014 };
1015 break;
1016 case 'easeOutSine':
1017 ease = function (t, b, c, d) {
1018 return c * Math.sin(t / d * (Math.PI / 2)) + b;
1019 };
1020 break;
1021 case 'easeInOutSine':
1022 ease = function (t, b, c, d) {
1023 return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
1024 };
1025 break;
1026 case 'easeInQuad':
1027 ease = function (t, b, c, d) {
1028 return c * (t /= d) * t + b;
1029 };
1030 break;
1031 case 'easeOutQuad':
1032 ease = function (t, b, c, d) {
1033 return -c * (t /= d) * (t - 2) + b;
1034 };
1035 break;
1036 case 'easeInOutQuad':
1037 ease = function (t, b, c, d) {
1038 if ((t /= d / 2) < 1) return c / 2 * t * t + b;
1039 return -c / 2 * ((--t) * (t - 2) - 1) + b;
1040 };
1041 break;
1042 case 'easeInCubic':
1043 ease = function (t, b, c, d) {
1044 return c * (t /= d) * t * t + b;
1045 };
1046 break;
1047 case 'easeOutCubic':
1048 ease = function (t, b, c, d) {
1049 return c * ((t = t / d - 1) * t * t + 1) + b;
1050 };
1051 break;
1052 case 'easeInOutCubic':
1053 ease = function (t, b, c, d) {
1054 if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
1055 return c / 2 * ((t -= 2) * t * t + 2) + b;
1056 };
1057 break;
1058 case 'easeInQuart':
1059 ease = function (t, b, c, d) {
1060 return c * (t /= d) * t * t * t + b;
1061 };
1062 break;
1063 case 'easeOutQuart':
1064 ease = function (t, b, c, d) {
1065 return -c * ((t = t / d - 1) * t * t * t - 1) + b;
1066 };
1067 break;
1068 case 'easeInOutQuart':
1069 ease = function (t, b, c, d) {
1070 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
1071 return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
1072 };
1073 break;
1074 case 'easeInQuint':
1075 ease = function (t, b, c, d) {
1076 return c * (t /= d) * t * t * t * t + b;
1077 };
1078 break;
1079 case 'easeOutQuint':
1080 ease = function (t, b, c, d) {
1081 return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
1082 };
1083 break;
1084 case 'easeInOutQuint':
1085 ease = function (t, b, c, d) {
1086 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
1087 return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
1088 };
1089 break;
1090 case 'easeInExpo':
1091 ease = function (t, b, c, d) {
1092 return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
1093 };
1094 break;
1095 case 'easeOutExpo':
1096 ease = function (t, b, c, d) {
1097 return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
1098 };
1099 break;
1100 case 'easeInOutExpo':
1101 ease = function (t, b, c, d) {
1102 if (t == 0) return b;
1103 if (t == d) return b + c;
1104 if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
1105 return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
1106 };
1107 break;
1108 case 'easeInCirc':
1109 ease = function (t, b, c, d) {
1110 return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
1111 };
1112 break;
1113 case 'easeOutCirc':
1114 ease = function (t, b, c, d) {
1115 return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
1116 };
1117 break;
1118 case 'easeInOutCirc':
1119 ease = function (t, b, c, d) {
1120 if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
1121 return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
1122 };
1123 break;
1124 case 'easeInElastic':
1125 ease = function (t, b, c, d) {
1126 var s = 1.70158;
1127 var p = 0;
1128 var a = c;
1129 if (t == 0) return b;
1130 if ((t /= d) == 1) return b + c;
1131 if (!p) p = d * .3;
1132 if (a < Math.abs(c)) {
1133 a = c;
1134 var s = p / 4;
1135 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
1136 return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
1137 };
1138 break;
1139 case 'easeOutElastic':
1140 ease = function (t, b, c, d) {
1141 var s = 1.70158;
1142 var p = 0;
1143 var a = c;
1144 if (t == 0) return b;
1145 if ((t /= d) == 1) return b + c;
1146 if (!p) p = d * .3;
1147 if (a < Math.abs(c)) {
1148 a = c;
1149 var s = p / 4;
1150 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
1151 return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
1152 };
1153 break;
1154 case 'easeInOutElastic':
1155 ease = function (t, b, c, d) {
1156 var s = 1.70158;
1157 var p = 0;
1158 var a = c;
1159 if (t == 0) return b;
1160 if ((t /= d / 2) == 2) return b + c;
1161 if (!p) p = d * (.3 * 1.5);
1162 if (a < Math.abs(c)) {
1163 a = c;
1164 var s = p / 4;
1165 } else var s = p / (2 * Math.PI) * Math.asin(c / a);
1166 if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
1167 return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
1168 };
1169 break;
1170 case 'easeInBack':
1171 ease = function (t, b, c, d, s) {
1172 if (s == undefined) s = 1.70158;
1173 return c * (t /= d) * t * ((s + 1) * t - s) + b;
1174 };
1175 break;
1176 case 'easeOutBack':
1177 ease = function (t, b, c, d, s) {
1178 if (s == undefined) s = 1.70158;
1179 return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
1180 };
1181 break;
1182 case 'easeInOutBack':
1183 ease = function (t, b, c, d, s) {
1184 if (s == undefined) s = 1.70158;
1185 if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
1186 return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
1187 };
1188 break;
1189 case 'easeInBounce':
1190 ease = function (t, b, c, d) {
1191 t = d - t;
1192 if ((t /= d) < (1 / 2.75)) {
1193 return c - c * (7.5625 * t * t) + b;
1194 } else if (t < (2 / 2.75)) {
1195 return c - c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
1196 } else if (t < (2.5 / 2.75)) {
1197 return c - c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
1198 } else {
1199 return c - c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
1200 }
1201 };
1202 break;
1203 case 'easeOutBounce':
1204 ease = function (t, b, c, d) {
1205 if ((t /= d) < (1 / 2.75)) {
1206 return c * (7.5625 * t * t) + b;
1207 } else if (t < (2 / 2.75)) {
1208 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
1209 } else if (t < (2.5 / 2.75)) {
1210 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
1211 } else {
1212 return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
1213 }
1214 };
1215 break;
1216 case 'easeInOutBounce':
1217 ease = function (t, b, c, d) {
1218 if (t < d / 2) {
1219 t = d - t * 2;
1220 if ((t /= d) < (1 / 2.75)) {
1221 return c * .5 - c * (7.5625 * t * t) * .5 + b;
1222 } else if (t < (2 / 2.75)) {
1223 return c * .5 - c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) * .5 + b;
1224 } else if (t < (2.5 / 2.75)) {
1225 return c * .5 - c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) * .5 + b;
1226 } else {
1227 return c * .5 - c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) * .5 + b;
1228 }
1229 } else {
1230 t = t * 2 - d;
1231 if ((t /= d) < (1 / 2.75)) {
1232 return c * (7.5625 * t * t) * .5 + c * .5 + b;
1233 } else if (t < (2 / 2.75)) {
1234 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) * .5 + c * .5 + b;
1235 } else if (t < (2.5 / 2.75)) {
1236 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) * .5 + c * .5 + b;
1237 } else {
1238 return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) * .5 + c * .5 + b;
1239 }
1240 }
1241 };
1242 break;
1243 }
1244 return ease;
1245 };
1246}
\No newline at end of file