JavaScript-动画原理如何使用js进行动画效果的实现
Posted Aic山鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript-动画原理如何使用js进行动画效果的实现相关的知识,希望对你有一定的参考价值。
目录
前言
动画对于我们来说都不陌生,css里面就有很多动画,2d,3d等各种动画,本篇主要是如何使用js实现动画效果,如果本篇文章对你有帮助,点赞支持一下吧!
1.动画原理
1.获得盒子当前位置
2.让盒子在当前位置加上1个移动距离
3.利用定时器不断重复这个操作
4.加一个结束定时器的条件
5.注意该元素需要添加定位,才能使用element.style.left
<body>
<div>
</div>
<script>
var div = document.querySelector('div');
var timer = setInterval(function ()
if (div.offsetLeft >= 500)
clearInterval(timer);
div.style.left = div.offsetLeft + 2 + 'px';
, 30)
</script>
</body>
主要核心就是利用定时器进行动画的实现
2.动画函数的封装
<script>
// 简单动画函数封装
function animate(obj, rug)
var timer = setInterval(function ()
if (obj.offsetLeft >= rug)
clearInterval(timer);
obj.style.left = obj.offsetLeft + 2 + 'px';
, 30)
var div = document.querySelector('div');
animate(div,300);
</script>
把这个动画封装成一个函数,方便以后的使用,该封装函数里的obj是哪个元素要进行动画的实现rug是该元素要移动多少距离
3.给不同元素添加定时器
<body>
<div>
</div>
<button>点击走</button>
<script>
// 简单动画函数封装
// 给不同元素添加定时器
function animate(obj, rug)
clearInterval(obj.timer);
obj.timer = setInterval(function ()
if (obj.offsetLeft >= rug)
clearInterval(obj.timer);
else
obj.style.left = obj.offsetLeft + 2 + 'px';
, 30)
var div = document.querySelector('div');
var but = document.querySelector('button');
but.addEventListener('click', function ()
animate(div, 200);
)
</script>
这样就能实现多个元素进行动画的使用了,并且每个元素都有属于自己的定时器
4.缓动动画原理
公式:目标值-现在的位置/10 ,作为每次的移动距离
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: pink;
</style>
</head>
<body>
<button>点击</button>
<div></div>
<script>
function animate(obj, rug)
clearInterval(obj.timer);
obj.timer = setInterval(function ()
// 步长值
var step = (rug - obj.offsetLeft) / 10;
if (obj.offsetLeft == rug)
clearInterval(obj.timer);
else
obj.style.left = obj.offsetLeft + step + 'px';
, 15)
var div = document.querySelector('div');
var but = document.querySelector('button');
but.addEventListener('click', function ()
animate(div, 500);
)
</script>
</body>
</html>
5.给动画添加回调函数
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面 ,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
当跑完800米后,会弹出一个框“hello”,这个就是在执行完800米这个动画后再次进行的函数,这就是回调函数
6.动画函数的使用
实现侧边栏滑动效果
当鼠标经过slider就会让con这 个盒子滑动到左侧
当鼠标离开slider就会让con这 个盒子滑动到右侧
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./js/animate.js"></script>
<style>
.silder
margin-left: 1600px;
text-align: center;
position: relative;
line-height: 100px;
width: 100px;
height: 100px;
background-color: aqua;
span
.con
position: absolute;
top: 0;
left: 0;
z-index: -1;
width: 200px;
height: 100px;
background-color: rgb(132, 0, 255);
</style>
</head>
<body>
<div class="silder">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var silder = document.querySelector('.silder');
var con = document.querySelector('.con');
var span = document.querySelector('span');
silder.addEventListener('mouseenter', function ()
animate(con, -200, function ()
span.innerHTML = '→';
);
)
silder.addEventListener('mouseleave', function ()
animate(con, 0, function ()
span.innerHTML = '←';
);
)
</script>
</body>
</html>
function animate(obj, rug, callback)
clearInterval(obj.timer);
obj.timer = setInterval(function ()
// 步长值
// var step = Math.ceil((rug - obj.offsetLeft) / 10);
var step = (rug - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == rug)
clearInterval(obj.timer);
if (callback)
callback();
else
obj.style.left = obj.offsetLeft + step + 'px';
// 回调函数写道计时器结束里
, 15)
写在最后
我是Aic山鱼,感谢您的支持
原 创 不 易 ✨还希望支持一下
点赞👍:您的赞赏是我前进的动力!
收藏⭐:您的支持我是创作的源泉!
评论✍:您的建议是我改进的良药!
山鱼🦈社区:山鱼社区💌💌希望三连下👍⭐✍支持一下博主🌊
JavaScript动画相关
JS动画原理
通过CSS缓慢变化从而实现动画效果
获取css属性
Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。
Demo box斜线运动
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box { width: 20px; height: 20px; background-color: black; position: absolute; /*必须要有定位才能实现动画效果*/ left: 0; right: 0; } </style> </head> <body> <div class="box"></div> <script> var speedx = 3; // 设置每次移距离 var speedy = 3; // 设置每次移距离 var dv = document.getElementsByClassName("box")[0]; // 获取要移动的元素 这里使用的是ClassName 所以需要索引取出element_obj function move(el) { // 创建移动函数
var currentleft = parseInt(window.getComputedStyle(el).left); //实时获取当前标签的left距离并转化为int类型 var currenttop = parseInt(window.getComputedStyle(el).top); //实时获取当前标签的top距离并转化为int类型 var left = currentleft + speedx; //进行动态数据计算 var top = currenttop + speedy; //进行动态数据计算 el.style.left = `${left}px`; //通过style属性实时更改数据量 el.style.top = `${top}px`;//通过style属性实时更改数据量 } setInterval(function () { //设置定时任务 move(dv) },20) </script> </body> </html>
获取浏览器的宽/高
window.innerWidth
window.innerHeight
Demo box斜线运动边缘碰撞改良版
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box { width: 20px; height: 20px; background-color: black; position: absolute; left: 0; right: 0; overflow: hidden; } </style> </head> <body> <div class="box"></div> <script> var speedx = 3; var speedy = 3; var dv = document.getElementsByClassName("box")[0]; function move(el) { var style = window.getComputedStyle(el); var currentleft = parseInt(style.left); var currenttop = parseInt(style.top);
check_border_collision(el); var left = currentleft + speedx; var top = currenttop + speedy; el.style.left = `${left}px`; el.style.top = `${top}px`; } function check_border_collision(el) { // 矫正函数 var style = window.getComputedStyle(el); // 获取box对象css属性 var left = parseInt(style.left); // 获取当前左边距 var top = parseInt(style.top); // 获取当前下距离 var w = parseInt(style.width); // 获取元素宽度 var h = parseInt(style.height); // 获取元素高度 if (left < 0 || left > window.innerWidth - w) { // 判断条件 如果box左边距距离小于0 或者大于浏览器宽度-元素宽度 left = 0; speedx *= -1; //反转移动 } if (top < 0 || top > window.innerHeight - h) {// 判断条件 如果box上边距距离小于0 或者大于浏览器高度-元素高度 top = 0; speedy *= -1; //反转移动 } } setInterval(function () { move(dv); //调用移动函数 }, 20) </script> </body> </html>
Demo 两个box互相碰撞
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { overflow: hidden; } .box { width: 40px; height: 40px; background-color: black; position: absolute; left: 0; right: 0; overflow: hidden; } .box2 { width: 40px; height: 40px; background-color: black; position: absolute; left: 100px; right: 100px; overflow: hidden; } </style> </head> <body> <div class="box"></div> <div class="box2"></div> <script> var middleware_x; // 声明中间变量 用于存放交换变量 var middleware_y; // 声明中间变量 用于存放交换变量 var dv1 = document.getElementsByClassName("box")[0]; // 获取要移动的元素 这里使用的是ClassName 所以需要索引取出element_obj var dv2 = document.getElementsByClassName("box2")[0];// 获取要移动的元素 这里使用的是ClassName 所以需要索引取出element_obj // 分别设置box横纵坐标移动速度 dv1.speedx = 3; dv1.speedy = 5; dv2.speedx = 5; dv2.speedy = 3; // 移动函数 function move(el) { // el 为element_obj var style = window.getComputedStyle(el); // 获取标签的css属性obj var currentleft = parseInt(style.left); var currenttop = parseInt(style.top); check_border_collision(el); // 调用函数 用于碰到周围弹回 if (check_block_collision(dv1, dv2)) { // 条件判断 如果两个box碰撞 速度属性反转 先试用中间变量存储x,y速度在依次调换 middleware_x = dv1.speedx; middleware_y = dv1.speedy; dv1.speedx = dv2.speedx; dv1.speedy = dv2.speedy; dv2.speedx = middleware_x; dv2.speedy = middleware_y; } // 计算速度 var left = currentleft + el.speedx; var top = currenttop + el.speedy; // 更新至box标签 el.style.left = `${left}px`; el.style.top = `${top}px`; } function check_border_collision(el) { // 矫正函数 var style = window.getComputedStyle(el); // 获取box对象css属性 var left = parseInt(style.left); // 获取当前左边距 var top = parseInt(style.top); // 获取当前下距离 var w = parseInt(style.width); // 获取元素宽度 var h = parseInt(style.height); // 获取元素高度 if (left < 0 || left > window.innerWidth - w) { // 判断条件 如果box左边距距离小于0 或者大于浏览器宽度-元素宽度 left = 0; el.speedx *= -1; //反转移动 } if (top < 0 || top > window.innerHeight - h) {// 判断条件 如果box上边距距离小于0 或者大于浏览器高度-元素高度 top = 0; el.speedy *= -1; //反转移动 } } // 判断函数 用于判断两个box是否相撞 function check_block_collision(ev1, ev2) { var style1 = window.getComputedStyle(ev1); var style2 = window.getComputedStyle(ev2); var left1 = parseInt(style1.left); var left2 = parseInt(style2.left); var top1 = parseInt(style1.top); var top2 = parseInt(style2.top); var width1 = parseInt(style1.width); var width2 = parseInt(style2.width); var height1 = parseInt(style1.height); var height2 = parseInt(style2.height); // box坐标 x=left1+width/2 y=top+height/2 var center1 = { x: left1 + width1 / 2, y: top1 + height1 / 2 }; var center2 = { x: left2 + width2 / 2, y: top2 + height2 / 2 }; // 计算两个box的坐标差的绝对值 var diffx = Math.abs(center1.x - center2.x); var diffy = Math.abs(center1.y - center2.y); // 判断是否碰撞 如果x轴向大于两个box的宽之和且y轴大于两个box的高之和即为碰撞 if (diffx < (width1 + width2) / 2 && diffy < (height1 + height2) / 2) { return true } return false } // 设置定时器 setInterval(function () { move(dv1); //调用移动函数 move(dv2); }, 20) </script> </body> </html>
封装动画函数
实现功能: 动态的渐变效果 支持多参数 例如 {"left":500} 从左至右500px从快至慢渐停
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { overflow: hidden; } .box { width: 40px; height: 40px; background-color: black; position: absolute; left: 0; right: 0; opacity: 1; } </style> </head> <body> <div class="box" id="box1"></div> <script> // 封装函数 解决兼容问题 得到Style function getStyle(el) { // el指element节点 if (getComputedStyle) { return window.getComputedStyle(el) } else { return el.currentStyle } } function animate(el, properties) { //el指element节点 property指方向等但是只能使用默认的方向 left等 target 目标值 // property 新增透明模式 opacity var interval_id; //声明计时器id 如果抛错把这个声明至外部 var current; var speed; if (interval_id) { //如果有定时器 清除 clearInterval(interval_id); } interval_id = setInterval(function () { // 创建定时器函数 for (var property in properties) { var target = properties[property]; if (property === ‘opacity‘) { // 透明度特殊处理 current = Math.round(parseFloat(getStyle(el)["opacity"]) * 100) //获取element透明度并x100进行后续数据处理 该方法将进行上舍入。 } else { current = parseInt(getStyle(el)[property]); // 渐变值 } speed = (target - current) / 30; // 步长 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); // Math.ceil向上取整 Math.floor向下取整 if (property === ‘opacity‘) { // 对opacity进行特殊处理 el.style.opacity = (current + speed) / 100 // 将前面先乘的除掉 } else { el.style[property] = current + speed + ‘px‘ } } }, 20) } el = document.getElementById(‘box1‘); //获取节点 animate(el, {‘opacity‘: 0,"left":200,‘width‘:500}) // 调用封装函数 </script> </body> </html>
以上是关于JavaScript-动画原理如何使用js进行动画效果的实现的主要内容,如果未能解决你的问题,请参考以下文章