网站开发书,网站建设思路设计,dedecms行业协会网站织梦模板,网站开发用几种字体前言#xff1a; 今天遇到了一个有意思的需求#xff0c;如何实现一个元素绕某一个点来进行圆周运动#xff0c;用到了一些初高中的数学知识#xff0c;实现起来还是挺有趣的#xff0c;特来分享#x1f381;。
一. 效果展示 我们先展示效果#xff0c;如下图所示…前言 今天遇到了一个有意思的需求如何实现一个元素绕某一个点来进行圆周运动用到了一些初高中的数学知识实现起来还是挺有趣的特来分享。
一. 效果展示 我们先展示效果如下图所示放大镜会绕着我们设定好的一个圆心来进行圆周运动。相信这个需求还是比较常见的接下来我会一步一步讲解我的实现过程。 tisp: 注意放大镜是一张 png 的图片并不是我们手动画出来的
二. 回忆画圆的步骤 不要着急想代码如何实现我们先思考如何手动画一个圆在这里我们很容易想到一个初中学习数学用到的工具----圆规如下图所示。 从上图可以得知手动画一个圆其实很简单大致分为三个步骤。 确定圆心确定半径旋转圆规 前两个我们可以很轻松的根据我们的需求设定好圆心就是确定页面上的一个点坐标而已半径也是我们手动写死的一个变量值而已关键点其实就在于第三步我们如何实现。 在实现第三步之前我会提前预热一下弧度的知识因为等会我们需要用到 sin 和 cos 的相关知识而在 js 中的相关三角函数的参数必须为弧度所以我们需要通过角度来计算得出弧度。 我们大家都知道一个圆有360度且度数和弧度之间有一个转换公式如下。 得知了转换关系我们就可以定义一个变量 angle 来表示我们这个 div 做圆周运动时绕圆心转过的角度则弧度radian 为 radian angle*π/180
三. 回忆 sin 和 cos 我们先在草稿纸上演练一遍我们的逻辑是否可行。让我们先准备一个矩形来代表我们的页面然后确定一个点来作为圆心。 圆心的位置坐标其实很简单不要想复杂了就是相对于页面的位置而已我们记住这个 (100,100) 的值等会它会作为我们实现圆周运动的圆心位置。 接下来确定半径这里我就随便取一个 50 作为半径值。 假设这是我们的 div 已经绕圆心转了一些弧度以后的情景。 tips: 在这里有一个十分重要的概念div 滑过的路径其实是由无数个不同坐标位置的点构成的。 接下来就是本文的关键部分请大家喝口水认真听讲。我们取一个中间时刻假设 div 此时做圆周运动到了点 B 那么我们的问题就转化为了如何求点 B 的坐标信息。不要忘了坐标信息其实就是相对于页面上的 left 和 top 而已。 一步一步来我们先求 X 坐标的值换算下来其实就是要求 a 的长度。 此时我们准备好拿出已有的数据来套公式即可。度数我们是有的因为我们已经用变量 angle 来假设我们绕过的度数则弧度radian angle*π/180 然后根据三角函数的正弦定理可得 sin(rad)a/radius 。 此时半径已知sin(rad) 已知则 asin(rad) X 50然后加上圆心的 x 坐标值 100即可得出此时 B 点相对于页面的 left 值。 Y 坐标同理只不过公式换为 cos 即可换算过程不再重复但是需要注意的点是我们计算 Y 坐标 的目的其实在求的是 B 点的 top 值又因为我们前端的坐标Y轴其实和数学的坐标Y轴的正负极是相反的所以我们其实要算的值是这一段的距离。如下图 即 B 点的 top 值为圆心的 Y 坐标值100 - 距离b至此我们所有需要的数据都已经获得接下来就是用代码验证我们思路的可行性。
四. 实现圆周运动函数 经过上面的解释我们接下来就可以动手写代码了。 我们先简单设计一个画面内容很简单一个普通的蓝底页面中间有一个居中的红色 div要想脱离文档流自行移动那么这个 div 肯定是 absolute 绝对定位。 然后提前定义好我们需要用到的变量为接下来的工作做准备。 因为我们是需要不断通过改变 div 的 X 偏移值和 Y 偏移值来实现圆周运动的先不考虑性能和优化所以很容易想到 setInterval所以现在你的代码应该是这个样子。 // 1. 确定圆心的位置
const centerPointer { x: 100, y: 100 };
// 2. 确定圆周运动的半径
const radius 50;
// 3. div 运动时的角度
let angle 0;function run() {setInterval(() {}, 16);
}首先我们需要让我们定义好的 angle 自增。 function run() {setInterval(() {angle 1;}, 16);
}接下来计算 ab 的值根据我们上面的出的公式 radian angle*π/180和sin(rad)*radiusa可以写出下面的代码。 function run() {setInterval(() {angle 1;const radian (angle * Math.PI) / 180;const a Math.sin(radian) * radius;const b Math.cos(radian) * radius;}, 16);
}根据我们在上面的结论div 的top 值为 半径 a left 值为 半径 - b你现在的 run函数 代码应该是这样的。
function run() {setInterval(() {if (!box.value) return;angle 1;const radian (angle * Math.PI) / 180;const a Math.sin(radian) * radius;const b Math.cos(radian) * radius;const x centerPointer.x a;const y centerPointer.y - b;box.value.style.left x px;box.value.style.top y px;}, 16);
}然后给我们的 div 打上 ref 那到这个 dom 元素。 在 onMounted 里执行我们的 run 函数接下来就是见证奇迹的时刻。
五. 源码
script setup langts
import { ref, onMounted, } from vue;const box refHTMLDivElement();
// 1. 确定圆心的位置
const centerPointer { x: 100, y: 100 };
// 2. 确定圆周运动的半径
const radius 50;
// 3. div 运动时的角度
let angle 0;function run() {setInterval(() {if (!box.value) return;angle 1;const radian (angle * Math.PI) / 180;const a Math.sin(radian) * radius;const b Math.cos(radian) * radius;const x centerPointer.x a;const y centerPointer.y - b;box.value.style.left x px;box.value.style.top y px;}, 16);
}onMounted(() {run();
});
/script
templatediv classw-full h-full centered bg-blue relative flex flex-col centereddiv refbox classabsolute w-50px h-50px bg-red/div/div
/template
六. 思考题
现在我们的 div 是顺时针运动我们该如何让它逆时针运动呢