フレームアニメーションプラグイン
40340 ワード
アニメーションプラグインパッケージ
最近ずっとアニメーションの方法についての知识を研究して、正直に言うと确かに容易ではありませんて、主にやはりアニメーションのアルゴリズムのこの方面は比较的に难しくて、结局学んだことがありません.もちろん収穫もあって、基本的なアニメーションの原理が何なのかを理解して、だから自分も1つの簡単なアニメーションのプラグインをカプセル化して自分の学んだことを強固にしました.
アニメーションプラグインの実装方法
フロントエンドにとって、主にアニメーションを実現する方法はcss(transition,animation)、js(settimout,setInterval,requestAnimationFrame)、canvas,svgなどですが、ここでは主にrequestAnimationFrameによってアニメーション効果を実現しています.
プラグインの説明
このプラグインは5つのパラメータを受け入れます.の最初のパラメータは、アニメーションが必要なターゲット要素です. の2番目のパラメータは、アニメーションが必要なプロパティであり、オブジェクトです. の3番目のパラメータは、アニメーションの合計時間です. の4番目のパラメータはアニメーションの効果です.現在、3つのアニメーション効果、linear、easeIn、easeOutがサポートされています. の5番目のパラメータは、アニメーション終了後のコールバック関数です.
このプラグインでは、複数のアトリビュートをアニメートしたり、単一のアトリビュートアニメーション効果を実装したり、1つのアトリビュートから1つのアトリビュートアニメーション効果を実装したりできます.コールバック関数を使用しているため、アニメーション効果を達成するために次から次へとアトリビュートが適用されると、コールバック関数のネストが発生します.
プラグインコード
インスタンスコード
最近ずっとアニメーションの方法についての知识を研究して、正直に言うと确かに容易ではありませんて、主にやはりアニメーションのアルゴリズムのこの方面は比较的に难しくて、结局学んだことがありません.もちろん収穫もあって、基本的なアニメーションの原理が何なのかを理解して、だから自分も1つの簡単なアニメーションのプラグインをカプセル化して自分の学んだことを強固にしました.
アニメーションプラグインの実装方法
フロントエンドにとって、主にアニメーションを実現する方法はcss(transition,animation)、js(settimout,setInterval,requestAnimationFrame)、canvas,svgなどですが、ここでは主にrequestAnimationFrameによってアニメーション効果を実現しています.
プラグインの説明
このプラグインは5つのパラメータを受け入れます.
このプラグインでは、複数のアトリビュートをアニメートしたり、単一のアトリビュートアニメーション効果を実装したり、1つのアトリビュートから1つのアトリビュートアニメーション効果を実装したりできます.コールバック関数を使用しているため、アニメーション効果を達成するために次から次へとアトリビュートが適用されると、コールバック関数のネストが発生します.
プラグインコード
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>