ホームページ  >  記事  >  ウェブフロントエンド  >  ポイントアニメーション効果を実現するCSS

ポイントアニメーション効果を実現するCSS

青灯夜游
青灯夜游転載
2021-01-20 16:01:173645ブラウズ

ポイントアニメーション効果を実現するCSS

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

1. 全体的な考え方

まず、基本的な輪郭は、地球があり、その周りにいくつかのきらめく小さな星が半円を描き、そしてそれらが落ちていく、というものだと思います。同時に地球にも。 CSS の位​​置決め、border-radius を使用して円を描画し、アニメーション、クリック アクションで新しいアニメーションをトリガーし、ポイント増加効果は countUp.js に似ていますが、このプラグインはここでは使用されず、手動で実装されます。

(学習ビデオ共有: css ビデオ チュートリアル )

1.1 半円サラウンド エフェクト

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

this.integral.forEach(i => {
    // 角度转化为弧度
    let angle = Math.PI / 180 * this.getRandomArbitrary(90, 270)
    // 根据弧度获取坐标
    i.x = xAxis + 100 * Math.sin(angle)
    i.y = 100 + 100 * Math.cos(angle)
    // 贝塞尔函数
    i.timing = this.timeFun[parseInt(this.getRandomArbitrary(0, 3))]
})

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

// 求两个数之间的随机数
getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

timeFunc は、ベッセル関数名のコレクションです。データで定義された一体型フラッシュ (上下スライド) の効果を実現するには:

timeFun: ['ease', 'ease-in', 'ease-in-out', 'ease-out'], // 贝塞尔函数实现闪烁效果

1.2 ポイント フラッシュ (上下スライド)

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

.foo {
    display: flex;
    font-size: 10px;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    position: fixed;
    top: 0;
    left: 0;
    animation-name: slideDown;
    /*默认贝塞尔函数*/
    animation-timing-function: ease-out;
    /*动画时间*/
    animation-duration: 1500ms;
    /*动画循环播放*/
    animation-iteration-count: infinite;
    -moz-box-shadow: -5px -5px 10px 3px rgb(277, 102, 63) inset;
    -webkit-box-shadow: -5px -5px 10px 3px rgb(277, 102, 63) inset;
    box-shadow: -5px -5px 10px 3px rgb(277, 102, 63) inset;
}

/*小积分上下闪烁*/
@keyframes slideDown {
    from {
        transform: translateY(0);
    }
    50% {
        transform: translateY(5px);
        background-color: rgb(255, 234, 170);
    }
    to {
        transform: translateY(0);
        background: rgb(255, 202, 168);
    }
}

ポイントを上下に移動するだけでなく、それに応じて背景色も変更することに注意してください。上下の動きのペースを一定にしないと鈍く見えるため、乱数関数を使用してベッセル関数の 1 つをランダムに選択し、積分ボールが上下にスライドして不均一に見えるようにします。キーコードは次のとおりです。

/*html*/
{{item.value}}
/*js*/ // data中定义 timeFun: ['ease', 'ease-in', 'ease-in-out', 'ease-out'], // 贝塞尔函数实现闪烁效果 // 随机获取贝塞尔函数 i.timing = this.timeFun[parseInt(this.getRandomArbitrary(0, 3))]

1.3 合計ポイントの増加効果

クリックしてポイントを集めた後、合計ポイントがこれは countUp.js の効果に似ていますが、この機能についてはこのプラグインをここで引用することはできません。このプロジェクトでは vue.js を使用しており、データの応答属性を変更して数値を変更することは容易に考えられますが、これを一度に変更するのではなく、どのように徐々に変更するかが重要です。ここでの私のアイデアは、データ属性が突然変化しないように、一定の間隔でデータ属性を変更する Promise setTimeout です。

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

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

this.integralClass.fooClear = true
this.totalClass.totalAdd = true
this.totalText = `${this.totalIntegral}积分`
let count = this.integral.length, timeoutID = null, tasks = [], totalTime = parseInt(1500 / count)
const output = (i) => new Promise((resolve) => {
    timeoutID = setTimeout(() => {
        // 积分递增
        this.totalIntegral += this.integral[i].value
        // 修改响应式属性
        this.totalText = `${this.totalIntegral}积分`
        resolve();
    }, totalTime * i);
})
for (var i = 0; i < 5; i++) {
    tasks.push(output(i));
}
Promise.all(tasks).then(() => {
    clearTimeout(timeoutID)
})

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

最後のステップでは、小さな点が全体積分の方向に沿って移動して消え、全体積分が拡大します。

小さな積分は移動して消え、x 軸座標は全体積分の x 軸座標に移動し、y 軸は全体積分の y 軸座標に移動します。座標点は総積分と同じになるので、中心に沿った動きは同じように見えます。すべての微積分の座標がここに移動すると、データを削除できます。重要な CSS は次のとおりです:

.fooClear {
    animation-name: clearAway;
    animation-timing-function: ease-in-out;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
    -webkit-animation-duration: 1500ms;
    -moz-animation-duration: 1500ms;
    -o-animation-duration: 1500ms;
    animation-duration: 1500ms;
}

/*清除小的积分*/
@keyframes clearAway {
    to {
        top: 150px;
        left: 207px;
        opacity: 0;
        visibility: hidden;
        width: 0;
        height: 0;
    }
}

合計ポイントが拡張されます。ここでの実装アイデアは、transform:scale(1.5, 1.5); つまり、元のサイズより少し大きくして、最後に返すというものです。

.totalAdd {
    animation-name: totalScale;
    animation-timing-function: ease-in-out;
    /*动画只播放一次*/
    animation-iteration-count: 1;
    /*动画停留在最后一个关键帧*/
    animation-fill-mode: forwards;
    -webkit-animation-duration: 1500ms;
    -moz-animation-duration: 1500ms;
    -o-animation-duration: 1500ms;
    animation-duration: 1500ms;
}

@keyframes totalScale {
    50% {
        transform: scale(1.15, 1.15);
        -ms-transform: scale(1.15, 1.15);
        -moz-transform: scale(1.15, 1.15);
        -webkit-transform: scale(1.15, 1.15);
        -o-transform: scale(1.15, 1.15);
    }
    to {
        transform: scale(1, 1);
        -ms-transform: scale(1, 1);
        -moz-transform: scale(1, 1);
        -webkit-transform: scale(1, 1);
        -o-transform: scale(1, 1);
    }
}

ここまでで、アニメーション全体のロジックが明確になりましたので、まずはデモを書いてみましょう。アニメーションを統合するコードを github に置きました。

効果は次のとおりです:

2. プロジェクトに実装

最後に、プロジェクトに実装します。 、Ajax リクエストはポイントを収集するためのもので、Ajax リクエスト成功コールバックにアニメーションを入れるだけで完了です。主要な JS コードは次のとおりです。

// 一键领取积分
aKeyReceive() {
    if (this.unreceivedIntegral.length === 0) {
        return bottomTip("暂无未领积分")
    }
    if (this.userInfo.memberAKeyGet) {
        let param = {
            memberId: this.userInfo.memberId,
            integralIds: this.unreceivedIntegral.map(u => u.id).join(","),
            integralValue: this.unreceivedIntegral.reduce((acc, curr, index, arr) => { return acc + curr.value }, 0)
        }
        this.$refs.resLoading.show(true)
        api.getAllChangeStatus(param).then(res => {
            let data = res.data
            if (data.success) {
                this.getRecordIntegralList()
                this.playIntegralAnim()
            } else {
                bottomTip(data.message)
            }
        }).finally(() => {
            this.$refs.resLoading.show(false)
        })
    } else {
        this.$refs.refPopTip.show()
    }
},
// 领取积分的动画
playIntegralAnim() {
    this.integralClass.fooClear = true
    this.totalClass.totalAdd = true
    this.totalText = `${this.statisticsData.useValue}积分`
    let count = this.unreceivedIntegral.length, timeoutID = null, tasks = [], totalTime = parseInt(1500 / count)
    const output = (i) => new Promise((resolve) => {
        timeoutID = setTimeout(() => {
            this.statisticsData.useValue += this.unreceivedIntegral[i].value
            this.totalText = `${this.statisticsData.useValue}积分`
            resolve();
        }, totalTime * i);
    })
    for (let i = 0; i < count; i++) {
        tasks.push(output(i));
    }
    Promise.all(tasks).then(() => {
        clearTimeout(timeoutID)
    })
}

プロジェクトがオンラインになった後の最終的な効果は次のとおりです。

ページが点滅する理由に注意してください。これは、ajax リクエストがあるためです。サーバーが完全に信頼できる場合、ロード状態は実際には必要ありません。

最後に、読者の皆さんが同じようなニーズを持っている場合は、彼らから学びたいと思うかもしれません。より良いアイデアがある場合は、私の参考資料として提供してください。

プログラミング関連の知識について詳しくは、プログラミング学習をご覧ください。 !

以上がポイントアニメーション効果を実現するCSSの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。