CSSアニメーションでポイント獲得効果を実現するアイデアを詳しく解説

CSSアニメーションでポイント獲得効果を実現するアイデアを詳しく解説

最近のプロジェクトでは、ポイントを集める効果を作成する必要があります。 ボスの説明によると、この効果は Alipay Ant Forest でエネルギーを集めることに似ています。全体的な効果は、いくつかの不可欠な要素が木の周りに浮かんでいて、きらめく星のように上下にスライドしていることです。クリックしてそれらを受け取ると、それらは木の中心に沿ってスライドして消えます。木のエネルギーは徐々に増加し、最終的に拡大して少し大きくなります。

1. 全体的な考え方

最初に思い浮かぶ基本的な輪郭は、地球とその周りを半円状にきらめくいくつかの小さな星々が囲み、同時に地球に落ちてくるというものです。 CSS ポジショニング、円を描くための border-radius、アニメーション、およびクリック アクションを使用して新しいアニメーションをトリガーします。ポイント増分効果は countUp.js に似ていますが、このプラグインはここでは使用されず、手動で実装されます。

1.1 半円囲み効果

これには数学的な知識が必要で、角度に基づいてラジアンを取得し (ラジアン = 角度 * π/180)、積分要素が全体の積分を囲むように座標に変換する必要があります。キーコードは次のとおりです。

this.integral.forEach(i => {
    // 角度をラジアンに変換します。let angle = Math.PI / 180 * this.getRandomArbitrary(90, 270)
    // ラジアンに基づいて座標を取得します ix = xAxis + 100 * Math.sin(angle)
    iy = 100 + 100 * Math.cos(角度)
    // ベッセル関数 i.timing = this.timeFun[parseInt(this.getRandomArbitrary(0, 3))]
})

getRandomArbitrary() 関数の機能は、次のように乱数を取得することであることに注意してください。

// 2つの数値間の乱数を見つける getRandomArbitrary(min, max) {
    Math.random() * (max - min) + min を返します。
}

timeFuncは、積分点滅(上下にスライド)の効果を実現するためのベッセル関数名のセットです。

1.2 ポイントが点滅(上下にスライド)

CSS アニメーションを使用して、ポイントを上下にスライドさせます。ここで考えられる方法は、 transform: translateY(5px) です。これは、y 軸上で特定の距離を移動し、アニメーションをループで再生します。コードは次のとおりです。

.foo {
    ディスプレイ: フレックス;
    フォントサイズ: 10px;
    アイテムの位置を中央揃えにします。
    コンテンツの中央揃え: 中央;
    幅: 30ピクセル;
    高さ: 30px;
    位置: 固定;
    上: 0;
    左: 0;
    アニメーション名: slideDown;
    /*デフォルトのベッセル関数*/
    アニメーションタイミング関数: easy-out;
    /*アニメーション時間*/
    アニメーション期間: 1500ms;
    /*アニメーションループ再生*/
    アニメーションの反復回数: 無限;
    -moz-box-shadow: -5px -5px 10px 3px rgb(277, 102, 63) インセット;
    -webkit-box-shadow: -5px -5px 10px 3px rgb(277, 102, 63) インセット;
    ボックスシャドウ: -5px -5px 10px 3px rgb(277, 102, 63) インセット;
}

/*小さな積分が上下に点滅します*/
@keyframes スライドダウン {
    から {
        変換: translateY(0);
    }
    50% {
        変換: translateY(5px);
        背景色: rgb(255, 234, 170);
    }
    に {
        変換: translateY(0);
        背景: rgb(255, 202, 168);
    }
}

ポイントを上下に動かすだけでなく、それに応じて背景色も変更することに注意してください。

1.3 総得点増加効果

ポイントを受け取るためにクリックした後、合計ポイントが蓄積されます。これは countUp.js の効果に似ていますが、この機能にはこのプラグインは使用できません。このプロジェクトでは vue.js を使用しています。データのレスポンシブ プロパティを変更して数値を変更することは簡単に考えられます。重要なのは、変更を一度に行うのではなく、段階的に行う方法です。ここでの私のアイデアは、Promise + setTimeout で、データ属性を一定期間ごとに変更して、突然変更されたように見えないようにすることです。

アニメーション効果を滑らかに見せるために、合計時間(1500ミリ秒)を小さな積分の数で割ってアニメーションのキーフレームと同様の値を取得し、この値を変更回数として使用して、一定の間隔で実行します。全体的な効果が一定になるように、すべてのアニメーション時間は 1500 ミリ秒に設定されています。

キーコードは次のとおりです。

this.integralClass.fooClear = true
this.totalClass.totalAdd = true
this.totalText = `${this.totalIntegral} 積分`
count = this.integral.length、timeoutID = null、tasks = []、totalTime = parseInt(1500 / count) とします。
const 出力 = (i) => 新しい Promise((resolve) => {
    タイムアウトID = setTimeout(() => {
        // 積分を増分する this.totalIntegral += this.integral[i].value
        // レスポンシブプロパティを変更します this.totalText = `${this.totalIntegral} points`
        解決する();
    }, 合計時間 * i);
})
(var i = 0; i < 5; i++) の場合 {
    タスクをプッシュします(出力(i));
}
Promise.all(tasks).then(() => {
    タイムアウトをクリア(タイムアウトID)
})

1.4 小さなポイントが消え、合計ポイントが拡大する

最後のステップは、小さな積分が全積分の方向へ移動して消え、全積分が拡大することです。

小積分が移動して消え、x軸座標が全積分のx軸座標に移動し、y軸が全積分のy軸座標に移動します。実際には座標点が全積分と同じになるため、中心の方向に移動しているように見えます。すべての小積分の座標がここに移動すると、データを削除できます。主要な CSS は次のとおりです。

.fooクリア{
    アニメーション名: clearAway;
    アニメーションタイミング関数: easy-in-out;
    アニメーションの反復回数: 1;
    アニメーション塗りつぶしモード: forwards;
    -webkit アニメーション期間: 1500 ミリ秒;
    -moz-アニメーション期間: 1500ms;
    -o-アニメーション期間: 1500ms;
    アニメーション期間: 1500ms;
}

/* 小さな点をクリアする */
@keyframes をクリアする {
    に {
        上: 150px;
        左: 207px;
        不透明度: 0;
        可視性: 非表示;
        幅: 0;
        高さ: 0;
    }
}

合計スコアが拡大します。ここでの私の実装アイデアは、transform: scale(1.5, 1.5); です。つまり、元の基準で少し大きくなり、最終的に元のサイズに戻ります。transform: scale(1, 1);。重要な CSS は次のとおりです。

.合計追加{
    アニメーション名: totalScale;
    アニメーションタイミング関数: easy-in-out;
    /*アニメーションは1回だけ再生されます*/
    アニメーションの反復回数: 1;
    /*アニメーションは最後のキーフレームに留まります*/
    アニメーション塗りつぶしモード: forwards;
    -webkit アニメーション期間: 1500 ミリ秒;
    -moz-アニメーション期間: 1500ms;
    -o-アニメーション期間: 1500ms;
    アニメーション期間: 1500ms;
}

@keyframes 合計スケール {
    50% {
        変換: スケール(1.15, 1.15);
        変換後のサイズを 1.15 から 1.15 に変更します。
        スケールを 1.15 に設定します。
        -webkit-transform: スケール(1.15, 1.15);
        -o-変換: スケール(1.15, 1.15);
    }
    に {
        変換: スケール(1, 1);
        変換後のサイズを1から10までの範囲で指定します。
        スケールを1にするには、次のようにします。
        -webkit-transform: スケール(1, 1);
        -o-変換: スケール(1, 1);
    }
}

この時点で、アニメーション全体のロジックは整理されました。まずはデモを書いてみましょう。コードは github の points animation に置いてあります。

効果は以下のとおりです。

2. プロジェクトに実装する

最後に、プロジェクトにはポイントを収集するための Ajax リクエストが含まれています。この Ajax リクエストの成功コールバックにアニメーションを配置するだけで完了です。重要な js コードは次のとおりです。

// ワンクリックでポイントを受け取る aKeyReceive() {
    (this.unreceivedIntegral.length === 0)の場合{
        return bottomTip("まだポイントは獲得されていません")
    }
    if (this.userInfo.memberAKeyGet) {
        パラメータ = {
            メンバーID: this.userInfo.memberId、
            積分ID: this.unreceivedIntegral.map(u => u.id).join(","),
            積分値: this.unreceivedIntegral.reduce((acc, curr, index, arr) => { return acc + curr.value }, 0)
        }
        this.$refs.resLoading.show(true)
        api.getAllChangeStatus(param).then(res => {
            データ = res.data とします
            if (データ.成功) {
                this.getRecordIntegralList()
                this.playIntegralAnim()
            } それ以外 {
                ボトムチップ(データ.メッセージ)
            }
        }).finally(() => {
            this.$refs.resLoading.show(false)
        })
    } それ以外 {
        this.$refs.refPopTip.show()
    }
},
// ポイントを集めるアニメーション playIntegralAnim() {
    this.integralClass.fooClear = true
    this.totalClass.totalAdd = true
    this.totalText = `${this.statisticsData.useValue} ポイント`
    count = this.unreceivedIntegral.length、timeoutID = null、tasks = []、totalTime = parseInt(1500 / count) とします。
    const 出力 = (i) => 新しい Promise((resolve) => {
        タイムアウトID = setTimeout(() => {
            this.statisticsData.useValue += this.unreceivedIntegral[i].value
            this.totalText = `${this.statisticsData.useValue} ポイント`
            解決する();
        }, 合計時間 * i);
    })
    (i = 0 とします; i < count; i++) {
        タスクをプッシュします(出力(i));
    }
    Promise.all(tasks).then(() => {
        タイムアウトをクリア(タイムアウトID)
    })
}

プロジェクト開始後の最終的な効果は次のとおりです。

ここでページが点滅する理由は、Ajax リクエストに読み込み状態があるためであることに注意してください。実際、サーバーが完全に信頼できる場合は、これは不要です。

要約する

CSSアニメーションを使用してポイント獲得効果を実現するアイデアの詳細な説明については、これでこの記事を終了します。CSSでポイント獲得効果を実現する方法に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMを応援していただければ幸いです。

<<:  Dockerでホストファイルをカスタマイズする方法について簡単に説明します

>>:  HTML <!--...--> コメントタグの役割の詳細な分析

推薦する

FTP、FTPS、SFTPの違いについて簡単に説明します

目次FTP、FTPS、SFTP の概要FTP FTPS FTPサーバーFTPソフトウェアのアクティブ...

年末ですが、MySQL パスワードは安全ですか?

序文:年末です。データベースを検査する時期ではないでしょうか?一般的に、検査では、パスワードの複雑さ...

ウェブのさまざまなフロントエンド印刷方法: CSS はウェブページの印刷スタイルを制御します

CSS は Web ページの印刷スタイルを制御します。 CSS を使用して印刷スタイルを制御します。...

Bash スクリプトを使用して Linux のメモリ使用量を監視する方法

序文Linux システムのパフォーマンスを監視するために使用できるオープンソースの監視ツールが市場に...

IDEA は MySQL への接続時にエラーを報告します。サーバーが無効なタイムゾーンを返します。タブに移動して serverTimezone プロパティを設定してください。

これからの道は常に困難で、棘だらけです。歯を食いしばって、乗り越えられると信じてください。さあ、さあ...

JavaScript プロトタイプとプロトタイプチェーンの深い理解

目次1. プロトタイプとは何ですか? 2. プロトタイプ__プロト__ 4. コンストラクター5. ...

MySQL ページングクエリ最適化テクニック

ページング クエリを使用するアプリケーションでは、LIMIT と OFFSET を含むクエリが非常に...

Dockerボリュームコンテナ間のデータ共有の実装

ボリュームとは何ですか?ボリュームは英語で容量を意味し、Docker ではデータ ボリューム、つまり...

ウェブページのカスタム選択ボックス選択

選択ドロップダウン リスト フォームは誰もがよく知っているかもしれませんが、デフォルトのドロップダウ...

CSS で QR コードスキャンボックスを実装するためのサンプルコード

カメラを開くと通常はスキャンボックスが表示されますが、静的なQRコードではフォーカスを合わせたりスキ...

Linux で MySQL データベースのデータ ファイル パスを変更する手順

rpm インストール方法を使用して MySQL データベースをインストールした後、データ ファイルの...

JavaScript を使用してタイムラインとアニメーション効果を実装するためのサンプル コード (フロントエンドのコンポーネント化)

目次コードのクリーニングJavaScript の「フレーム」 「フレーム」の実装方法1. 間隔を設定...

HTML4とHTML5の違い: 入力にフォーカス実装コードを追加する方法

html4:コードをコピーコードは次のとおりです。 <フォーム> <p>&l...

Vueは動的に生成されたコンポーネントをドラッグアンドドロップする要件を実装します

目次製品要件アイデア問題ライブラリ選択をドラッグコンポーネントを生成する方法コンポーネントを生成する...

Linux で mysql-8.0.20 をインストールするための詳細なチュートリアル

** Linuxにmysql-8.0.20をインストールする**環境の紹介オペレーティングシステム:...