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 <!--...--> コメントタグの役割の詳細な分析

推薦する

ウェブサイトのコンテンツの100~1%はナビゲーションである

ウェブサイトでは、コンテンツの(100-1)%がナビゲーションです1. ジェシー・ジェームズ・ギャレ...

JavaScriptクロージャの原理と機能の詳細な説明

目次導入クロージャの使用カレー作りパブリック変数の実装キャッシュカプセル化(属性のプライベート化)閉...

Node.js コード実行をバイパスするためのヒントのまとめ

目次1. 子プロセス2. nodejsでのコマンド実行2.1 16進数エンコード2.2 ユニコードエ...

DOCTYPE 文書型宣言 (Web ページ愛好家必読)

DOCTYPE 宣言 作成するすべてのページの先頭に、ドキュメント宣言が必要です。はい、そうでしょう...

Linux で rc.local ファイルがない場合の完璧なソリューション

新しい Linux ディストリビューションには rc.local ファイルがなくなりました。サービス...

ローカル画像サーバーのNginx構成の実装

目次1. Nginx の紹介2. 画像サーバーの構築1. Nginx の紹介Nginx はリバース ...

Vue実装のカウンターケース

この記事では、カウンター表示を実現するためのVueの具体的なコードを例として紹介します。具体的な内容...

Mac VMware Fusion CentOS7 静的 IP 構成チュートリアル図

目次CentOS7をインストールする静的IPの設定viを使用してファイルを編集するCentOS7をイ...

Reactコンポーネントのライフサイクルの詳細な説明

目次1.ライフサイクルとは何か2. 読み込みプロセス1.コンストラクタ2. レンダリング3. コンポ...

ES9の新機能の詳細な説明: 非同期反復

目次非同期トラバーサル非同期反復可能トラバーサル非同期反復生成非同期メソッドと非同期ジェネレーター非...

WeChatアプレットで画像の幅と高さを取得する方法

起源最近、私は要件 A に取り組んでいます。そこには、次のように記述される小さな機能ポイントがありま...

Mysql は非集計列を選択できません

1. はじめに最近ブログをアップグレードし、記事ページの下部に前の記事と次の記事に直接ジャンプできる...

MySQLはパスワードなしでログインする例を実装しています

具体的な方法:ステップ1: mysqlサービスを停止する /etc/init.d/mysqld を停...

CSS スタイルの導入方法とその長所と短所の紹介

CSSを導入する3つの方法1. インラインスタイル利点: 書きやすく、重みがある 欠点: 構造とスタ...

Linux 7.6 バイナリに MySQL 8.0.27 をインストールする詳細な手順

目次1. 環境整備1.1 オペレーティング システムのバージョン1.2 ディスク容量1.3 ファイア...