气球平滑移动的两种实现方式(附代码)
<style>#papa {
margin: auto;
width: 740px;
height: 660px;
box-shadow: 3px 3px 24px #000;
position: relative;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background: green radial-gradient(at 35% 35%, lightgray, transparent);
box-shadow: inset -8px -8px 80px -8px tan;
border-radius: 50% 50% 25% 50%;
transform: rotate(45deg);
cursor: pointer;
}
.box::before {
position: absolute;
content: '';
width: 26px;
height: 6px;
border: 2px solid #663399;
border-radius: 0 0 50% 50% / 0 0 100% 100%;
border-top: none;
right: -20px;
bottom: 0;
}
</style>
<div id="papa">
<div class="box"></div>
</div>
<script>
let box = document.querySelector('.box');
let moveX = 0, moveY = 0, stepX = 1, stepY = 1.5, flag = true;
requestAnimationFrame(motion);
box.onclick = () => {
flag = !flag;
if(flag) requestAnimationFrame(motion);
}
function motion() {
if(!flag) return false;
moveX += stepX;
moveY += stepY;
box.style.left = moveX + 'px';
box.style.top = moveY + 'px';
requestAnimationFrame(motion);
if(moveX < 0 || moveX > papa.offsetWidth - box.offsetWidth) stepX = -stepX;
if(moveY < 0 || moveY > papa.offsetHeight - box.offsetHeight - 30) stepY = -stepY;
}
</script>
本帖最后由 马黑黑 于 2022-8-5 13:03 编辑
实现方式一:requestAnimationFrame
<style>
#papa {
margin: auto;
width: 1024px;
height: 660px;
box-shadow: 3px 3px 24px #000;
position: relative;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background: green radial-gradient(at 35% 35%, lightgray, transparent);
box-shadow: inset -8px -8px 80px -8px tan;
border-radius: 50% 50% 25% 50%;
transform: rotate(45deg);
cursor: pointer;
}
.box::before {
position: absolute;
content: '';
width: 26px;
height: 6px;
border: 2px solid #663399;
border-radius: 0 0 50% 50% / 0 0 100% 100%;
border-top: none;
right: -20px;
bottom: 0;
}
</style>
<div id="papa">
<div class="box"></div>
</div>
<script>
let box = document.querySelector('.box');
let moveX = 0, moveY = 0, stepX = 1, stepY = 1.5, flag = true;
requestAnimationFrame(motion);
box.onclick = () => {
flag = !flag;
if(flag) requestAnimationFrame(motion);
}
function motion() {
if(!flag) return false;
moveX += stepX;
moveY += stepY;
box.style.left = moveX + 'px';
box.style.top = moveY + 'px';
requestAnimationFrame(motion);
if(moveX < 0 || moveX > papa.offsetWidth - box.offsetWidth) stepX = -stepX;
if(moveY < 0 || moveY > papa.offsetHeight - box.offsetHeight - 30) stepY = -stepY;
}
</script>
实现方法二:setTimeout
将二楼标红的三行代码中红色部分替换为以下蓝色代码即可:
setTimeout(motion, 1000/60);
两种设置得到的效果都是差不多的吧?{:4_187:} 原理解释:
requestAnimationFrame 是利用屏幕的刷新率来实现动画,在 1000/60 即大约 16.7 毫秒以内变换元素形态,肉眼觉察不出这个时间内的动作变化过程,从而觉得元素的变化是连续的。
60是保守估算,因为现在的显示器刷新率最低也应该是60。
requestAnimationFrame 可以视为也是一个定时器,其时间间隔大约是 16.7,或者更低。
setTimeout 定时器是通过设定的间隔时间去执行元素的变化,1000/60 非常接近显示器一次刷新所用的时间,所以用这个间隔时间,setTimeout 也能达到非常接近于 requestAnimationFrame 的效果。
requestAnimationFrame不消耗CPU资源,页面最小化或被遮挡时停止运行;
setTimeout 消耗一定的CPU资源,页面最小化或不可见时依然执行任务,且容易受干扰从而偶尔有丢帧的现象。 红影 发表于 2022-8-5 13:12
两种设置得到的效果都是差不多的吧?
看五楼 不消耗CPU资源最好。 加林森 发表于 2022-8-5 14:45
不消耗CPU资源最好。
用setTimeout定时器消耗的也只是九牛一毛可以忽略不计 马黑黑 发表于 2022-8-5 19:05
用setTimeout定时器消耗的也只是九牛一毛可以忽略不计
哦,知道了。 加林森 发表于 2022-8-5 20:53
哦,知道了。
{:4_190:} 马黑黑 发表于 2022-8-5 13:18
看五楼
这个太专业了点。黑黑厉害{:4_187:} 红影 发表于 2022-8-5 22:13
这个太专业了点。黑黑厉害
去学习、研究,谁都可以略知一二 这个我好像一点看不懂{:4_201:} 继续看看,去实践一下看看 请求动画帧
“requestAnimationFrame字面意思:请求动画帧。官方解释:帧动画。就是可以一帧一帧的执行动画。 那么问题来了,这个一帧的执行频率是多久?答案是:与屏幕的刷新频率同步。 也可以认为:让浏览器在显示器屏幕下次刷新时,执行一帧;那么显示器多次刷新屏幕,就执行了多帧;如果速度够快,就会形成动画。 那么显示器的刷新屏幕,也就是屏幕的刷新频率又是什么呢?” 黑黑我平时就这么看。一点点理解的,没有办法 笨咋办{:4_201:} 小辣椒 发表于 2022-8-5 22:31
请求动画帧
“requestAnimationFrame字面意思:请求动画帧。官方解释:帧动画。就是可以一帧一帧的执行动画 ...
这个是requestAnimationFrame的工作原理解释。语法则是:
requestAnimationFrame(函数)
函数是自己编写的,比如让元素 id="box" 的元素左移:
let x = 0;
move(); //调用函数
function move() {
let x = x + 1;
if(x > 1000) x = 0; //1000像素后重来
box.style.left = x + 'px';
requestAnimationFrame(move); //递归调用本函数
}
这是简单的示例。
小辣椒 发表于 2022-8-5 22:32
黑黑我平时就这么看。一点点理解的,没有办法 笨咋办
能理解个大概就行。JS难度很大的。 马黑黑 发表于 2022-8-5 22:39
能理解个大概就行。JS难度很大的。
黑黑我把我加进去的代码发你在这里。你看看我错误在哪里 小辣椒 发表于 2022-8-5 22:50
黑黑我把我加进去的代码发你在这里。你看看我错误在哪里
两个HTML错误:
一、严重错误:重复使用 id="名称" 的盒子
<div id="papa">
<span id="tit">我想有个家--买得起这个房产吗</span>
<span id="ball"></span>
</div>
<div id="papa">
<img id="zlu " src="https://pic.imgdb.cn/item/62ecc29e8c61dc3b8e215099.gif" alt="" />
</div>
改为:
<div id="papa">
<img id="zlu" src="https://pic.imgdb.cn/item/62ecc29e8c61dc3b8e215099.gif" alt="" />
<span id="tit">我想有个家--买得起这个房产吗</span>
<span id="ball"></span>
</div>
注意:一切都是放在 papa 盒子内,而不是放在它之外。id="名称" 的东东,只能有一次。
二、小错误:红色部分多了一个空格
<img id="zlu " src="https://pic.imgdb.cn/item/62ecc29e8c61dc3b8e215099.gif" alt="" />
页:
[1]
2