<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-34  評論-1965  文章-0  trackbacks-0

    這段時間身體欠佳,經常頭暈。醫生說并無大礙,可我服了藥也不見有多少好轉。因此我很久沒有更新Blog了。

    針對大家關于Struts 2的問題,我正著手開發一個應用程序例子。這個例子以ASP.NET的“Personal Web Site Stater Kit”應用程序作為藍本,采用“Spring 2 + Hiberante 3 + Struct 2”架構(姑且稱之:-)),并且會以“prototype+DWR”為基礎實現AJAX。

    在AJAX如火如荼的今天,相信大家對Prototype這個Javascript類庫應該都有所耳聞,它也的確使編寫Javascript變得更簡單。關于Prototype的文章,《Prototype簡介》、《Prototype源碼》諸如此類數不勝數;所以本文不會再做這幾方面的介紹,并假設讀者對Prototype有一定了解。

    網頁動畫與原理

    提到網頁動畫,大家首先想起應該Flash。不知道大家沒有開發過Flash動畫,故我想對此作一個簡單的介紹(在我讀大學的時候,對Flash也曾有過癡迷,所以也略懂一二)。Flash的動畫主要分兩類:漸變動畫和逐幀動畫。

    • 漸類動畫——用戶在時間軸上創建開始的關鍵幀和結束的關鍵幀,開發環境(Macromedia Profassional Flash 8等)會根據以上所創建的關鍵幀的顏色、位置和形狀等,在計算出中間的過渡幀并添加到相應的時間軸上。這適用于創建簡單的動畫。
    • 逐幀動畫——用戶在時間軸的每幀上創建關鍵幀,并在其中繪制相應的圖按。這適用于創建復雜的動畫。

    在Javascript中由于沒有繪圖API(應用程序接口),故只可以使用DOM+CSS改變元素的外觀。而通過每隔一段時間調用一次改變元素外觀的函數,實現類似Flash的漸類動畫。

    具體實現

    因為不同的Javascript動畫實現的基本原理都相同,所以可以創建一個基類將其抽象出來。代碼如下:

    var Animation = Class.create();
    Animation.prototype
    = {
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?構造函數
    ? ? |
    ? ? | 參數:
    ? ? | ? ?element 將要實現動畫效果的元素
    ? ? | ? ?fps ? ? 每秒播放幀數
    ? ? ------------------------------------------------------------------------
    */
    ? ?
    ? ?initialize:
    function (element, fps) {
    ? ? ? ?
    this .element = $(element);
    ? ? ? ?
    this .interval = Math.round( 1000 / fps);
    ? ? ? ?
    ? ? ? ?
    this .isPlaying = false ;
    ? ? ? ?
    this .currentFrame = 1 ; ??
    ? ? ? ?
    ? ? ? ?
    // 創建一個用于存儲中間狀態的臨時對象
    ? ? ? ? this .temp = { } ; ? ? ? ? ? ??
    ? ?}
    ,
    ? ?
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?子類覆蓋該方法,實現自定義的動畫補間
    ? ? ------------------------------------------------------------------------
    */
    ? ?
    ? ?_createTweens:
    function (original, transformed, frames) { } ,
    ? ?
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?創建動畫補間
    ? ? |
    ? ? | 參數:
    ? ? | ? ?original ? ?開始狀態
    ? ? | ? ?transformed 結束狀態
    ? ? | ? ?frames ? ? ?動畫幀數
    ? ? ------------------------------------------------------------------------
    */
    ? ?
    ? ?createTweens:
    function (original, transformed, frames) {
    ? ? ? ?
    if ( this .isPlaying) {
    ? ? ? ? ? ?
    this .stop();
    ? ? ? ?}

    ? ? ? ?
    ? ? ? ?
    this ._createTweens(original, transformed, frames);
    ? ? ? ? ? ?
    ? ? ? ?
    this .original = original;
    ? ? ? ?
    this .transformed = transformed;
    ? ? ? ?
    this .frames = frames;
    ? ? ? ?
    ? ? ? ?
    // 將開始狀態拷貝到臨時對象
    ? ? ? ?Object.extend( this .temp, original); ? ? ? ?
    ? ?}
    ,
    ? ?
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?判斷臨時對象狀態是否超出結束狀態
    ? ? |
    ? ? | 參數:
    ? ? | ? ?prop 狀態屬性名稱
    ? ? ------------------------------------------------------------------------
    */
    ??
    ? ?_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 {
    ? ? ? ? ? ? ? ?
    // 最后一幀繪制結束狀態 ? ? ? ? ? ?
    ? ? ? ? ? ? ? ? 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();
    ? ? ? ? ? ?
    ? ? ? ? ? ?
    // 回到開始狀態
    ? ? ? ? ? ? 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類實現了一些公用的管理內部狀態的操作,如播放動畫、停止動畫和暫停動畫等。接下來,創建特定的動畫變得相當容易了,下面讓我們來看一個形狀和位置漸變的動畫實現,代碼如下:

    var ShapeAnimation = Class.create();
    ShapeAnimation.prototype
    = Object.extend( new Animation(), {
    ??
    ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?覆蓋父類的空白實現,計算每幀的變化量
    ? ? ------------------------------------------------------------------------
    */
    ? ?
    ? ?_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);
    ? ?}
    ,
    ? ?
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?覆蓋父類的空白實現,計算當前的狀態。如果超出結束狀態,保持結束狀態不變
    ? ? ------------------------------------------------------------------------
    */

    ? ?_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 + this .wSpan;
    ? ? ? ?
    this .temp.h = this ._isOverstep('h') ? this .transformed.h : this .temp.h + this .hSpan;
    ? ?}
    ,
    ? ?
    ? ?
    /* ------------------------------------------------------------------------
    ? ? | 用途:
    ? ? | ? ?覆蓋父類的空白實現,刷新元素外觀
    ? ? ------------------------------------------------------------------------
    */

    ? ?_draw:
    function (frame) {
    ? ? ? ?
    var x = frame.x + 'px';
    ? ? ? ?
    var y = frame.y + 'px';
    ? ? ? ?
    var w = frame.w + 'px';
    ? ? ? ?
    var h = frame.h + 'px'; ? ? ? ?
    ? ? ? ?
    ? ? ? ?Element.setStyle(
    this .element, { left: x, top: y, width: w, height: h } );
    ? ?}

    ? ?
    }
    );
    清單2 ShapeAnimation.js

    ShapeAnimation類繼承Animation類,并覆蓋了其中的某些方法。最后,讓我們創建HTML文件,測試一下這個ShapeAnimation是否可以正確工作。代碼如下:

    <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
    < html xmlns ="http://www.w3.org/1999/xhtml" >
    < head >
    ? ?
    < title > ShapeAnimation Test </ title >

    ? ?
    < script type ="text/javascript" src ="prototype-1.4.0.js" ></ script >
    ? ?
    < script type ="text/javascript" src ="Animation.js" ></ script >
    ? ?
    < script type ="text/javascript" src ="ShapeAnimation.js" ></ script >

    ? ?
    < script type ="text/javascript" > ?
    ? ? ? ?
    var animation; ?
    ? ? ? ??
    ? ? ? ? Event.observe(window, 'load', init,
    false );
    ? ? ? ??
    ? ? ? ?
    function init() {
    ? ? ? ? ? ?
    var clip = $('clip');
    ? ? ? ? ? ?
    var pos = Position.cumulativeOffset(clip); ? ? ? ? ? ?
    ? ? ? ? ? ??
    ? ? ? ? ? ? animation
    = new ShapeAnimation(clip, 12 );
    ? ? ? ? ? ? animation.createTweens( { x: pos[
    0 ], y: pos[ 1 ], w: 100 , h: 75 },
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { x:
    100 , y: 100 , w: 200 , h: 200 },
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    24 );
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function play() { ? ? ? ? ? ?
    ? ? ? ? ? ? animation.play(); ? ? ? ? ? ?
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function stop() {
    ? ? ? ? ? ? animation.stop(); ? ??
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function pause() {
    ? ? ? ? ? ? animation.pause(); ? ?
    ? ? ? ? }
    ? ?
    </ script >
    </ head >
    < body >
    ? ?
    < input type ="button" onclick ="play()" value ="Play" />
    ? ?
    < input type ="button" onclick ="stop()" value ="Stop" />
    ? ?
    < input type ="button" onclick ="pause()" value ="Pause" />< br />
    ? ?
    < br />
    ? ?
    < img src ="thumb.jpg" alt ="Thumb" id ="clip" style ="left: 13px; position: absolute; top: 52px;" />
    </ body >
    </ html >
    清單3 ShapeAnimationTest.htm

    分別在IE或Firefox中打開ShapeAnimationTest.htm,播擊“Play”、“Stop”和“Pause”按鈕工作正常。

    舉一反三

    上述例子,我創建了形狀動畫類。有了Animation類作為基類,當然我可以容易地創建更多的動畫類。下面我再舉一個裁剪動畫示例。代碼如下:

    var ClipAnimation = Class.create();
    ClipAnimation.prototype
    = Object.extend( new Animation(), {
    ??
    ? ?_createTweens:
    function (original, transformed, frames) {
    ? ? ? ?
    this .tSpan = Math.round((transformed.t - original.t) / frames);
    ? ? ? ?
    this .rSpan = Math.round((transformed.r - original.r) / frames);
    ? ? ? ?
    this .bSpan = Math.round((transformed.b - original.b) / frames);
    ? ? ? ?
    this .lSpan = Math.round((transformed.l - original.l) / frames);
    ? ?}
    ,
    ? ?
    ? ?_prepare:
    function () {?
    ? ? ? ?
    this .temp.t = this ._isOverstep('t') ? this .transformed.t : this .temp.t + this .tSpan;
    ? ? ? ?
    this .temp.r = this ._isOverstep('r') ? this .transformed.r : this .temp.r + this .rSpan;
    ? ? ? ?
    this .temp.b = this ._isOverstep('b') ? this .transformed.b : this .temp.b + this .bSpan;
    ? ? ? ?
    this .temp.l = this ._isOverstep('l') ? this .transformed.l : this .temp.l + this .lSpan;
    ? ?}
    ,
    ? ?
    ? ?_draw:
    function (frame) {
    ? ? ? ?
    var clipStyle = 'rect(' + frame.t + 'px ';
    ? ? ? ?clipStyle
    = clipStyle + frame.r + 'px ';
    ? ? ? ?clipStyle
    = clipStyle + frame.b + 'px ';
    ? ? ? ?clipStyle
    = clipStyle + frame.l + 'px)'; ? ?
    ? ? ? ?
    ? ? ? ?Element.setStyle(
    this .element, { clip: clipStyle } );
    ? ?}

    ? ?
    }
    );
    清單4 ClipAnimation.js

    測試文件代碼如下:

    <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
    < html xmlns ="http://www.w3.org/1999/xhtml" >
    < head >
    ? ?
    < title > Untitled Page </ title >

    ? ?
    < script type ="text/javascript" src ="prototype-1.4.0.js" ></ script >
    ? ?
    < script type ="text/javascript" src ="Animation.js" ></ script >
    ? ?
    < script type ="text/javascript" src ="ClipAnimation.js" ></ script >

    ? ?
    < script type ="text/javascript" > ?
    ? ? ? ?
    var animation; ?
    ? ? ? ??
    ? ? ? ? Event.observe(window, 'load', init,
    false );
    ? ? ? ??
    ? ? ? ?
    function init() {
    ? ? ? ? ? ?
    var clip = $('clip');
    ? ? ? ? ? ?
    var pos = Position.cumulativeOffset(clip);
    ? ? ? ? ? ?
    var dimensions = Element.getDimensions(clip);
    ? ? ? ? ? ??
    ? ? ? ? ? ? animation
    = new ClipAnimation(clip, 12 );
    ? ? ? ? ? ? animation.createTweens( { t:
    0 , r: dimensions.width, b: Element.getHeight(clip), l: 0 },
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { t:
    0 , r: dimensions.width, b: 0 , l: 0 },
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    24 );
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function play() { ? ? ? ? ? ?
    ? ? ? ? ? ? animation.play();
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function stop() {
    ? ? ? ? ? ? animation.stop(); ? ??
    ? ? ? ? }
    ? ? ? ??
    ? ? ? ?
    function pause() {
    ? ? ? ? ? ? animation.pause(); ? ?
    ? ? ? ? }
    ? ?
    </ script >
    </ head >
    < body >
    ? ?
    < input type ="button" onclick ="play()" value ="Play" />
    ? ?
    < input type ="button" onclick ="stop()" value ="Stop" />
    ? ?
    < input type ="button" onclick ="pause()" value ="Pause" />< br />
    ? ?
    < br />
    ? ?
    < img src ="thumb.jpg" alt ="Thumb" id ="clip" style ="left: 13px; position: absolute; top: 52px;" />
    </ body >
    </ html >
    清單5 ClipAnimationTest.htm

    總結

    Prototype實現了部分的面向對象,對常用的操作提供了方便的封裝。這樣我們可以編寫具有更高可重性的Javascript代碼,將實現重HTML文件中分離出來,使程序結構更清晰可讀。

    點擊以下鏈接下載示例代碼

    posted on 2007-01-26 15:06 Max 閱讀(5634) 評論(6)  編輯  收藏 所屬分類: 方法與技巧(Tips & tricks)

    評論:
    # re: 編寫基于Prototype的Javascript動畫類 2007-01-26 16:47 | Brian
    可以用SVG繪制矢量圖  回復  更多評論
      
    # re: 編寫基于Prototype的Javascript動畫類 2007-01-26 17:16 | Max
    @Brian
    雖然可以使用SVG繪制矢量圖,但目前還沒有瀏覽器內置支持SVG,所以要使用它的話,必須安裝插件。  回復  更多評論
      
    # re: 編寫基于Prototype的Javascript動畫類 2007-08-09 10:09 | liaolliso
    firefox支持的   回復  更多評論
      
    # re: 編寫基于Prototype的Javascript動畫類 2008-06-03 12:10 | ysaas
    firefox瀏覽器好垃圾的,特別是對中文網站,顯示樣式都不正確  回復  更多評論
      
    # re: 編寫基于Prototype的Javascript動畫類 2008-09-19 13:10 | go tu
    @ysaas

    要不就是你垃圾FF怎么不支持中文網站啦,
    顯示樣式都不正確都是寫那個網站的人太垃圾了。  回復  更多評論
      
    # re: 編寫基于Prototype的Javascript動畫類 2008-09-23 14:26 | fcrpg2008
    @go tu
    說得好!!
    Firefox目前是業界支持到CSS3.0的標準瀏覽器,你說的看到很多中文網站界面一踏糊涂,那是寫網站的人失敗。  回復  更多評論
      
    主站蜘蛛池模板: 久久免费公开视频| 一个人看www免费高清字幕| 国产午夜成人免费看片无遮挡| 国产亚洲日韩在线a不卡| GOGOGO高清免费看韩国| 国产91精品一区二区麻豆亚洲| 久久精品国产亚洲AV无码娇色| 亚洲av日韩综合一区久热| 午夜毛片不卡高清免费| 亚洲精品美女久久久久99| 成人免费观看男女羞羞视频| 亚洲性久久久影院| 国产精品福利片免费看| 国产精品国产亚洲精品看不卡| 亚洲日韩乱码久久久久久| 中美日韩在线网免费毛片视频| 亚洲一区免费在线观看| 亚洲美女免费视频| 日韩在线视精品在亚洲| 免费乱理伦在线播放| 一级毛片人与动免费观看| 亚洲国产天堂久久综合网站| 国产午夜亚洲精品不卡电影| 亚洲AV中文无码乱人伦| 中文字幕无码免费久久9一区9| 在线看片无码永久免费aⅴ| 色多多www视频在线观看免费| 毛片免费全部播放一级| 亚洲a∨国产av综合av下载| 中文字幕在亚洲第一在线| 99久久精品免费视频| 亚洲欧美日韩一区二区三区| 久久99国产乱子伦精品免费| 亚洲日韩国产欧美一区二区三区 | 亚洲精品无码成人片在线观看| 亚洲香蕉在线观看| 免费国产怡红院在线观看| 亚洲欧美日韩自偷自拍| 亚洲色大成网站www永久一区| 久久精品国产亚洲AV无码偷窥| 日本高清不卡aⅴ免费网站|