大家都知道JQuerry有animate方法来给DOM元素进行运动,CSS3中也有transition、transform来进行运动。而使用原生的Javascript来控制元素运动,须要写非常多运动的细节以及兼容。

然而。当你的BOSS不让你使用庞大的JQ框架,并且你开发的产品也须要在一些不兼容CSS3的浏览器运行的时候。你是否认为每次都要开个定时器来琢磨运动该怎么进行,是件非常费力的事情呢?

那么福利来了,笔者近期总结了两个经常使用的运动框架,并将其写成组件,

仅仅要依照以下的方法调用。就可以方便使用。

1.在你的页面中引入js

<script src="Mover.js"></script>

2.在你的js代码中创建Mover对象

<script>
window.onload=function(){
var mover = new Mover();
};
</script>

3.開始使用mover!

使用方法说明:笔者写的组件包含了两种运动框架供使用。一种是基于速度的;一种是基于时间的。让我们来先看看基于速度的运动框架的使用方法

startMoveBySpeed(obj, json, endFn);

參数obj : 传入要运动的对象

參数json : 以json的形式传入要运动的属性,包含left、top、width、height等以px为单位的属性和透明度opacity,他们的值是运动的终点

參数endFn(可选) : 结束运动后要运行的方法

<script>
//基于速度的运动框架使用方法
window.onload=function(){
//得到你要运动的元素
var oDiv = document.getElementsByTagName('div')[0]; //使用运动框架
var mover = new Mover();
oDiv.onclick=function(){
mover.startMoveBySpeed(this,{'left':200,'width':300,'opacity':50});
//使oDiv的left运动到200px,宽度变为300px,透明度变为50%
} };
</script>

让我们来看看第二种基于时间的运动框架

startMoveByTime(obj, json, options, endFn )

參数obj : 传入要运动的对象

參数json : 以json的形式传入要运动的属性。包含left、top、width、height等以px为单位的属性和透明度opacity。他们的值是运动的终点

參数options : 以json的形式传入传入运动的总时间和运动方式,如:

{

‘times’ : 1000。//运动总时间为1s

‘fx’ : ‘linear’ // 运动形式为匀速

}

当options传入參数为空json{}时,就使用默认设置(运动时间500ms,运动形式为匀速)

參数endFn(可选) : 结束运动后要运行的方法

//基于事件的运动框架使用方法
window.onload=function(){
//得到你要运动的元素
var oDiv = document.getElementsByTagName('div')[0];
//使用运动框架
var mover = new Mover();
oDiv.onclick=function(){
mover.startMoveByTime(
this,
{'left':500,'top':200},
{'times':1000,'fx':'easeIn'},
function(){
mover.startMoveByTime(this,{'opacity':20},{});
});
//使oDiv的left变为500px,高度变为200px,结束上述运动后再使透明度变为20%
}
}

如今来说说两种方式的差别吧。使用第一种方式进行运动时。元素的各项须要改变的属性的运动速度同样,而因为每项属性起点到终点的距离不一样。所以各项属性到达运动终点的时间也不一样。

而第二种运动直接固定了运动总时间同样,所以全部传入參数的属性一起改变、一起终止。

以下是Mover.js组件的代码,笔者乃菜鸟一仅仅,欢迎指正。后面有时间也会将弹性运动、碰撞运动、重力运动一起写入框架

/*
js原生运动组件
*/ //Mover构造函数
function Mover(){
this.setting = {
'times' : 500,
'fx' : 'linear'
}
} //获取当前样式
Mover.prototype.getStyle = function(obj,attr)
{
return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
} //获取当前时间
Mover.prototype.now = function(){
return (new Date()).getTime();
} //速度版运动框架
Mover.prototype.startMoveBySpeed = function (obj,json,fnEnd)
{
clearInterval(obj.timer);
_this = this;
obj.timer = setInterval(function(){
obj.bStop = true;
for(var attr in json)
{
var cur = 0;
var speed = 0;
if(attr === 'opacity')
{
cur = _this.getStyle(obj,attr);
cur = Math.round( parseFloat(cur*100) );
}
else
{
cur = parseInt(_this.getStyle(obj,attr));
} var speed = (json[attr]-cur)/8; speed = speed ? Math.ceil(speed):Math.floor(speed); if(cur !== json[attr])
{
obj.bStop = false;
} if(attr === 'opacity')
{
obj.style.opacity = (cur+speed)/100;
obj.style.filter = 'Alpha(opacity:'+(cur+speed)+')';
}
else
{
obj.style[attr] = (cur+speed)+'px';
}
} if(obj.bStop)
{
clearInterval(obj.timer);
fnEnd && fnEnd.call(obj);
} },20);
} //时间版运动框架
Mover.prototype.startMoveByTime = function(obj,json,options,endFn){
//对于时间版框架来说。初始值b是固定的,所以写在定时器外面
var _this = this;
//默认设置
extend(_this.setting,options); var iCur = {};
//获取当前值
for(attr in json)
{
iCur[attr] = 0; if(attr === 'opacity')
{
iCur[attr] = Math.round( parseFloat( _this.getStyle(obj,attr) )*100 );
}else{
iCur[attr] = parseInt( _this.getStyle(obj,attr) );
} }; var iStartTime = _this.now();
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var iCurTime = _this.now();
var t = _this.setting.times-
Math.max(0,iStartTime-iCurTime+_this.setting.times);
for(attr in json)
{
/*
Tween[fx]函数4个參数
t:current time(当前时间)
b:beginning value(初始值)
c: change in value(变化量)
d:duration(持续时间)
return (目标点)
*/
var value = _this.Tween[_this.setting.fx](
t, //t 0~times
iCur[attr], //b
json[attr]-iCur[attr], //c
_this.setting.times //d
);
if(attr === 'opacity')
{
obj.style[attr] = parseFloat(value/100);
obj.style.filter = 'alpha(opacity:'+value+')';
}else{
obj.style[attr] = value + 'px';
} } if( t === _this.setting.times )
{
clearInterval(obj.timer);
endFn && endFn.call(obj);
}
},13); }
//覆盖默认设置
function extend(child,father){
for(var attr in father)
{
child[attr] = father[attr];
}
}
//Tween运动算法
Mover.prototype.Tween = {
/*
4个參数
t:current time(当前时间)
b:beginning value(初始值)
c: change in value(变化量)
d:duration(持续时间)
return (目标点) */ linear: function (t, b, c, d){ //匀速
return c*t/d + b;
},
easeIn: function(t, b, c, d){ //加速曲线
return c*(t/=d)*t + b;
},
easeOut: function(t, b, c, d){ //减速曲线
return -c *(t/=d)*(t-2) + b;
},
easeBoth: function(t, b, c, d){ //加速减速曲线
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
easeInStrong: function(t, b, c, d){ //加加速曲线
return c*(t/=d)*t*t*t + b;
},
easeOutStrong: function(t, b, c, d){ //减减速曲线
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
easeBothStrong: function(t, b, c, d){ //加加速减减速曲线
if ((t/=d/2) < 1) {
return c/2*t*t*t*t + b;
}
return -c/2 * ((t-=2)*t*t*t - 2) + b;
}
}

【原生JS组件】javascript 运动框架的更多相关文章

  1. 原生JS封装animate运动框架

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  2. 【repost】JavaScript运动框架之速度时间版本

    一.JavaScript运动框架之速度版 1.1 运动框架的实现思路 运动,其实就是在一段时间内改变 left . right . width . height . opactiy 的值,到达目的地之 ...

  3. javascript运动框架(三)

    迟到了好几天,不好意思哈!继续来优化一下javascript运动框架的代码.之前的代码存在bug,当重复点击时速度会加快,那么怎么解决这个bug呢? 现在我们就来解决一下,其实很简单,在开始运动时,关 ...

  4. 好程序员技术教程分享JavaScript运动框架

    好程序员技术教程分享JavaScript运动框架,有需要的朋友可以参考下. JavaScript的运动,即让某元素的某些属性由一个值变到另一个值的过程.如让div的width属性由200px变到400 ...

  5. JavaScript 运动框架 Step by step(转)

    1,运动原理 Js运动,本质来说,就是让 web 上 DOM 元素动起来.而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等.动画的原理就是把不同状态的物体,串成连续的样 ...

  6. javascript运动框架

    下面这个一个运动框架可以控制元素在一个属性上的运动,同时,可以调用回调函数. /* 获取元素某个属性的值 @obj: 对象 @attr: 属性值 */ function getStyle(obj, a ...

  7. JS 之完美运动框架

    完美运动框架是对原来的任意值运动框架的改善和效率的提升,即利用了json对属性进行封装,从而提高效率: window.onload=function(){ var oDiv=document.getE ...

  8. 原生JS封装时间运动函数

    /*讲时间运动之前先给大家复习一下运动函数 通常大家都会写运动框架,一个定时器(Timer),一个步长(step 就是每次运动的距离),一个当前位置(current)一个目标位置(target),然后 ...

  9. javaScript运动框架之匀速运动

    运动框架 1.在开始运动时,关闭已有定时器 2.把运动和停止隔开(if/else) 匀速运动的停止条件 运动终止条件:距离足够近 Demo代码 <!DOCTYPE html> <ht ...

随机推荐

  1. PHP 二维数组去掉重复值并保持原结构

    PHP 二维数组去掉重复值并保持原结构 直接上代码,解释很详细 //二维数组去掉重复值 function arrunique($a){ foreach($a[0] as $k => $v){ / ...

  2. 8.ES6测试

    转自:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html 如果测试脚本是用ES6写的,那么运行测试之前,需 ...

  3. checkbox和文字不再同一水平线上

    为了演示效果,我故意将文字变为12px,将复选框变大,看到的效果就是下面的那样 然后,我们通过给复选框添加vertical-align:middle:让文字和复选框达到同一水平线的效果

  4. 001.TypeScript简介.md

    TypeScript是一门开源的,由微软开发维护的,发布于2012年10月的静态类型的语言: 他是ECMAScript的超集,支持JavaScript的所有语法和语义,并且在此基础之上提供了更多额外的 ...

  5. ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上)

    前言 在上篇文章中,详细分析了RACSignal是创建和订阅的详细过程.看到底层源码实现后,就能发现,ReactiveCocoa这个FRP的库,实现响应式(RP)是用Block闭包来实现的,而并不是用 ...

  6. UI Framework-1: Aura

    Aura (obsolete) This document is still good for a high level overview, with contact information, but ...

  7. 初学javascript,写一个简单的阶乘算法当作练习

    代码如下: <script> var a = prompt("请输入值"); function mul(a){ if(a==1){ return 1; } return ...

  8. ES6学习笔记(十六)async函数

    1.含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖,号称异步的终极解决方案. 前文有一个 Gen ...

  9. zabbix4.0 使用nginx前端安装

    注:环境需求:centos7 1.安装阿里云yum源: rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/4.1/rhel/7/x86_64/zabb ...

  10. whatis---查询一个命令执行什么功能

    whatis命令是用于查询一个命令执行什么功能,并将查询结果打印到终端上. whatis命令在用catman -w命令创建的数据库中查找command参数指定的命令.系统调用.库函数或特殊文件名.wh ...