多物体运动

多个物体用同一个函数时,函数里定义的定时器应该要每个物体对应一个定时器名称,不然会导致未完成运动就被关闭了,因为定时器名称一样,而开启定时器前会清除一下。

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学习-基础运动的更多相关文章

  1. Vue.JS学习基础

      = 导航   顶部 vue.js介绍 vue.js实例 模板语法 计算属性 样式绑定 条件渲染 列表渲染 事件处理器 表单控件绑定 组件   顶部 vue.js介绍 vue.js实例 模板语法 计 ...

  2. js实现基础运动

    首先我定义3个div每个div当我鼠标放上去的时候,他的宽度就表达,如下图 首先是样式和html代码 <style> div{ width:100px; height:50px; back ...

  3. js学习——基础知识

    数据类型 函数.方法 变量作用域 运算符 条件语句 break和continue typeof 错误(异常) 变量提升 严格模式 JSON void(0) JavaScript            ...

  4. require.js 学习基础

    RequireJS 是一个JavaScript模块加载器,他的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代码,但其主要目的还是为了代 ...

  5. JS学习笔记 - 运动 - 淘宝轮播图

    <script> window.onload=function () { var oDiv=document.getElementById('play'); var aBtn=oDiv.g ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. Node.js系列基础学习----安装,实现Hello World, REPL

    Node.js基础学习 简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一 ...

  8. Node.js学习笔记(一)基础介绍

    什么是Node.js 官网介绍: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...

  9. Node.js学习看这里:基础、进阶、文章

    Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快速的.可扩展的网络应用. Node.js采用事件 ...

随机推荐

  1. web 应用的部署

    一.项目管理 : zentao(国产开源),其他 project.redmine.trac 二.自动部署: jenkins:自动化配置 docker:容器,类似虚拟机,不过只是本机系统的内核的一个虚拟 ...

  2. HDU - 5306 剪枝的线段树

    题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和 本题是吉利爷的2016论文题,1 2套路不 ...

  3. SS7

    在PSTN中各个网络点通过数字信令网交换信息的过程及协议 呼叫流程 SS7 的消息是通过网络点之间的56/64Kbps 的双向通道传送的,这些通道就叫信令链路(signaling links). 信令 ...

  4. python自动化day3-函数、递归、内置函数

    一.什么是函数 修理工===>程序员 具备某一功能的工具===>函数 要想使用工具,需要事先准备好,然后拿来就用且可以重复使用要想用函数,需要先定义,再使用 二.函数基础 1.函数分类 # ...

  5. pyinstaller打包工具简单使用

    python脚本如果在没有安装python的机器上不能运行,所以将脚本打包成exe文件将可跨平台使用,那么怎么打包了,python提供了专门的模块:pyinstaller,下面就介绍下怎么用 1.安装 ...

  6. 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 ...

  7. 实现Map按key或按value排序

    原理思路:用List实现排序,然后将List中的值遍历存入到LinkedHashMap 实现方式: //这里将map.entrySet()转换成list List<Map.Entry<St ...

  8. es第一篇:Getting Started

    es是一个近乎实时的搜索平台,这意味着从索引文档到文档可搜索,是有一点点延迟的(通常是一秒).es集群是一个或多个节点的集合,它们共同保存数据,并提供跨所有节点的联合索引和搜索功能.集群名由clust ...

  9. CSAPP阅读笔记-汇编语言初探(数据传送类指令)-来自第三章3.2-3.3的笔记-P115-P128

    1.如何由机器代码生成汇编代码? objdump -d再加上文件名即可直接在终端看到由反汇编器恢复的汇编代码.注意,文件名并不一定得是.o文件,任何可执行文件都可以. 结果如下: 仅列举了反汇编tes ...

  10. 关于Sql注入的那些事

    登陆注册应该是每一个网站的必做的业务,但是在选择使用Django中的ORM还是说执行原生的Sql语句不同的人应该会有不同的建议,有经验的开发人员都喜欢原生的sql语句,因为相对于ORM来说,执行效率高 ...