編寫基于Prototype的Javascript動畫類
系統(tǒng)
2076 0
在AJAX如火如荼的今天,相信大家對Prototype這個Javascript類庫應該都有所耳聞,它也的確使編寫Javascript變得更簡單。關于Prototype的文章,《Prototype簡介》、《Prototype源碼》諸如此類數(shù)不勝數(shù);所以本文不會再做這幾方面的介紹,并假設讀者對Prototype有一定了解。
網(wǎng)頁動畫與原理
提到網(wǎng)頁動畫,大家首先想起應該Flash。不知道大家沒有開發(fā)過Flash動畫,故我想對此作一個簡單的介紹(在我讀大學的時候,對Flash也曾有過癡迷,所以也略懂一二)。Flash的動畫主要分兩類:漸變動畫和逐幀動畫。
-
漸類動畫——用戶在時間軸上創(chuàng)建開始的關鍵幀和結束的關鍵幀,開發(fā)環(huán)境(Macromedia Profassional Flash 8等)會根據(jù)以上所創(chuàng)建的關鍵幀的顏色、位置和形狀等,在計算出中間的過渡幀并添加到相應的時間軸上。這適用于創(chuàng)建簡單的動畫。
-
逐幀動畫——用戶在時間軸的每幀上創(chuàng)建關鍵幀,并在其中繪制相應的圖按。這適用于創(chuàng)建復雜的動畫。
在Javascript中由于沒有繪圖API(應用程序接口),故只可以使用DOM+CSS改變元素的外觀。而通過每隔一段時間調(diào)用一次改變元素外觀的函數(shù),實現(xiàn)類似Flash的漸類動畫。
具體實現(xiàn)
因為不同的Javascript動畫實現(xiàn)的基本原理都相同,所以可以創(chuàng)建一個基類將其抽象出來。代碼如下:
var
?
Animation
?
=
?
Class.create();
Animation.prototype
?
=
?
{
?
? ?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?構造函數(shù)
?
? ? |
?
? ? | 參數(shù):
?
? ? | ? ?element 將要實現(xiàn)動畫效果的元素
?
? ? | ? ?fps ? ? 每秒播放幀數(shù)
?
? ? ------------------------------------------------------------------------
*/
?
? ?
?
? ?initialize:
?
function
(element, fps)
?
{
?
? ? ? ?
this
.element
?
=
?
$(element);
?
? ? ? ?
this
.interval
?
=
?
Math.round(
1000
?
/
?
fps);
?
? ? ? ?
?
? ? ? ?
this
.isPlaying
?
=
?
false
;
?
? ? ? ?
this
.currentFrame
?
=
?
1
; ??
?
? ? ? ?
?
? ? ? ?
//
創(chuàng)建一個用于存儲中間狀態(tài)的臨時對象
?
? ? ? ?
this
.temp
?
=
?
{ }
; ? ? ? ? ? ??
?
? ?}
,
?
? ?
?
? ?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?子類覆蓋該方法,實現(xiàn)自定義的動畫補間
?
? ? ------------------------------------------------------------------------
*/
?
? ?
?
? ?_createTweens:
?
function
(original, transformed, frames)
?
{ }
,
?
? ?
?
? ?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?創(chuàng)建動畫補間
?
? ? |
?
? ? | 參數(shù):
?
? ? | ? ?original ? ?開始狀態(tài)
?
? ? | ? ?transformed 結束狀態(tài)
?
? ? | ? ?frames ? ? ?動畫幀數(shù)
?
? ? ------------------------------------------------------------------------
*/
?
? ?
?
? ?createTweens:
?
function
(original, transformed, frames)
?
{
?
? ? ? ?
if
(
this
.isPlaying)
?
{
?
? ? ? ? ? ?
this
.stop();
?
? ? ? ?}
?
? ? ? ?
?
? ? ? ?
this
._createTweens(original, transformed, frames);
?
? ? ? ? ? ?
?
? ? ? ?
this
.original
?
=
?
original;
?
? ? ? ?
this
.transformed
?
=
?
transformed;
?
? ? ? ?
this
.frames
?
=
?
frames;
?
? ? ? ?
?
? ? ? ?
//
將開始狀態(tài)拷貝到臨時對象
?
? ? ? ?Object.extend(
this
.temp, original); ? ? ? ?
?
? ?}
,
?
? ?
?
? ?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?判斷臨時對象狀態(tài)是否超出結束狀態(tài)
?
? ? |
?
? ? | 參數(shù):
?
? ? | ? ?prop 狀態(tài)屬性名稱
?
? ? ------------------------------------------------------------------------
*/
?
??
?
? ?_isOverstep:
?
function
(prop)
?
{
?
? ? ? ?
if
(
this
.original[prop]
?
<
?
this
.transformed[prop])
?
{
?
? ? ? ? ? ?
return
?
this
.temp[prop]
?
>
?
this
.transformed[prop]; ?
?
? ? ? ?}
?
?
? ? ? ?
return
?
this
.temp[prop]
?
<
?
this
.transformed[prop];
?
? ?}
,?
?
? ?
?
? ?_prepare:
?
function
()
?
{ }
,
?
? ?
?
? ?_draw:
?
function
(frame)
?
{ }
,
?
? ?
?
? ?_drawFrame:
?
function
()
?
{
?
? ? ? ?
if
(
this
.isPlaying)
?
{
?
? ? ? ? ? ?
if
(
this
.currentFrame
?
<
?
this
.frames)
?
{ ? ? ? ? ? ? ? ?
?
? ? ? ? ? ? ? ?
this
._prepare();
?
? ? ? ? ? ? ? ?
this
._draw(
this
.temp);
?
? ? ? ? ? ? ? ?
?
? ? ? ? ? ? ? ?
this
.currentFrame
?
++
;
?
? ? ? ? ? ?}
?
else
?
{
?
? ? ? ? ? ? ? ?
//
最后一幀繪制結束狀態(tài) ? ? ? ? ? ?
?
? ? ? ? ? ? ? ?
this
._draw(
this
.transformed);
?
? ? ? ? ? ? ? ?
this
.stop();
?
? ? ? ? ? ?}
?
? ? ? ?}
?
? ?}
,
?
? ?
?
? ?_play:
?
function
()
?
{ }
,
?
? ?
?
? ?play:
?
function
()
?
{
?
? ? ? ?
if
(
!
this
.isPlaying)
?
{
?
? ? ? ? ? ?
this
._play();
?
? ? ? ? ? ?
?
? ? ? ? ? ?
this
.isPlaying
?
=
?
true
;
?
? ? ? ? ? ?
this
.timer
?
=
?
setInterval(
this
._drawFrame.bind(
this
),
?
this
.interval); ? ? ? ? ? ?
?
? ? ? ?}
?
? ?}
,
?
? ?
?
? ?_stop:
?
function
()
?
{ }
,
?
? ?
?
? ?stop:
?
function
()
?
{
?
? ? ? ?
if
(
this
.isPlaying)
?
{
?
? ? ? ? ? ?
this
._stop();
?
? ? ? ? ? ?
?
? ? ? ? ? ?
//
回到開始狀態(tài)
?
? ? ? ? ? ?
this
.isPlaying
?
=
?
false
;
?
? ? ? ? ? ?
this
.currentFrame
?
=
?
1
;
?
? ? ? ? ? ?
?
? ? ? ? ? ?Object.extend(
this
.temp,
?
this
.original);
?
? ? ? ? ? ?clearInterval(
this
.timer);
?
? ? ? ?}
?
? ?}
,
?
? ?
?
? ?_pause:
?
function
()
?
{ }
,
?
? ?
?
? ?pause:
?
function
()
?
{
?
? ? ? ?
if
(
this
.isPlaying)
?
{ ? ? ?
?
? ? ? ? ? ?
this
._pause();
?
? ? ? ? ? ? ? ? ?
?
? ? ? ? ? ?
this
.isPlaying
?
=
?
false
;
?
? ? ? ? ? ?clearInterval(
this
.timer);
?
? ? ? ?}
?
? ?}
}
清單1 Animation.js
Animation類實現(xiàn)了一些公用的管理內(nèi)部狀態(tài)的操作,如播放動畫、停止動畫和暫停動畫等。接下來,創(chuàng)建特定的動畫變得相當容易了,下面讓我們來看一個形狀和位置漸變的動畫實現(xiàn),代碼如下:
var
?
ShapeAnimation
?
=
?
Class.create();
ShapeAnimation.prototype
?
=
?
Object.extend(
new
?
Animation(),
?
{
?
??
?
?
?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?覆蓋父類的空白實現(xiàn),計算每幀的變化量
?
? ? ------------------------------------------------------------------------
*/
?
? ?
?
? ?_createTweens:
?
function
(original, transformed, frames)
?
{
?
? ? ? ?
this
.xSpan
?
=
?
Math.round((transformed.x
?
-
?
original.x)
?
/
?
frames);
?
? ? ? ?
this
.ySpan
?
=
?
Math.round((transformed.y
?
-
?
original.y)
?
/
?
frames);
?
? ? ? ?
this
.wSpan
?
=
?
Math.round((transformed.w
?
-
?
original.w)
?
/
?
frames);
?
? ? ? ?
this
.hSpan
?
=
?
Math.round((transformed.h
?
-
?
original.h)
?
/
?
frames);
?
? ?}
,
?
? ?
?
? ?
/*
------------------------------------------------------------------------
?
? ? | 用途:
?
? ? | ? ?覆蓋父類的空白實現(xiàn),計算當前的狀態(tài)。如果超出結束狀態(tài),保持結束狀態(tài)不變
?
? ? ------------------------------------------------------------------------
*/
?
? ?_prepare:
?
function
()
?
{?
?
? ? ? ?
this
.temp.x
?
=
?
this
._isOverstep('x')
?
?
?
this
.transformed.x :
?
this
.temp.x
?
+
?
this
.xSpan;
?
? ? ? ?
this
.temp.y
?
=
?
this
._isOverstep('r')
?
?
?
this
.transformed.y :
?
this
.temp.y
?
+
?
this
.ySpan;
?
? ? ? ?
this
.temp.w
?
=
?
this
._isOverstep('w')
?
?
?
this
.transformed.w :
?
this
.temp.w
?
+
分享到:
編寫基于Prototype的Javascript動畫類
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
評論