Home > Web Front-end > JS Tutorial > A brief analysis of javascript animation_javascript skills

A brief analysis of javascript animation_javascript skills

WBOY
Release: 2016-05-16 17:50:29
Original
1082 people have browsed it
애니메이션의 원리

소위 애니메이션은 일련의 움직임을 통해 형성된 움직이는 그림이다. 웹 페이지에서는 요소의 CSS 값을 지속적으로 변경하여 동적 효과를 얻을 수 있습니다.

사용된 공식

총 거리 S = 총 시간 T * 속도 V, 즉: V = S/T
현재 거리 s = S/T * 경과 시간 t, 즉 는: s = S * (t/T)
즉, 현재 거리 = 총 거리 * (경과 시간/총 시간)
즉, 애니메이션 요소 시작 값(애니메이션 요소 끝 값 - 애니메이션 요소 시작 값)입니다. ) * ( 현재 시간 - 시작 시간) / (애니메이션에 필요한 시간) 값 형식

위 수식을 사용하면 JavaScript의 setInterval 또는 setTimeout을 사용하여 간단한 애니메이션을 만들 수 있습니다.
그러나 애니메이션 라이브러리를 구축하려면 다른 요소도 고려해야 합니다. 예를 들어 동일한 요소의 애니메이션은 순차적으로 실행되어야 합니다. 다양한 요소의 애니메이션을 동시에 실행할 수 있습니다.

이 경우 이러한 애니메이션을 관리하려면 다른 개체를 사용해야 합니다. 나의 초기 아이디어는 각 요소를 배열에 넣고 여러 setInterval을 사용하여 배열의 애니메이션 기능을 반복하고 하나씩 실행하는 것이었습니다.

animate1 = [{elem,fn},{elem,fn}];
animate2 = [{elem,fn},{elem,fn}]

달성하면 동일한 요소 애니메이션이 순차적으로 실행되는 반면, 다른 요소 애니메이션은 동시에 실행될 수 있습니다. 하지만 여기에는 문제가 있습니다. 즉, 애니메이션의 요소가 10개 이상인 경우입니다. 프로그램은 10개의 setInterval을 열어야 합니다.

이러한 상황을 방지하기 위해 위 내용을 바탕으로 몇 가지 개선 작업을 진행했습니다. 따라서 애니메이션이 아무리 많아도 마찬가지입니다. 모두 setInterval을 사용하여 수행됩니다. 수정된 구조는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

[
[elem ,[fn ,fn,fn,fn]],
[요소,[fn,fn,fn,fn]],
[요소,[fn,fn,fn,fn]]
]


이런 방식으로 setInterval을 사용하여 모든 애니메이션을 완성할 수 있습니다. 수행해야 할 작업은 elem을 반복하고 elem 이후 요소의 첫 번째 fn을 실행하는 것입니다. fn을 삭제합니다. 다음 fn을 호출합니다. 모든 fn이 비어 있으면 큰 배열에서 elem을 삭제합니다. elem이 비어 있으면 setInterval을 지웁니다. 그러면 논리가 이해가 될 것입니다.

그러나 애니메이션에서 가장 중요한 또 하나의 요소가 있는데 바로 완화입니다. 완화가 없으면 애니메이션이 매우 경직된 것처럼 보입니다. 동일성. 현재 js 애니메이션에는 많은 여유 알고리즘이 사용되며 이는 대략 두 가지 범주로 나눌 수 있습니다.
하나는 플래시 클래스이고 다른 하나는 프로토타입 클래스입니다.

flash에는 4개의 매개변수가 필요합니다.
1. 시간의 초기 시간 t
2. 애니메이션의 초기 값 b
3. 애니메이션의 종료 값 c
4. 🎜>다음은 Flash 유형의 균일 모션 알고리즘입니다.
Linear: function(t,b,c,d){ return c*t/d b; }
다른 하나는 프로토타입입니다. 하나, 그러면 현재 시간 t와 기간 d의 비율(t/d)입니다.
두 번째 방법은 매개변수가 편리하기 때문에 사용했습니다. 또한 위의 애니메이션 공식에 더 적합합니다. 다음은 프로토타입 균일 모션 알고리즘
linear: function(t){ return t;}입니다.
easing을 추가하면 위의 공식은
애니메이션 요소가 됩니다. 시작 값(애니메이션 요소 종료 값 - 애니메이션 요소 시작 값) * 완화 함수((현재 시간 - 시작 시간) / (애니메이션 필요 시간)) 값 형식입니다.
이제 전체 애니메이션 디자인이 끝났습니다. 다른 분들의 블로그를 참고해서 감사의 말씀을 전하고 싶습니다.
마지막으로 자세한 코드를 올려드리겠습니다.

코드 복사 코드는 다음과 같습니다.

/**
* 생성시간 2012/08/29
* @author lynx cat.
* @version 0.77beta.
*/

(function(win,doc){
var win = win || window;
var doc = doc || win. document,
pow = Math.pow,
sin = Math.sin,
PI = Math.PI,
BACK_CONST = 1.70158
var Easing = {
// 匀速运动
linear: function(t){
return t;
},
easeIn: function(t) {
return t * t
},
easeOut: 함수 (t) {
return ( 2 - t) * t
},
easeBoth : function (t) {
return (t *= 2)
.5 * t * t :
.5 * (1 - (--t) * (t - 2))
},
easeInStrong : function (t) {
return t * t * t * t
},
easeOutStrong: 함수(t) {
return 1 - (--t) * t * t * t
},
easeBothStrong: 함수(t ) {
반환 (t *= 2) < 1 ?
.5 * t * t * t * t :
.5 * (2 - (t -= 2) * t * t * t);
},
easeOutQuart : function(t){
return -(pow((t-1), 4) -1)
},
easeInOutExpo : function(t ){
if(t===0) return 0;
if(t===1) return 1
if((t/=0.5) < 1) return 0.5 * pow( 2,10 * (t-1));
return 0.5 * (-pow(2, -10 * --t) 2)
},
easeOutExpo : function(t){
반환 (t===1) ? 1 : -pow(2, -10 * t) 1;
},
swingFrom : function(t) {
return t*t*((BACK_CONST 1)*t - BACK_CONST);
},
swingTo: function(t) {
return (t-=1)*t*((BACK_CONST 1)*t BACK_CONST) 1;
},
sinusoidal : function(t) {
return (-Math.cos(t*PI)/2) 0.5;
},
flicker : function(t) {
var t = t (Math.random()-0.5)/5;
return this.sinusoidal(t 1 ? 1 : t);
},
backIn : function (t) {
if (t === 1) t -= .001;
t * t * ((BACK_CONST 1) * t - BACK_CONST)를 반환합니다.
},
backOut : 함수 (t) {
return (t -= 1) * t * ((BACK_CONST 1) * t BACK_CONST) 1;
},
bounce : 함수(t) {
var s = 7.5625, r;
if (t r = s * t * t;
}
else if (t r = s * (t -= (1.5 / 2.75)) * t .75;
}
else if (t r = s * (t -= (2.25 / 2.75)) * t .9375;
}
else {
r = s * (t -= (2.625 / 2.75)) * t .984375;
}
r을 반환합니다.
}
};
/**
* 대화 메소드가 포함된 객체를 반환하는 데 사용되는 Cornerstone
* @param elem
* @return {Object}
*/
function catfx(elem){
elem = elem 유형 === 'string' ? doc.getElementById(elem) : 요소;
새 fx(elem)를 반환합니다.
}
/**
* 대화 메소드가 포함된 객체를 반환하는 데 사용되는 내부 초석
* @param elem
* @return {Object}
*/
function fx(elem){
this.elem = elem;
이것을 돌려주세요;
}
/**
* 기본 클래스에는 몇 가지 기본 메서드와 불변값이 포함되어 있습니다
*/
var fxBase = {
속도: {
느림: 600,
빠름: 200,
기본값: 400
},
fxAttrs : [],
fxMap:[],
/**
* 객체 요소의 CSS 값을 반환합니다.
* @param elem
* @param p
* @return css value
*/
getStyle : function(){
var fn = function (){} ;
if('getCompulatedStyle' in win){
fn = function(elem, p){
var p = p.replace(/-(w)/g,function(i,str){
return str.toUpperCase()
});
var val = getCompulatedStyle(elem, null)[p];
if(~(' ' p ' ').indexOf(' 왼쪽 오른쪽 위 아래 ') && val === 'auto'){
val = '0px';
}
반환 값;
}
}else {
fn = function(elem, p){
var p = p.replace(/-(w)/g,function(i,str){
return str.toUpperCase()
});
var val = elem.currentStyle[p];
if(~(' ' p ' ').indexOf(' width height') && val === 'auto'){
var ect = elem.getBoundingClientRect();
val = ( p === '너비' ? REC.오른쪽 - REC.왼쪽 : REC.하단 - REC.TOP ) 'px';
}
if(p === '불투명도'){
var filter = elem.currentStyle.filter;
if( /opacity/.test(filter) ){
val = filter.match( /d / )[0] / 100;
val = (val === 1 || val === 0) ? val.toFixed(0) : val.toFixed(1);
}else if( val === 정의되지 않음 ){
val = 1;
}
}
if(~(' ' p ' ').indexOf(' 왼쪽 오른쪽 위 아래 ') && val === 'auto'){
val = '0px';
}
반환 값;
}
}
fn을 반환;
}(),
/**
* 객체 요소의 CSS 값을 반환합니다
* @param 색상 값(red, pink, blue 및 기타 영문은 아직 지원되지 않음)
* @return rgb(x,x,x)
*/
getColor : function(val){
var r, g, b;
if(/rgb/.test(val)){
var arr = val.match(/d /g);
r = arr[0];
g = arr[1];
b = arr[2];
}else if(/#/.test(val)){
var len = val.length;
if( len === 7 ){
r =parseInt( val.slice(1, 3), 16);
g =parseInt(val.slice(3, 5), 16);
b =parseInt(val.slice(5), 16);
}
else if( len === 4 ){
r =parseInt(val.charAt(1) val.charAt(1), 16);
g = parsInt(val.charAt(2) val.charAt(2), 16);
b = parsInt(val.charAt(3) val.charAt(3), 16);
}
}else{
return val;
}
return {
r:parseFloat(r),
g:parseFloat(g),
b:parseFloat(b)
}
},
/**
* Return the parsed css
* @param prop
* @return {val:val,unit:unit}
*/
parseStyle : function(prop){
var val = parseFloat(prop),
unit = prop.replace(/^[-d.] /, '');
if(isNaN(val)){
val = this.getColor(unit);
unit = '';
}
return {val : val, unit : unit};
},
/**
* Set the transparency of the element
* @param elem
* @param val
*/
setOpacity : function(elem, val){
if( 'getComputedStyle' in win ){
elem.style.opacity = val === 1 ? '' : val;
}else{
elem.style.zoom = 1;
elem.style.filter = val === 1 ? '' : 'alpha(opacity=' val * 100 ')';
}
},
/**
* Set the css value of the element
* @param elem
* @param prop
* @param val
*/
setStyle : function(elem, prop, val){
if(prop != 'opacity'){
prop = prop.replace(/-(w)/g,function(i,p){
return p.toUpperCase();
});
elem.style[prop] = val;
}else{
this.setOpacity(elem, val);
}
},
/**
* Return the parsed prop
* @param prop
* @return {prop}
*/
parseProp : function(prop){
var props = {};
for(var i in prop){
props[i] = this.parseStyle(prop[i].toString());
}
return props;
},
/**
* Correct user parameters
* @param elem
* @param duration
* @param easing
* @param callback
* @return {options}
*/
setOption : function(elem,duration, easing, callback){
var options = {};
var _this = this;
options.duration = function(duration){
if(typeof duration == 'number'){
return duration;
}else if(typeof duration == 'string' && _this.speed[duration]){
return _this.speed[duration];
}else{
return _this.speed.defaults;
}
}(duration);
options.easing = function(easing){
if(typeof easing == 'function'){
return easing;
}else if(typeof easing == 'string' && Easing[easing]){
return Easing[easing];
}else{
return Easing.linear;
}
}(easing);
options.callback = function(callback){
var _this = this;
return function (){
if(typeof callback == 'function'){
callback.call(elem);
}
}
}(callback)
return options;
},
/**
* Maintain setInterval function and start animation
*/
tick : function(){
var _this = this;
if(!_this.timer){
_this.timer = setInterval(function(){
for(var i = 0, len = _this.fxMap.length; i < len; i ){
var elem = _this.fxMap[i][0];
var core = _this.data(elem)[0];
core(elem);
}
},16);
}
},
/**
* Stop all animations
*/
stop : function(){
if(this.timer){
clearInterval(this.timer);
this.timer = undefined;
}
},
/**
* Store or take out the queue
* @param elem
*/
data : function(elem){
for(var i = 0, len = this.fxMap.length; i < len; i ){
var data = this.fxMap[i];
if(elem === data[0]){
return data[1];
}
}
this.fxMap.push([elem,[]]);
return this.fxMap[this.fxMap.length - 1][1];
},
/**
* Delete queue
* @param elem
*/
removeData : function(elem){
for(var i = 0, len = this.fxMap.length; i < len; i ){
var data = this.fxMap[i];
if(elem === data[0]){
this.fxMap.splice(i, 1);
if(this.isDataEmpty()){
this.stop();
}
}
}
},
isDataEmpty : function(){
return this.fxMap.length == 0;
}
}, $ = fxBase;
/**
* Core object, used to generate animation objects.
* @param elem
* @param props
* @param options
* @return {Object}
*/
function fxCore(elem, props, options){
this.elem = elem;
this.props = props;
this.options = options;
this.start();
}
fxCore.prototype = {
constructor : fxCore,
/**
* Add the animation function to the queue and start the animation.
*/
start : function(){
var cores = $.data(this.elem);
cores.push(this.step());
$.tick();
},
/**
* 核心方法,控制每一帧元素的状态。
* @return 함수
*/
step : function(){
var _this = this;
var fn = function(elem){
var t = Date.now() - this.startTime;
if(Date.now() < this.startTime this.options.duration){
if(t <= 1){ t = 1;}
for(this.target의 var i ){
if(typeof this.source[i]['val'] === 'number'){
var val =parseFloat((this.source[i]['val'] (this. target[i]['val'] - this.source[i]['val']) * this.options.easing(t / this.options.duration)).toFixed(7));
}else{
var r =parseInt(this.source[i]['val']['r'] (this.target[i]['val']['r'] - this. source[i]['val']['r']) * this.options.easing(t / this.options.duration));
var g =parseInt(this.source[i]['val']['g'] (this.target[i]['val']['g'] - this.source[i][' val']['g']) * this.options.easing(t / this.options.duration));
var b =parseInt(this.source[i]['val']['b'] (this.target[i]['val']['b'] - this.source[i][' val']['b']) * this.options.easing(t / this.options.duration));
var val = 'rgb(' r ',' g ',' b ')';
}
$.setStyle(this.elem,i,val this.source[i]['unit']);
}
}else{
for(var i in this.target){
if(typeof this.target[i]['val'] === 'number'){
var val = this.target[i]['val'];
}else{
var val = 'rgb(' this.target[i]['val']['r'] ',' this.target[i]['val']['g' ] ',' this.target[i]['val']['b'] ')';
}
$.setStyle(elem,i,val this.source[i]['unit']);
}
var cores = $.data(elem);
cores.shift();
this.options.callback();
if(cores.length == 0){
$.setStyle(elem,'overflow',this.overflow);
$.removeData(elem);
}
}
}
반환 함수(elem){
if(!_this.startTime){
var source = {};
_this.target = _this.props;
for(var i in _this.props){
var val = $.getStyle(_this.elem, i);
소스[i] = $.parseStyle(val);
}
_this.source = 소스;
_this.startTime = Date.now();
_this.overflow = $.getStyle(elem,'overflow');
$.setStyle(elem,'overflow','hidden');
}
fn.call(_this,elem);
}
}
}
/**
* 외부 인터페이스 클래스.
*/
fx.prototype = {
constructor : fx,
/**
* 애니메이션 메소드
* @param prop
* @param 기간
* @param easing
* @param 콜백
* @return {Object}
*/
animate: function(prop, Duration, easing, callback){
if(arguments.length == 3 && typeof easing === 'function'){ //多数时候用户第三个参数是回调
콜백 = 완화;
완화 = 정의되지 않음;
}
var props = $.parseProp(prop);
var options = $.setOption(this.elem,duration,easing,callback);
var core = new fxCore(this.elem,props,options);
이것을 돌려주세요;
},
/**
* 애니메이션 중지 방법
* catjs('your element id').stop() 방법 사용
*/
stop : function(){
$.removeData(this.elem);
}
}
win.catfx = catfx;
})(이 문서);

使用起来也比较简单.直接catfx('ID').animate({'margin-left':200,'Background-color':'#ff0000'},600,'easeOut ',기능(){});

jquery의 사용 방법은 다양하지 않습니다.数为函数,并且总共只有三个参数时。第三个参数为回调。

例:catfx('ID').animate({'margin-left':200,'Background-color':'#ff0000'},600,function (){alert('洒家是回调函数~')});
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template