帧动画插件

动画插件封装

最近这段时间一直都在研究关于动画方法的知识,说实话确实不容易,主要还是动画算法这方面比较难,毕竟没学过。当然也有所收获,明白了基本动画的原理是什么,所以自己也封装了一个简单的动画插件来巩固自己所学。

动画插件的实现方式

对于前端来说,主要实现动画的方式就是css(transition , animation),js(setTimeout , setInterval , requestAnimationFrame),canvas,svg等方式,在这里我主要是通过requestAnimationFrame来实现动画效果的。

插件说明

该插件接受5个参数:

  1. 第一个参数是需要动画的目标元素。
  2. 第二个参数是需要动画的属性,是一个对象。
  3. 第三个参数是动画的总时长。
  4. 第四个参数是动画的效果。目前支持三种动画效果,linear,easeIn,easeOut。
  5. 第五个参数是动画结束之后的回调函数。

该插件可以实现多个属性一起动画效果,也可以实现单个属性动画效果,也可以实现一个属性接着一个属性动画效果。由于使用的是回调函数,所以当一个接着一个属性来实现动画效果的时候,会产生回调函数嵌套。

插件代码

function  (element , props , duration , easing , callback) {

if (typeof element !== 'object' && element.nodeType !== 1) {

return;

};

if (typeof props !== 'object' && props.toString() !== '[object Object]') {

return;

};

var noop = function () {};

this.element = element;

this.props = props;

this.duration = duration || 600;

this.easing = easing || 'linear';

this.callback = callback || noop;

this.tickID = 0;

this.styles = this.getStyle();

this.animate();

};

Animator.prototype = {

getStyle : function () {

return window.getComputedStyle ? window.getComputedStyle(this.element) : this.element.currentStyle();

},

animate : function () {

for (var prop in this.props) {

this.step.call(this , prop);

}

},

step : function (prop) {

var self = this;

var initialValue = 0;

var beginTime = new Date();

var endValue = parseFloat(this.props[prop]);

var beginValue = parseFloat(this.styles[prop]);

var changeValue = parseFloat(endValue - beginValue);  

var distance = 0;

var move = function () {

var p = (new Date() - beginTime) / self.duration;

if (p > 1) {

self.element.style[prop] = (prop === 'opacity') ? endValue : endValue + 'px';

cancelAnimationFrame(self.tickID);

self.tickID = null;

self.callback.call(self);

} else {

if (self.easing === 'linear') {

distance = changeValue * p;

} else if (self.easing === 'easeIn') {

distance = changeValue * p * p;

} else if (self.easing === 'easeOut') {

distance = changeValue * (2 * p - p * p);

};

self.element.style[prop] = (prop === 'opacity') ? (beginValue + distance) : (beginValue + distance + 'px');

this.tickID = requestAnimationFrame(move);  

}

};

move();

}

};

实例代码


<html lang="en">

<head>

<meta charset="UTF-8">

<title>Document</title>

<style>

*{

margin: 0;

padding: 0;

list-style: none;

}

.box{

width:100px;

height:100px;

background:#f60;

position:absolute;

top:50;

left:0;

border: 1px solid #000;大专栏  帧动画插件iv>
        }

</style>

</head>

<body>

<button id="btn">click</button>

<div id="box" class="box"></div>

<script>

function  (element , props , duration , easing , callback) {

if (typeof element !== 'object' && element.nodeType !== 1) {

return;

};

if (typeof props !== 'object' && props.toString() !== '[object Object]') {

return;

};

var noop = function () {};

this.element = element;

this.props = props;

this.duration = duration || 600;

this.easing = easing || 'linear';

this.callback = callback || noop;

this.tickID = 0;

this.styles = this.getStyle();

this.animate();

};

Animator.prototype = {

getStyle : function () {

return window.getComputedStyle ? window.getComputedStyle(this.element) : this.element.currentStyle();

},

animate : function () {

for (var prop in this.props) {

this.step.call(this , prop);

}

},

step : function (prop) {

var self = this;

var initialValue = 0;

var beginTime = new Date();

var endValue = parseFloat(this.props[prop]);

var beginValue = parseFloat(this.styles[prop]);

var changeValue = parseFloat(endValue - beginValue);  

var distance = 0;

var move = function () {

var p = (new Date() - beginTime) / self.duration;

if (p > 1) {

self.element.style[prop] = (prop === 'opacity') ? endValue : endValue + 'px';

cancelAnimationFrame(self.tickID);

self.tickID = null;

self.callback.call(self);

} else {

if (self.easing === 'linear') {

distance = changeValue * p;

} else if (self.easing === 'easeIn') {

distance = changeValue * p * p;

} else if (self.easing === 'easeOut') {

distance = changeValue * (2 * p - p * p);

};

self.element.style[prop] = (prop === 'opacity') ? (beginValue + distance) : (beginValue + distance + 'px');

this.tickID = requestAnimationFrame(move);  

}

};

move();

}

};

var box = document.querySelector('#box');

var btn = document.querySelector('#btn');

btn.addEventListener('click' , function () {

new Animator(box , {

width : 300,

height : 300,

top : 200,

left : 100,

opacity : 0.5,

borderWidth : 20

});

});

//效果二

btn.addEventListener('click' , function () {

new Animator(box , {

width : 500

} , 1000 , 'easeOut' , function () {

new Animator(box , {

height : 300,

left : 100,

borderWidth : 50

} , 1000 , 'easeIn' , function () {

new Animator(box , {

opacity : 0.6

})

});

});

});

</script>

原文地址:https://www.cnblogs.com/lijianming180/p/12026664.html

时间: 2024-11-07 06:38:38

帧动画插件的相关文章

UGUI 帧动画插件

最近在开发一款功夫猫游戏,本来使用Unity Sprite制作,但是发现Sprite对各种分辨率不支持. 看着游戏很简单就使用UGUI制作,在中途发现有很多帧动画播放,使用了Animation调整使用多了的确很不方便. 于是改成脚本来控制Sprite帧动画切换,慢慢开始形成了写一个插件来调整. 写了两个通宵终于搞定了. O(∩_∩)O~ 效果图: 代码: 组件类: using UnityEngine; using System.Collections; using System.Collecti

程序猿必备的10款web前端动画插件一

1.动画SVG框架幻灯片 在幻灯片之间切换时显示动画SVG帧的实验性幻灯片.不同的形状可以用来创建各种风格. 我们想和大家分享一个实验幻灯片.我们的想法是在从一个幻灯片转换到另一张幻灯片时,使SVG帧动画化.使用不同的形状,我们可以在改变SVG路径时创建各种框架样式.这个想法的灵感是基于Dribbble拍摄:06章太平庸.我们使用的是anime.js的动画. 在线演示 源码下载 2.WebGL的背景装饰 使用WebGL显示为背景的装饰形状的集合.这些形状由Three.js创建,并使用TweenM

3DSMAX 中的CS 骨骼动画插件初探

王玉培 郑利平1 合肥工业大学计算机与信息学院VCC 研究室, 合肥 230009 摘要:首先介绍了3DSMAX 中的CS 骨骼动画制作方法,通过Biped 骨架可以快速方便的制 作两足动物的动画.并介绍了基于3DSMAX SDK 的插件开发,SDK 中类库的组织方式和3DSMAX 的场景组织,最后介绍了和3D引擎密切相关的骨骼动画导出插件的开发过程. 关键词:骨骼动画 插件开发 Biped Preliminary Study on the CS Skeletal Animation Plug-

强大的CSS3/JS:帧动画的多种实现方式与性能对比

Web动画形式 首先我们来了解一下Web有哪些动画形式 1\. CSS3动画 Transform(变形) Transition(过渡) Animation(动画) 2\. JS动画(操作DOM.修改CSS属性值) 3\. Canvas动画 4\. SVG动画 5\. 以Three.js为首的3D动画 以上各种动画形式都可以制作出一种类型的动画,那就是帧动画,也叫序列帧动画,定格动画,逐帧动画等,这里我们统一用帧动画来表述. 这里推荐一下我的前端学习交流扣qun:767273102 ,里面都是学习

逐帧动画-AnimationDrawable的简单用法

将Animation设置为ImageView的backgrond即可 MainActivity.java: import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget

window.requestAnimationFrame() ,做逐帧动画,你值得拥有

window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用. 如果你想做逐帧动画的时候,你应该用这个方法.这就要求你的动画函数执行会先于浏览器重绘动作.通常来说,被调用的频率是每秒60次,但是一般会遵循W3C标准规定的频率.如果是后台标签页面,重绘频率则会大大降低. 基本语法: requestID = window.requestAnimatio

Android 基础的三种动画 帧动画、补间动画、属性动画。

帧动画 drawable   animation 通过xml文件声明一个帧动画 ①在res目录下创建一个drawable目录 把用到的图片资源放到这个目录下 并且创建一个xml文件 根元素  animation-list可以设置一个属性 oneshot如果设置为true 动画只执行一次 执行之后停在最后一帧 animation-list 子元素item <?xml version="1.0" encoding="utf-8"?> 2. <anima

Android动画--帧动画和补间动画

帧动画 首先我们定义在drawable文件夹下定义一个xml文件 里面包含我们要播放的动画的图片,以及每一帧动画的播放的时长 <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mi

实现逐帧动画和补间动画两种动画效果

1.逐帧动画(Frame Animation)通常在Android项目的res/drawable/目录下面定义逐帧动画的XML模板文件.编码的时候,需要在动画模板文件的<animation-list>标签中依次放入需要播放的图片,并设置好播放的间隔时间. <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"