当前位置: 首页 > news >正文

在UniApp中css实现蚂蚁森林点击抖动效果的完整指南

前言
蚂蚁森林的点击互动动画是提升用户参与感的经典设计。本文通过 UniApp + Vue3 技术栈,结合 CSS 关键帧动画 ,实现高度还原的小树点击抖动效果。

一、效果演示
点击小树后触发连贯动画:

树木呈现弹性缩放效果(Y轴拉伸)
伴随轻微水平位移的拟真抖动
动画结束后平滑恢复初始状态
二、核心实现原理

  1. 动画关键帧设计
    通过 scaleY 纵向缩放模拟拉伸,scaleX 横向补偿形变,结合多阶段关键帧实现弹性效果:

CSS

@keyframes growBounceTree {0% { transform: scaleX(1) scaleY(1); }       /* 初始状态 */18% { transform: scaleX(1.04) scaleY(1.18); } /* 最大拉伸 */30% { transform: scaleX(0.98) scaleY(1.08); } /* 回弹阶段1 */45% { transform: scaleX(1.03) scaleY(1.13); } /* 二次拉伸 */60% { transform: scaleX(0.99) scaleY(1.06); } /* 回弹阶段2 */75% { transform: scaleX(1.01) scaleY(1.10); } /* 微调拉伸 */100% { transform: scaleX(1) scaleY(1); }     /* 恢复原点 */
}
  1. 动画绑定与触发
    通过 Vue 响应式状态控制动画类名切换:

HTML

<image class="tree-img" :class="{ shake: isShaking }" @click="shakeTree" @animationend="isShaking = false"
/>

JavaScript

const isShaking = ref(false)
const shakeTree = () => {if (!isShaking.value) isShaking.value = true
}

三、关键技术细节

  1. 形变中心点控制
    通过 transform-origin: 50% 100% 设置形变基准点为树木底部,模拟真实植物生长效果:

CSS

.tree-img {transform-origin: 50% 100%; /* x轴居中,y轴底部对齐 */
}
  1. 动画性能优化
    开启 GPU 加速:添加 will-change: transform 提示浏览器预优化
    复合动画曲线:使用默认 ease-out 曲线实现自然回弹
    避免重复渲染:动画结束后立即移除类名减少内存占用
    四、完整实现代码
    HTML
<template><view class="tree-demo-container"><image class="tree-img" src="https://p6.itc.cn/q_70/images03/20220108/4fa1d2e8006140fb838fcda2a61259f3.jpeg":class="{ shake: isShaking }" @click="shakeTree" @animationend="isShaking = false" mode="widthFix" /><view class="tip-text">点击小树体验抖动效果</view></view>
</template><script lang="ts" setup>
import { ref } from 'vue'
const isShaking = ref(false)
const shakeTree = () => {if (!isShaking.value) isShaking.value = true
}
</script><style lang="scss" scoped>
.poster-container {padding: 20rpx;display: flex;flex-direction: column;align-items: center;
}.poster-preview {margin: 30rpx auto;width: 100%;display: flex;flex-direction: column;align-items: center;
}.poster-image {width: 100%;box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);border-radius: 20rpx;
}/* 新增树动画样式 */
// .tree-img {
//     width: 160rpx;
//     height: 220rpx;
//     margin-bottom: 30rpx;
//     transition: transform 0.1s;
//     /* 以底部为中心进行缩放和晃动 */
//     transform-origin: 50% 100%;
// }// .shake {
//     animation: growBounceTree 0.7s;
//     transform-origin: 50% 100%;
// }// @keyframes growBounceTree {
//     0% {
//         transform: scaleX(1) scaleY(1) translateY(0);
//     }//     20% {
//         transform: scaleX(1.05) scaleY(1.18) translateY(-18rpx);
//     }//     35% {
//         transform: scaleX(0.98) scaleY(1.08) translateY(-10rpx);
//     }//     50% {
//         transform: scaleX(1.03) scaleY(1.13) translateY(-14rpx);
//     }//     65% {
//         transform: scaleX(0.99) scaleY(1.06) translateY(-7rpx);
//     }//     80% {
//         transform: scaleX(1.01) scaleY(1.10) translateY(-10rpx);
//     }//     100% {
//         transform: scaleX(1) scaleY(1) translateY(0);
//     }
// }.poster-image {width: 100%;box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);border-radius: 20rpx;/* 新增动画相关属性 */transform-origin: 50% 100%;/* 你可以在JS中动态加shake类来触发动画 */
}.shake {animation: growBounceTree 0.7s;transform-origin: 50% 100%;
}@keyframes growBounceTree {0% {transform: scaleX(1) scaleY(1);}18% {transform: scaleX(1.04) scaleY(1.18);}30% {transform: scaleX(0.98) scaleY(1.08);}45% {transform: scaleX(1.03) scaleY(1.13);}60% {transform: scaleX(0.99) scaleY(1.06);}75% {transform: scaleX(1.01) scaleY(1.10);}100% {transform: scaleX(1) scaleY(1);}
}.canvas-container {position: fixed;left: -9999px;top: -9999px;z-index: -1;
}.poster-canvas {width: 750px;height: 1200px;
}.action-buttons {margin-top: 40rpx;width: 100%;padding: 0 30rpx;
}.save-btn,
.share-btn {margin-top: 30rpx;
}

五、高级扩展技巧

  1. 复合抖动效果
    在现有动画基础上增加水平位移:

CSS

@keyframes growBounceTree {0% { transform: translateX(0) scaleX(1) scaleY(1); }18% { transform: translateX(-3px) scaleX(1.04) scaleY(1.18); }/* ...其余关键帧同步调整... */
}
  1. 移动端优化方案
    禁用点击高亮:
    CSS
.tree-img {-webkit-tap-highlight-color: transparent;
}

添加触觉反馈(需调用设备API)
性能分级策略:低端设备减少动画阶段
3. 音效同步播放
JavaScript

const playSound = () => {const audio = uni.createInnerAudioContext()audio.src = '/static/shake-sound.mp3'audio.play()
}const shakeTree = () => {if (!isShaking.value) {isShaking.value = trueplaySound()}
}

六、常见问题排查
现象 解决方案
动画卡顿 检查是否缺少 will-change 或 transformZ(0)
iOS 无效果 确认 HBuilderX 版本 ≥3.4.10
点击无响应 检查图片是否添加 @click 事件绑定
形变位置错误 确认 transform-origin 值是否正确

相关文章:

  • [Linux]多线程(二)原生线程库---pthread库的使用
  • JVM——即时编译器的中间表达形式
  • LVGL图像导入和解码
  • vllm笔记
  • 《基于人工智能的智能客服系统:技术与实践》
  • Python 包管理新选择:uv
  • 栈溢出攻击最基本原理
  • MySQL 1366 - Incorrect string value:错误
  • 采用SqlSugarClient创建数据库实例引发的异步调用问题
  • 动态规划:最长递增子序列
  • Python企业级OCR实战开发:从基础识别到智能应用
  • JMeter 中实现 双 WebSocket(双WS)连接
  • 前端EXCEL插件,智表ZCELL产品V3.0 版本发布,底层采用canvas全部重构,功能大幅扩展,性能极致提升,满足千万级单元格加载
  • openlayers利用已知的三个经纬度的坐标点 , 绘制一个贝塞尔曲线
  • JDBC执行sql过程
  • Unity.UGUI DrawCall合批笔记
  • onGAU:简化的生成式 AI UI界面,一个非常简单的 AI 图像生成器 UI 界面,使用 Dear PyGui 和 Diffusers 构建。
  • 移动零--双指针
  • 【Java ee初阶】网络原理
  • P1725 琪露诺
  • “科创板八条”后百单产业并购发布,披露交易金额超247亿
  • 欧盟公布关税反制清单,瞄准美国飞机、汽车等产品
  • 广州下调个人住房公积金贷款利率
  • 圆桌丨权威专家解读中俄关系:在新形势下共同应对挑战、共创发展机遇
  • 两国战机均未侵入对方领空,巴方公布对印回击细节
  • 用社群活动维系“不开发”古镇的生命力