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动画相关的更多相关文章

  1. 梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画

    CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能. 一.两者的主要区别 先开门见山的说说两者之间的区别. 1)CSS动画: 基于CSS的动 ...

  2. javascript动画系列第三篇——碰撞检测

    前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...

  3. javascript动画系列第一篇——模拟拖拽

    × 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...

  4. JavaScript动画知多少?

    今天,小学生以自己浅薄的见地,在前辈大能的基础上写这篇文章,希望给大家打开一扇窥探JavaScript(以下简称JS)动画的窗户. JS如何制造出动画效果? 结合浏览器提供的 setInterval ...

  5. Javascript动画效果(三)

    Javascript动画效果(三) 前面我们已经介绍了速度动画.透明度动画.多物体运动和任意值变化,并且我们在Javascript动画效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的 ...

  6. Javascript动画效果(一)

    Javascript动画效果(一) 前面我们介绍了Javascript的回到顶部效果,今天呢,我们对Javascript动画做进一步的研究.在这篇博文中我们只介绍简单的匀速运动.简单的缓冲运动和简单的 ...

  7. Javascript动画效果(二)

    Javascript动画效果(二) 在前面的博客中讲了简单的Javascript动画效果,这篇文章主要介绍我在改变之前代码时发现的一些问题及解决方法. 在前面的多物体宽度变化的例子中,我们给其增加代码 ...

  8. Javascript动画效果(四)

    Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...

  9. CSS3之动画相关

    CSS3动画相关的属性:transform,transition,animation. 变形Transform 语法: transform: rotate | scale | skew | trans ...

随机推荐

  1. itest(爱测试) 4.3.1 发布,开源BUG 跟踪管理 & 敏捷测试管理软件

    4.3.0 发布后有三个用户强烈要求的更新,所以一周后4.3.1出炉,有点版本帝的味道哈,用户的反馈是我们持续升级的动力...... itest 简介:查看简介 test 开源敏捷测试管理,testO ...

  2. 概率DP hdu 3366 .

    题意:一个人被困在一个城堡里,面前有n条路,他自己有m百万元,选择每一条路都有p概率通过,q概率遇到士兵,1-p-q概率道路不通:遇到士兵的话需要上交1百万,如果不够钱,则被杀死,问的是最优情况下多少 ...

  3. Educational Codeforces Round 80 (Rated for Div. 2)D(二分答案,状压检验)

    这题1<<M为255,可以logN二分答案后,N*M扫一遍表把N行数据转化为一个小于等于255的数字,再255^2检验答案(比扫一遍表复杂度低),复杂度约为N*M*logN #define ...

  4. 生成SSH密钥过程

    1.查看是否已经有了ssh密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除 2.生存密钥: $ ssh-keygen -t rsa -C "name@doumi.com& ...

  5. QT写的一个小工具:阿里云MQTT连接参数生成器.

    一.工具介绍. 最近在研究MQTT协议联网的一些问题,现在主流的物联网平台都支持MQTT协议. 在做阿里云平台连接测试的时候,连接参数的生成没有好用的工具, 所以就自己写了一个. 这个工具主要用于阿里 ...

  6. iso15693芯片读写工具套件 icode-slix2读写 nfc type 5 tag读写

    iso15693芯片读写工具套件 icode-slix2读写 nfc type 5 tag读写校验套件 iso15693工具套件支持icode-slix,icode-slix2芯片的读写,支持iso1 ...

  7. Kmp算法浅谈

    Kmp算法浅谈 一.Kmp算法思想 在主串和模式串进行匹配时,利用next数组不改变主串的匹配指针而是改变模式串的匹配指针,减少大量的重复匹配时间.在Kmp算法中,next数组的构建是整个Kmp算法的 ...

  8. C#串口通信:MSComm控件使用详解

    目  次MSComm控件两种处理通讯的方式CommPort属性RThreshold 属性CTSHolding 属性SThreshold 属性CDHolding 属性DSRHolding 属性Setti ...

  9. OGG在windows环境下字符集的配置

    windows环境下不配置字符集(默认使用windows自己的字符集),从linux等系统同步过来的表中如果含有中文字符列将显示为乱码,被ogg误认为虚拟列,从而导致进程abend. 设置ogg进程在 ...

  10. C#加载XML方式

    //path:xml文件路径  SECSMessage:xml文件的根元素下的第一个子集元素 <SECSLibrary> <SECSMessage> <Descripti ...