JS学习-基础运动
多物体运动
多个物体用同一个函数时,函数里定义的定时器应该要每个物体对应一个定时器名称,不然会导致未完成运动就被关闭了,因为定时器名称一样,而开启定时器前会清除一下。
obj.timer
多值同时运动
- 怎样同时运动?
startMove(this, 'width', 200, 10);
startMove(this, 'height', 200, 10);
下面的运动会清除掉上面的定时器,因为定时器开启前会先清除一下,所以这样不行。应该通过json传入数据,for in遍历。
- 一个值到target了,另外一个还没有到,怎样判断?
要所有值都到了目标点才能清除定时器
解决方案
var oDiv1 = document.getElementById('div1');
oDiv1.onclick = function() {
startMove(this, {
width : 200,
height: 300
}, 10); //////json
}
function startMove(obj, json, iSpeed) {
clearInterval(obj.iTimer);
var iCur = 0;
obj.iTimer = setInterval(function() {
var iBtn = true;
for ( var attr in json ) {
//什么时候停止定时器?所有属性都运动到了目标点的时候
var iTarget = json[attr];
if (attr == 'opacity') {
iCur = Math.round(css( obj, 'opacity' ) * 100);
} else {
iCur = parseInt(css(obj, attr));
}
if (iCur != iTarget) {
iBtn = false; //判断是不是所有属性都运动到了目标点
if (attr == 'opacity') {
obj.style.opacity = (iCur + iSpeed) / 100;
obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
} else {
obj.style[attr] = iCur + iSpeed + 'px';
}
}
}
//在for in循环外来看下,所有属性是不是都到了目标点
if (iBtn) {
clearInterval(obj.iTimer);
}
}, 30);
}
function css(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
缓冲运动(减速运动)
越接近目标点,速度就越小
框架:
速度要在定时器里定义
速度=(目标值-当前值)/缩放系数
速度取整(保证能达到目标点)
停下条件:到达目标点
基本框架和前面的运动一样,只是速度iSpeed的处理不一样
json同样可以传入多值,都有缓冲效果,像多值同时运动一样
function startMove(obj, json, fn) {
clearInterval(obj.iTimer);
var iCur = 0;
var iSpeed = 0;
obj.iTimer = setInterval(function() {
var iBtn = true;
for ( var attr in json ) {
var iTarget = json[attr];
if (attr == 'opacity') {
iCur = Math.round(css( obj, 'opacity' ) * 100);
} else {
iCur = parseInt(css(obj, attr));
}
//不同的运动形式主要速度算法不一样,其他部分都差不多
iSpeed = ( iTarget - iCur ) / 8;
//这里除/乘小数/减都可以,主要处理是这里,可以很好的控制停下的点
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
//向上取整和向下取整
//取整是因为offsetLeft是js解释出来的,会四舍五入,当乘或除到iSpeed小于0.5时就达到不了目标点
//看下表解释
if (iCur != iTarget) {
iBtn = false;
if (attr == 'opacity') {
obj.style.opacity = (iCur + iSpeed) / 100;
obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
} else {
obj.style[attr] = iCur + iSpeed + 'px';
}
}
}
if (iBtn) {
clearInterval(obj.iTimer);
fn && fn.call(obj);
}
}, 30);
}
function css(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
| offsetLeft | iSpeed | style.left |
|---|---|---|
| 495 | 0.625 | 495.625 |
| 496 | 0.5 | 496.5 |
| 497 | 0.375 | 497.375 |
| 497 | 0.375 | 497.375 |
497.375后一直四舍五入,所以得出速度也一直是0.375,导致停在497.375的位置。
offsetLeft是JS解释,是计算后的值,会四舍五入并不带单位
style.left是CSS解释,会认小数的
JS运动应用
多图片展开、收缩
元素居中放大:除了要改变元素的宽高以外,还要改变元素定位(left,top),如果图片方法一倍,那么位移放大的宽高的一半
在用js去设置css样式的时候:在同一个代码块中,有些css样式的设置的权限(优先级)要高于其他的样式
解决方案:不放在同一代码块
带运动效果的留言本(瀑布流)
略
淘宝首页幻灯片
略
带运动的返回顶部
略
图片的预先加载 Image对象
如果一个页面有几十张图片,都是用src加载进去会导致打开页面慢,页面未加载完成,js也没有动作。
可以用数组把所有图片地址存起来,只用一个src,用户点下一张时把src地址换一下。这个可以解决一次加载多个src的问题,但当用户网络慢或者一张图片太大,会导致按下一张后要隔一定时间才加载出来。
最好方法应该是先把图片预加载
在页面刚打开的时候,我们去加载第一张图片,然后页面加载完成以后,在用户看的时间内,去加载后面的内容,那么我们必须有个工具 -> Image对象
new Image()
var oImage = new Image();
属性:
- src : 当我们给Image对象的src属性赋值一个url的时候,这个Image对象就去会加载url资源(有点像下载器),加载完成以后的资源被保存到了浏览器的缓存文件夹里面,下次如果我们要去调用这个url地址的时候,直接是从缓存文件夹读取到的,所以速度很快。
- onload : 当资源加载完成的时候触发
- onerror : 当资源加载失败的时候触发
应用:预加载图片-相册
var iCur = 0;//记录第几张
function xunlei() {
oImage.src = arr[iCur];
oImage.onload = function() {
iCur++;
if (iCur < arr.length) {
xunlei(); //递归
}
}
}
//当第0张加载完成后,开始加载第一张,一直到全部加载完成,
//加载完成以后的资源被保存到了浏览器的缓存文件夹里面,当需要用这个url时,照常赋值给src,它会直接从缓冲文件里读取
按需加载
略
高级运动
加减速运动
速度 +/-= 加速度
弹性运动
框架:
速度要是全局变量
速度 += (目标点 - 当前值)/系数;
速度 *= 摩擦系数;
系数最适取值:6 7 8
摩擦系数最适取值:0.7 0.75
停下条件:速度足够小,距离目标点足够近
if( Math.abs(速度)<=1 && Math.abs(目标点 - 当前值offset)<=1 ){
...
}
应用:弹性菜单
和缓冲运动区别:
缓冲运动框架
速度要在定时器里定义
速度=(目标值-当前值)/缩放系数
速度取整
停下条件:到达目标点
滚动歌词
用两行一样的歌词,叠在一起,上面一行是滚动的,下面行固定
弹性过界问题
当宽高出现负值时,非标准IE会报错
解决方案:有可能出现负值的时候,先判断是否 < 0 ,若是小于零则赋0;
碰撞运动
碰撞运动 : 首先找到碰撞的临界点 , 再确定运动的方向 , 然后去改对应的速度(速度取反)
应用:浮动广告
定时器问题
速度版的运动框架在老版本的浏览器中,切换到别的页面时,定时器会变得缓慢,导致多个定时器时会时间不一致,在新版本的浏览器中已经修复了这个问题。
解决方案
window.onfocus = function(){
timer = setInterval(...);
};
//在切换页面时停止定时器,切换回来时在开定时器
//方法不算很好,onfocus、onblur可能还有兼容性问题
window.onblur = function(){
clearInterval(timer);
};
这个问题在时间版运动框架中也有,但是时间版中控制对象位置的t在切换回页面时会马上到时间了,所以位置也一瞬间从原来的位置跳到目标位置了;
时间版运动框架
与经典startMove的区别
- 以时间为单位,而不是以速度为单位
- 例子 : 从中间放大的图片
优点:经典版同时移动两个值的时候,如果两个值移动的距离不一样,会导致一个快一个慢的问题,时间版运动框架就没有这个问题
Tween
一个来自flash的运动算法
JQ中也在使用tween算法
Tween公式:4个参数
- t:current time(当前时间)
- b:beginning value(初始值)
- c: change in value(变化量)
- d:duration(持续时间)
- return (目标点)
还有几个运动有a,p的值,这是用来控制幅度之类的,不写也可以,本身有默认值;
通过( new Date() ).getTime()获取当前时间
var startTime = now(); //放在定时器外,是1970年到现在的毫秒时间
var changeTime = now();//放在定时器内
var t = d - Math.max(0,startTime - changeTime + d);
//d是持续时间
//Math.max(0,startTime - changeTime + d)得到d-0的时间段
// d - Math.max(0,startTime - changeTime + d)得到0到d的时间段
//通过上面的方法获取到t的值
function now(){
return (new Date()).getTime();
}
包含的运动有:
- 匀速
- 加/减速曲线
- 加加/减减速曲线
- 正弦衰减/增强曲线(弹动渐入/渐出)
- 回退加速/减速(回退渐入/渐出)
- 弹球减振/加振(弹球渐出/渐入)
JS学习-基础运动的更多相关文章
- Vue.JS学习基础
= 导航 顶部 vue.js介绍 vue.js实例 模板语法 计算属性 样式绑定 条件渲染 列表渲染 事件处理器 表单控件绑定 组件 顶部 vue.js介绍 vue.js实例 模板语法 计 ...
- js实现基础运动
首先我定义3个div每个div当我鼠标放上去的时候,他的宽度就表达,如下图 首先是样式和html代码 <style> div{ width:100px; height:50px; back ...
- js学习——基础知识
数据类型 函数.方法 变量作用域 运算符 条件语句 break和continue typeof 错误(异常) 变量提升 严格模式 JSON void(0) JavaScript ...
- require.js 学习基础
RequireJS 是一个JavaScript模块加载器,他的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代码,但其主要目的还是为了代 ...
- JS学习笔记 - 运动 - 淘宝轮播图
<script> window.onload=function () { var oDiv=document.getElementById('play'); var aBtn=oDiv.g ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Node.js系列基础学习----安装,实现Hello World, REPL
Node.js基础学习 简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一 ...
- Node.js学习笔记(一)基础介绍
什么是Node.js 官网介绍: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...
- Node.js学习看这里:基础、进阶、文章
Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快速的.可扩展的网络应用. Node.js采用事件 ...
随机推荐
- web 应用的部署
一.项目管理 : zentao(国产开源),其他 project.redmine.trac 二.自动部署: jenkins:自动化配置 docker:容器,类似虚拟机,不过只是本机系统的内核的一个虚拟 ...
- HDU - 5306 剪枝的线段树
题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和 本题是吉利爷的2016论文题,1 2套路不 ...
- SS7
在PSTN中各个网络点通过数字信令网交换信息的过程及协议 呼叫流程 SS7 的消息是通过网络点之间的56/64Kbps 的双向通道传送的,这些通道就叫信令链路(signaling links). 信令 ...
- python自动化day3-函数、递归、内置函数
一.什么是函数 修理工===>程序员 具备某一功能的工具===>函数 要想使用工具,需要事先准备好,然后拿来就用且可以重复使用要想用函数,需要先定义,再使用 二.函数基础 1.函数分类 # ...
- pyinstaller打包工具简单使用
python脚本如果在没有安装python的机器上不能运行,所以将脚本打包成exe文件将可跨平台使用,那么怎么打包了,python提供了专门的模块:pyinstaller,下面就介绍下怎么用 1.安装 ...
- mysql出现 Unknown column 'bname' in 'where clause'和Unknown column 'bid' in 'field list'
在用mysql数据库建表和修改数据库数据时,出现 Unknown column 'bname' in 'where clause'和Unknown column 'bid' in 'field li ...
- 实现Map按key或按value排序
原理思路:用List实现排序,然后将List中的值遍历存入到LinkedHashMap 实现方式: //这里将map.entrySet()转换成list List<Map.Entry<St ...
- es第一篇:Getting Started
es是一个近乎实时的搜索平台,这意味着从索引文档到文档可搜索,是有一点点延迟的(通常是一秒).es集群是一个或多个节点的集合,它们共同保存数据,并提供跨所有节点的联合索引和搜索功能.集群名由clust ...
- CSAPP阅读笔记-汇编语言初探(数据传送类指令)-来自第三章3.2-3.3的笔记-P115-P128
1.如何由机器代码生成汇编代码? objdump -d再加上文件名即可直接在终端看到由反汇编器恢复的汇编代码.注意,文件名并不一定得是.o文件,任何可执行文件都可以. 结果如下: 仅列举了反汇编tes ...
- 关于Sql注入的那些事
登陆注册应该是每一个网站的必做的业务,但是在选择使用Django中的ORM还是说执行原生的Sql语句不同的人应该会有不同的建议,有经验的开发人员都喜欢原生的sql语句,因为相对于ORM来说,执行效率高 ...