<div class="other-35" id="js-other-35">
<div class="section"><button class="button is-primary" id="js-other-35-button">プレゼント取得</button></div>
</div>
<div class="modal other-35__modal" id="js-other-35-modal">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box other-35__modal-box">
<div class="other-35__modal-loader" id="js-other-35-loader"></div>
<div class="other-35__modal-close">
<div class="content has-text-centered">
<p>取得が完了しました</p>
<p><button class="button" id="js-other-35-close">閉じる</button></p>
</div>
</div>
</div>
</div>
</div>
<script src="../../js/script.js"></script>
.other-35#js-other-35
.section
button.button.is-primary#js-other-35-button プレゼント取得
//- ローディングモーダル
.modal.other-35__modal#js-other-35-modal
.modal-background
.modal-content
.box.other-35__modal-box
.other-35__modal-loader#js-other-35-loader
.other-35__modal-close
.content.has-text-centered
p 取得が完了しました
p
button.button#js-other-35-close 閉じる
script(src=path('/js/script.js'))
{
"text": "テキストが入ります。テキストが入ります。テキストが入ります。"
}
'use strict';
import lottie, { AnimationItem } from 'lottie-web';
export const other35 = () => {
const other = new Other35();
other.init();
};
class Other35 {
el: HTMLElement;
loaderEl: HTMLElement;
buttonEl: HTMLElement;
modalEl: HTMLElement;
closeEl: HTMLElement;
lottieDataUrl: string;
lottie: AnimationItem;
// lottie: any;
isLoading: boolean;
isLoadingAnim: boolean;
constructor() {
this.el = document.getElementById('js-other-35');
this.loaderEl = document.getElementById('js-other-35-loader');
this.buttonEl = document.getElementById('js-other-35-button');
this.modalEl = document.getElementById('js-other-35-modal');
this.closeEl = document.getElementById('js-other-35-close');
if (location.origin === 'https://zakzakst.github.io') {
// GitHubの場合
this.lottieDataUrl =
'/parts/img/components/others/other35/present-2.json';
} else {
// ローカル環境の場合
this.lottieDataUrl = '/img/components/others/other35/present-2.json';
}
this.isLoading = false;
this.isLoadingAnim = true;
}
/**
* 初期化
*/
init() {
if (!this.el) return;
this.lottieInit();
this.onClickButton();
this.onClickClose();
}
/**
* lottie 初期化
*/
lottieInit() {
this.lottie = lottie.loadAnimation({
container: this.loaderEl,
renderer: 'svg',
loop: false,
autoplay: false,
path: this.lottieDataUrl,
});
// 何倍かの数値を設定。1は通常の速度
this.lottie.setSpeed(1.5);
// ループ完了時の処理
// @ts-ignore
this.lottie.onComplete = async () => {
if (!this.isLoading) {
// ロード完了している場合
if (this.isLoadingAnim) {
console.log('ループアニメーション終了');
// 一度完了アニメーションを表示
this.lottieFinishAnim();
this.isLoadingAnim = false;
} else {
console.log('完了アニメーション終了');
await this.delay(300);
this.setModalLoading(false);
}
} else {
this.lottieLoopAnim();
}
};
}
/**
* 開始アニメーション表示
*/
lottieStartAnim() {
this.lottie.playSegments([0, 20], true);
}
/**
* ループアニメーション表示
*/
lottieLoopAnim() {
this.lottie.playSegments([21, 90], false);
}
/**
* 完了アニメーション表示
*/
lottieFinishAnim() {
this.lottie.playSegments([91, 150], false);
}
/**
* 取得ボタンクリック時の挙動
*/
onClickButton() {
this.buttonEl.addEventListener('click', async () => {
if (this.isLoading) return;
this.isLoading = true;
this.isLoadingAnim = true;
this.setModalLoading(true);
this.showModal();
this.lottieStartAnim();
console.log('ロード開始');
await this.randomDelay(1000, 6000);
console.log('ロード完了');
this.isLoading = false;
});
}
/**
* 閉じるボタンボタンクリック時の挙動
*/
onClickClose() {
this.closeEl.addEventListener('click', async () => {
this.hideModal();
});
}
/**
* 指定の秒数待つ
* @param ms 待つミリ秒
* @returns Promiseインスタンス
*/
delay(ms: number = 1000) {
return new Promise((resolve) => {
return setTimeout(resolve, ms);
});
}
/**
* ランダムな秒数待つ
* @param minMs 待つミリ秒(最小値)
* @param maxMs 待つミリ秒(最大値)
* @returns Promiseインスタンス
*/
randomDelay(minMs: number = 1000, maxMs: number = 1000) {
const defaultDelay = 1000;
const delay =
minMs > maxMs
? defaultDelay
: Math.random() * (maxMs + 1 - minMs) + minMs;
console.log(`ランダムな秒数待つ:${delay}ms`);
return new Promise((resolve) => {
return setTimeout(resolve, delay);
});
}
/**
* モーダルを表示
*/
showModal() {
this.modalEl.classList.add('is-active');
}
/**
* モーダルを非表示
*/
hideModal() {
this.modalEl.classList.remove('is-active');
}
/**
* モーダルのロード状態を設定する
* @param loading ロード中かどうか(trueでロード中)
*/
setModalLoading(loading: boolean) {
if (loading) {
this.modalEl.classList.add('is-loading');
} else {
this.modalEl.classList.remove('is-loading');
}
}
}
$BLOCK_NAME: '.other-35';
// 変数
#{ $BLOCK_NAME } {
&__modal-box {
display: flex;
align-items: center;
justify-content: center;
width: 240px;
height: 240px;
margin: auto;
}
&__modal-loader {
display: none;
@at-root #{ $BLOCK_NAME }__modal.is-loading & {
display: block;
}
}
&__modal-close {
@at-root #{ $BLOCK_NAME }__modal.is-loading & {
display: none;
}
}
}
'use strict';
import lottie from 'lottie-web';
export const other35 = () => {
const other = new Other35();
other.init();
};
class Other35 {
el: HTMLElement;
loaderEl: HTMLElement;
buttonEl: HTMLElement;
modalEl: HTMLElement;
closeEl: HTMLElement;
lottieDataUrl: string;
lottie: any;
loaderInstanceName: string;
isLoading: boolean;
isLoadingAnim: boolean;
constructor() {
this.el = document.getElementById('js-other-35');
this.loaderEl = document.getElementById('js-other-35-loader');
this.buttonEl = document.getElementById('js-other-35-button');
this.modalEl = document.getElementById('js-other-35-modal');
this.closeEl = document.getElementById('js-other-35-close');
if (location.origin === 'https://zakzakst.github.io') {
// GitHubの場合
this.lottieDataUrl = '/parts/img/components/others/other35/present.json';
} else {
// ローカル環境の場合
this.lottieDataUrl = '/img/components/others/other35/present.json';
}
this.loaderInstanceName = 'other-35-loader';
this.isLoading = false;
this.isLoadingAnim = true;
}
/**
* 初期化
*/
init() {
if (!this.el) return;
this.lottieInit();
this.onClickButton();
this.onClickClose();
}
/**
* lottie 初期化
*/
lottieInit() {
this.lottie = lottie.loadAnimation({
container: this.loaderEl,
renderer: 'svg',
loop: false,
autoplay: false,
path: this.lottieDataUrl,
// アニメーションインスタンスに名前を渡して、後でlottieコマンドで参照することができる
name: this.loaderInstanceName,
initialSegment: [0, 100],
});
// 何倍かの数値を設定。1は通常の速度
this.lottie.setSpeed(2.5, this.loaderInstanceName);
// ループ完了時の処理
this.lottie.onComplete = async () => {
if (!this.isLoading) {
// ロード完了している場合
if (this.isLoadingAnim) {
console.log('ループアニメーション終了');
// 一度完了アニメーションを表示
this.lottieFinishAnim();
this.isLoadingAnim = false;
} else {
console.log('完了アニメーション終了');
await this.delay(300);
this.setModalLoading(false);
}
} else {
this.lottieLoopAnim();
}
};
}
/**
* ループアニメーション表示
*/
lottieLoopAnim() {
this.lottie.playSegments([0, 100], true);
}
/**
* 完了アニメーション表示
*/
lottieFinishAnim() {
this.lottie.playSegments([101, 186], true);
}
/**
* 取得ボタンクリック時の挙動
*/
onClickButton() {
this.buttonEl.addEventListener('click', async () => {
if (this.isLoading) return;
this.isLoading = true;
this.isLoadingAnim = true;
this.setModalLoading(true);
this.showModal();
this.lottieLoopAnim();
console.log('ロード開始');
await this.randomDelay(5000, 10000);
console.log('ロード完了');
this.isLoading = false;
});
}
/**
* 閉じるボタンボタンクリック時の挙動
*/
onClickClose() {
this.closeEl.addEventListener('click', async () => {
this.hideModal();
});
}
/**
* 指定の秒数待つ
* @param ms 待つミリ秒
* @returns Promiseインスタンス
*/
delay(ms: number = 1000) {
return new Promise((resolve) => {
return setTimeout(resolve, ms);
});
}
/**
* ランダムな秒数待つ
* @param minMs 待つミリ秒(最小値)
* @param maxMs 待つミリ秒(最大値)
* @returns Promiseインスタンス
*/
randomDelay(minMs: number = 1000, maxMs: number = 1000) {
const defaultDelay = 1000;
const delay =
minMs > maxMs
? defaultDelay
: Math.random() * (maxMs + 1 - minMs) + minMs;
console.log(`ランダムな秒数待つ:${delay}ms`);
return new Promise((resolve) => {
return setTimeout(resolve, delay);
});
}
/**
* モーダルを表示
*/
showModal() {
this.modalEl.classList.add('is-active');
}
/**
* モーダルを非表示
*/
hideModal() {
this.modalEl.classList.remove('is-active');
}
/**
* モーダルのロード状態を設定する
* @param loading ロード中かどうか(trueでロード中)
*/
setModalLoading(loading: boolean) {
if (loading) {
this.modalEl.classList.add('is-loading');
} else {
this.modalEl.classList.remove('is-loading');
}
}
}