匀速运动(当需要物体做匀速运动直接调用statMove函数)

 function startMove(dom, speed,targetPosetion){     //dom : 运动对象, speed :运动速度 targetPosition : 到达目标位置
  clearInterval(timer); //防止定时器叠加,先清除定时器。
3 speed = targetPosetion - dom.offsetLeft > 0 ? speed : -speed;
//断物体到移动的目标位置的左边还是右边,左边速度是正的,右边速度是负的。
  timer = setInterval(function(){    //设置定时器。变量timer要定义在函数外面。
    if(Math.abs(targetPosetion - dom.offsetLeft ) < Math.abs(speed)){
      clearInterval(timer); //当目位置减去物体偏移量小于定时器移动的位置(因为在移动就超出了目标位置),清除定时器
      dom.style.left = targetPosetion + "px"; //因为距离目标位置还有一小段距离,直接让物体等于目标位置就行
    }else{
      dom.style.left = dom.offsetLeft + speed + "px";
    }
  },30);
}
 
缓冲运动(越接近目标,速度越慢)缓运运动比直线运动视觉性更好,更常用
 
 function startMove(dom, targetPosetion) {
  clearInterval(timer);
  var speed = null;
  timer = setInterval(function () {
    speed = (targetPosetion - dom.offsetLeft) /10; //因为越接近目标速度越慢,并且相距越短,所以可以用距离表示速度(由于速度太大,需要除以一个数或乘一个小数)
    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
    if(dom.offsetLeft == targetPosetion){
      clearInterval(timer);
    }else{
      dom.style.left = dom.offsetLeft + speed + "px";
    }
  }, 30)
}
6:当目标位置 - 物体偏移量小于除数时,speed就等于小数了, 但是偏移量都是整数,就会自动的取舍值,例如:dom.style.left = 355.24px 实际会转换成dom.style.left = 355px; 导致最后怎么加都是原来的那个整数。所以只要有小数就向上取整(Math.ceil()),加上1。当是负值的时候就下取整(Math.floor()).因为当speed是小数时,就会被取整。所以最后是一个像素一个像素加上去的,所以物体的偏移量正好等于目标位置时就清除定时器。
 
颜色渐变的缓冲运动
 
因为让当前的颜色渐变需要让当前的opacity增加或减少,获取当前的透明度opacity可以用计算样式window.getComputedStyle。
计算样式只读,返回的都是绝对值,没有相对单位
获取计算样式函数
 function getStyle(dom,attr){
  if(window.getComputedStyle){
    return window.getComputedStyle(dom,null)[attr];
  }
  else{
    return dom.currentStyle[attr]; //IE8不兼容,IE独有属性currentStyle
  }
}
 
让物体透明度缓冲变化
 
 startMove(div,0.5);
function startMove(dom, targetOpacity) {
  clearInterval(timer); targerOpacity = targetOpacity * 100; //透明度的范围是0-1,而缓冲变化最小变化是1 需要把缓冲范围变大(扩大100倍)。
  var speed = null,current = null;
  timer = setInterval(function () {
    current = parseFloat(getStyle(div,'opacity')) * 100;
    console.log(current);
    speed = (targetOpacity - current) / 10;
    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
    if (current == targetOpacity) {
      clearInterval(timer);
    } else {
    dom.style.opacity = (current + speed) / 100; //当赋值时需要缩小100倍
    }
  }, 30)
}
 
多物体运动
 
例:4个div,鼠标移入到那个div,宽度做缓冲运动移动到400;移除宽度变为100。
下面的代码。橙色的部分有timer变为dom自己的属性dom.timer,在上面定义timer的时候,
定义的timer是在函数外面的,4个div共用一个timer定时器,当鼠标移入第一个div时,开启一个定
时器,移出div时,又开启一个定时器。当快速从第一个div移到第二个div是,发现宽度回不去了,
因为鼠标移入第二个div时。把上一个定时器给清除了,重新开启了一个定时器。
 
所以解决这个问题,就是在每个div上都加一个定时器。
当清理定时器的时候也是清理自己的定时器,不会影响其他的,就在每个元素上加上timer属性。
 function startMove(dom, targetPosetion) {
clearInterval(dom.timer);
var speed = null;
dom.timer = setInterval(function () {
current = parseFloat(getStyle(dom, 'width')); //用计算样式获取当前宽度值。
speed = (targetPosetion - current) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
console.log(speed, current);
if (current == targetPosetion) {
clearInterval(dom.timer);
} else {
dom.style.width = current + speed + "px";
}
}, 30)
} for (var i = 0; i < div.length; i++) {
  div[i].onmouseenter = function () {
    startMove(this, 400)
  }
  div[i].onmouseleave = function () {
    startMove(this, 100);
  }
}
 
多物体不同属性运动
 
 function startMove(dom , attr , target){
  clearInterval(dom.timer);
  dom.timer = setInterval(function(){
    var current = null,speed = null;
    if(attr == 'opacity'){
      current = parseFloat(getStyle(dom,attr)) * 100;
    }else{
      current = parseFloat(getStyle(dom,attr));
    }
    speed = (target - current) / 10;
    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
    if(current == target){
      clearInterval(dom.timer);
    }
    else if(attr == 'opacity'){
      dom.style.opacity = (current + speed) / 100;
    }else{
      dom.style[attr] = (current + speed) + "px";
    }
  },30)
} var div = document.getElementsByTagName('div');
div[0].onmouseenter = function(){
  startMove(this,'width',400);
};
div[1].onmouseenter = function(){
  startMove(this,'height',400);
};
div[2].onmouseenter = function(){
  startMove(this,'borderWidth',20);
};
div[3].onmouseenter = function(){
  startMove(this,'opacity',50);
};

多物体多值运动 + 回调机制

function startMove(dom, targetObj, callback) {
clearInterval(dom.timer);
dom.timer = setInterval(function () {
var stop = true;
var speed = null, current = null;
for (var prop in targetObj) {
if (prop == 'opacity') {
current = parseFloat(getStyle(dom, prop))*100;
} else {
current = parseFloat(getStyle(dom, prop));
}
speed = (targetObj[prop] - current) / 10;
speed = speed>0?Math.ceil(speed):Math.floor(speed);
if (prop == 'opacity') {
dom.style.opacity = (current + speed) / 100;
} else {
dom.style[prop] = (current + speed) + "px";
}
if (targetObj[prop] != current) {
stop = false;
}
}
if (stop == true) {
clearInterval(dom.timer);
typeof callback == 'function' && callback();
}
}, 30);
}

//让多物体多值运动,由于多值就可以用对象来装。
startMove(dom, targetObj, callback)接收3个参数,运动对象,想要改变的多值属性对象,回调函数
跟上面一样一地步清除定时器,然后设置定时器,用for in 循环传过来的对象属性,
如果传过来的是opacity 就要扩大100倍,不是就正常调用上面getStyle()方法,返回一个计算属性。
设置一个锁,每次定时器执行时定义一个变量stop = true 可以停止,
当for in 循环时,判断如果有一个当前值不等于目标值的时候,就让stop = false。不可以停止
for in 结束,stop == true 的时候就代表所有的值都到达目标值,这时候就可以清空定时器。这个运动过程结束,调用回调函数
      var divOne = document.getElementById('one');
var divTwo = document.getElementById('two');
divOne.onclick = function () {
startMove(this, { width: 400,height: 400,left: 200,top: 300,opacity: 50}, function () {
startMove(divTwo, { width: 400, height: 400, left: 200, top: 300, opacity: 50 }, function () {
alert(555);
})
})
}

JavaScript 运动(缓冲运动,多物体运动 ,多物体多值运动+回调机制)的更多相关文章

  1. 原生JavaScript运动功能系列(三):多物体多值运动

    多物体同时出发运动函数实现 多属性同步运动变化实现 一.多物同时触发运动函数实现 前面两个动画示例基本理解了动画的核心:位置变化和速度变化,操作的核心就是定时器分段叠加属性值.但是动画还是基于单个元素 ...

  2. js 运动函数篇 (一) (匀速运动、缓冲运动、多物体运动、多物体不同值运动、多物体多值运动)层层深入

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS写 匀速运动.缓冲运动.多物体运 ...

  3. JS运动缓冲的封装函数

    之前经常写运动函数,要写好多好多,后来想办法封装起来.(运动缓冲). /* 物体多属性同时运动的函数 obj:运动的物体 oTarget:对象,属性名为运动的样式名,属性值为样式运动的终点值 rati ...

  4. js多物体多方向缓动动画加带有回调机制

    一.获取一组div元素 var boxs = document.getElementsByTagName('div'); 二.封装获取属性值的函数 function getStyle(dom, att ...

  5. JavaScript获取select下拉框中的第一个值

    JavaScript获取select下拉框中的第一个值 1.说明 获取select下拉框中的第一个值 2.实现源码 <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  6. Unity查找物体的子物体、孙物体

    Unity查找物体下的所有物体 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分 ...

  7. (转)使用Python和OpenCV检测图像中的物体并将物体裁剪下来

    原文链接:https://blog.csdn.net/liqiancao/article/details/55670749 介绍 硕士阶段的毕设是关于昆虫图像分类的,代码写到一半,上周五导师又给我新的 ...

  8. 客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值。

    客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值.     无论是什么的html控件,只要加上了runat="server" ...

  9. 研究下JavaScript中的Rest參数和參数默认值

    研究下JavaScript中的Rest參数和參数默认值 本文将讨论使 JavaScript 函数更有表现力的两个特性:Rest 參数和參数默认值. Rest 參数 通常,我们须要创建一个可变參数的函数 ...

随机推荐

  1. ES6笔记(二)

    一.字符串的扩展1. 用于从码点返回到对应字符. String.fromCodePoint(xx)2. for...of可以遍历字符串3. includes():返回布尔值,表示是否找到了参数字符串. ...

  2. react 入坑之罪

    componentDidMount :生命周期在react下只调用一次, render:比它先执行 componentWillRecvieProps(newProps) :能取到父组件的值 rende ...

  3. ereg

    int ereg ( string $pattern , string $string [, array &$regs ] ) Note: 使用 Perl 兼容正则表达式语法的 preg_ma ...

  4. Hibernate的增删改查(事务)

    Hibernate的事务: 1. 设置事务隔离级别都是用  自己进行存储的 二进制      十进制 read uncommitted   读未提交        0001         1 rea ...

  5. flask 第七章 简陋版智能玩具 +MongoDB初识和基本操作

    1.简陋版web智能玩具 FAQ.py文件 import os from aip import AipSpeech, AipNlp from uuid import uuid4 "" ...

  6. 复杂xml格式报文和实体类之间的转化

    pom.xml中引入如下依赖: <dependency> <groupId>org.eclipse.persistence</groupId> <artifa ...

  7. Django--filter()-字段查找(双下划线的使用详解)

    Django--filter()-字段查找(双下划线的使用详解) 在了解django中的字段查找的同时,让我们先熟悉一下比较符: 大于--gt-(greater than) 小于--lt-(less ...

  8. java中外部类和内部类的访问控制符区别

    外部类只有两种访问控制符,即public和default(包访问控制级别).原因:外部类的上一级程序单元是包,所以它只有两种作用域:同一个包内和任何位置,这样只需要用public和default即可, ...

  9. TCP学习总结(四)

    TCP连接管理 TCP运输连接有3个阶段, 即: 连接建立,数据传送和连接释放. 1. TCP的连接建立(3次握手) TCP连接的建立采用客户服务器方式.主动发起连接建立的应用进程叫做客户(clien ...

  10. 新手学习之浅析一下c/c++中的指针

    一.我们先来回忆一下指针的概念吧,方便下面的介绍 指针是存放地址值的变量或者常量.例如:int a=1;&a就表示指针常量(“&”表示取地址运算符,也即引用).int *b,b表示的是 ...