时间:2023-01-07 09:28:33 | 栏目:vue | 点击:次
前几天在好朋友楼上小黑的介绍下,看到了某个平台的官网,里面有一个人物介绍的模块,里面的动画感觉不错,于是就自己动手写了一个。
当然这里去掉了具体信息,原网站是里面圆圈中是人物的头像,旁边是介绍信息,每个人物就沿着圆弧移动到指定位置
当点击中间开始时,几个小球一次转动到固定角度
要让小圆在圆弧上动,我们只需要知道圆心在圆弧上的坐标(x,y)就行了
所以当我们知道外圆的半径,小圆的半径,以及角度再利用三角函数就可以计算出 小圆在圆弧上定位的位置 top right
这里是将 移动的小圆封装成一个组件 moveRound,只需要将 大圆半径,小圆半径,转动的角度,剩下的就可以按自己需要添加
<template> <div> <h3>围绕圆弧移动动画</h3> <div class="arc_bo" > <move-round :minR="25" :bigR="150" :angle="30" ref="mRound1" > </move-round> <span class="start" @click="toMove" >开始</span> </div> </div> </template> <script> import moveRound from './components/moveRound.vue' export default { name: 'arcMoveAni', components: { moveRound }, methods: { toMove() { this.$refs.mRound1.toMove() } } } </script> <style scoped> .arc_bo{ margin: 0 auto; width: 6rem; height: 6rem; border-radius: 50%; border: 1px solid #ccc; position: relative; margin-top: 2rem; } .start{ position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); color: #f40; width: 1rem; height: 1rem; border-radius: 50%; border: 1px solid #ccc; text-align: center; line-height: 1rem; } </style>
moveRound组件, 角度的动态改变计算 top,right的值,其中 raf,caf是 requestAnimationFrame的兼容处理,不明白的可以看往期文章或者百度。
<template> <div> <div class="round" :style="setPosition" ></div> </div> </template> <script> let timer = 0 import { raf,caf } from '../../utils/raf' export default { name: 'moveRound', props: { angle: { // 需要转动的角度 type: Number, default: 0 }, bigR: { // 外层大圆半径 type: Number, default: 0 }, minR: { //移动小圆半径 type: Number, default: 0 }, backgroundColor: { type: String, default: '#7fffd4' } }, data() { return { top: '', right: '', setAngle: 0 } }, mounted() { }, computed: { /** * sin 对应 y 的值,转换为定位中距离顶部top等于 圆的半径 - y - 小圆半径(让圆心在圆弧上) * cos 对应 x 的值,转换为定位中距离右边right等于 圆的半径 - x - 小圆半径 * **/ setPosition( { top, right ,setAngle, bigR, minR, backgroundColor} ) { let size = minR*2 + 'px' let x = bigR * ( 1 - Math.cos(setAngle * Math.PI/180)) - minR let y = bigR * ( 1 - Math.sin(setAngle * Math.PI/180)) - minR right = x + 'px' top = y + 'px' return { top, right, width: size, height: size, backgroundColor } } }, methods: { toMove() { // 调整 累加值,改变速度 this.setAngle += 1 timer = raf(this.toMove) // 结束动画 if(this.setAngle > this.angle) { caf(timer) // 也可以根据需要重复执行 // this.setAngle = 0 } } } } </script> <style> .round{ position: absolute; will-change: top,right; border-radius: 50%; } </style>
主要的点就是根据角度计算位置,只要思路正确,应该可以少走弯路。