作者TonyQ (沉默是金)
看板Ajax
標題[心得]從 js 到 jQuery 之六:五光四色的特效世界
時間Tue Aug 12 14:01:56 2008
※ [本文轉錄自 Web_Design 看板]
作者: TonyQ (沉默是金) 看板: Web_Design
標題: [心得]從 js 到 jQuery 之六:五光四色的特效世界
時間: Tue Aug 12 11:45:59 2008
本章一開始 , 我們先來看看一個小弟精心準備的小小demo吧.
http://tonyq.org/jqtalk/jq6_effectDemo.html
────────────────────────────────
呵 , 一個小小的demo , 帶下我們今天的主題 , 與其說是特效 ,
其實指的是 animation , 動態效果.
其實說到這一章 , 算是會讓我比較熱血沸騰 , 擔心會寫到失控的一章 ,
當初學 javascript 很大的一個因素是因為這個 ,從第一篇到第五篇,
我們不斷的強調 js 的用途主要在於修改頁面上的屬性 , 而用得最淋漓盡
致的應用 , 就在動態效果.
@demo頁的code好像有一點複雜 , 而且好像沒看到 jQuery呢?
我之所以要特地在最前面放一個傳統js寫出來的demo頁 , 主要是想強調
的是 jQuery 並不能平白生出各種效果 , 也是透過一些搭配來產生這些效果.
比方說在
#18dWSoRf (web_design) 一文中我就用js展示能做到opacity fade
跟color fade的模擬代碼 , 當然並沒有把所有情境考慮進去 , 但是只要把握
本章我們提的工具 , 你就不會迷失在各種令人目眩神迷的特效裡面.
js底下沒有新把戲 , 只是看你有沒有想到而已 .
這章算是傳統 js 跟 jQuery差距比較小的一章 , 因為觀念是 jQuery無法簡化
的 , 只有學習才能真的把非常複雜的事情簡化.
當然如果你不是立志要當一個開發效果的coder , 而只是想套用別人的效果 ,
本章可以讓你對於套用這些效果的「副作用」更了解一些.
@demo 是怎麼做的?
我以demo中有用到的一些技巧先行介紹 , 首先各位讀者應該有發現 ,
他是一個行為一個行為依序進行的 , 在這裡我們是透過計時器來處理 .
雖然說計時器是被我包裝成我比較習慣使用的模樣 , 不過我還是得介紹原型.
傳統 js 提供兩種計時器 , 其不僅僅是能夠提供我們計算時間而已 ,
同時他也是屬於非同步(Asynchronous)運算的 ,
對 multi-thread有了解的版友們可以把它想像成另一個thread.
@計時器
這兩個分別為 Timeout / Interval , 分別有對應的使用跟移除的function,
為 window.setTimeout(expr,time)
window.setInterval(expr,time)
window.clearTimeout(id)
window.clearInterval(id)
先談談用法 , expr 可以是javascript的字串 , 像是 "alert('hi');"
它會用eval的方式來呼叫,也可以是函數 , 像是 function(){alert('hi');
而time則是距離下一次執行的間隔時間(以ms為單位 , 1秒=1000ms)
不管是timeout或interval , 他們第一次都會是在計時器時間到時執行,
但 timeout 跟 interal最大的差異就是 , 前者呼叫時只會執行一次,
後者則是每隔指定時間就會呼叫expr這個函數,直到你把它clear掉.
每次當你呼叫 setTimeout或 setInterval時 , 他都會回傳一個數字 ,
那個數字就是所謂的timerId , 用來識別多個timer中是哪一個,
你需要透過timerId來clear掉對應的 Timeout 或 Interval.
@timer這麼猛 , 那我可以什麼都用timeout做非同步處理嗎?
由於多一個計時器本身就是不小的成本 , 建議是僅在必要時使用.
@計時器的時間準確嗎?
他本身難免還是會有一些誤差 , 不過我個人經驗是在100~200ms左右而已 ,
需要較高精確度時 , 時間區間要設小一點 , 然後透過紀錄date的時間差來算
目前差距時間,這樣會更準確一點.
@還有其他的東西嗎?
目前扣掉最基本的 show/hide , 你可能會比較想知道怎麼把元素指到指定的
位置,基本上我們也是透過css中的 position:absolute 搭配 left/top移動到
指定的位置 .
當然這樣另一個問題就來了 , 我們常會有一個畫面上的標地物.
比方說以tip效果而言 , mouseover後顯示資料在對應的物品旁邊,
我會需要這個事件對象的座標 , 一般在傳統js我們會用 offsetLeft跟
offsetTop , 不過這兩個dom元件的屬性在ie跟fx解讀下不同 ,
前者會解讀成自己跟父元素的left-top差距 , 後者則是在頁面上得left-top ,
所以在ie底下要取得 正確的 offsetLeft 要跑一個for loop 往父元素加總.
這其實一直都是許多人所碰到的釘子,因為這也是個常見的需求.
以 jQuery而言 ,用原為 dimension plug-in 的 offset(),
它現已被整合進1.2.6 jQuery Core , 可用來取得left跟top ,
就不需要自行維護寫function找左 上 , 寬高則可透過 css取.
傳統作法在這裡我先引用別人的文章來做說明 , 實際代碼可見底下連結.
http://0rz.tw/c74xz
function GetTopLeft(elm)
@我注意到你的圖形是跑圓形的 , 圓形的軌跡怎麼來的?
如果各位讀者有看source的話 , 應該會看到我是用 ( rCosΘ , rSinθ)
的方案 , 並且讓半徑r 成比例縮小來達到螺旋狀的效果 ,
對於三角函數還有印象的朋友, 可以看底下這個簡單的示意圖,
回想圓投影的公式,當然這不是這裡的重點 , 就不多做著墨.
. - .
. r /|.
. . . /θ| .
.  ̄ ̄ .
. .
`
我想表達的是對一個平面物來講 , 他就是只有 x,y座標 ,
你必須去計算他每個時間點的每個位置才能做出一連串的軌跡,
這過程中你偶爾會需要一些數學的輔助 , 像是線性遞增的等加級數就是常
用的技巧之一, 相對的 , 算法的優劣也就是決定效果出來好不好的關鍵 .
我們繼續分享一些操作上得基本技巧 ,
當你想把一個位置從 0,0 慢慢移動到 50,15 時, 假設設定移動15次時走到 ,
那你每次就要走 ((50-0)/15, (15-0)/15) 的長度 , 就可以在次數到達時 ,
走到目的地 .
當然如果你想扭扭腰之類的 , 就得去計算各個折點 , 或者仰賴簡諧運動公式.
(這邊都還在高中物理/高中數學的範疇 , 想想高中真是學了一堆鬼東西..)
至於立體軌跡 , 可能需要去找一下怎麼把 x,y,z投影到x,y平面的公式.
想把移動軌跡做水平扭曲或垂直扭曲的話 , 旋轉矩陣 會是個好幫手.
好啦 , 我知道不少位讀者現在心理正在哀號這些是什麼鬼東西 ,
我只是想提醒大家 , 學習可以簡化問題的難度...
有付出去學習就會有對應的收穫 .. 如果做不到 , 就是要多花時間學 ,
而不是說對方就像神一樣平白變魔術 , 仰賴jQuery協助我們做到許多
特效時 , 也可以順便思考它是怎麼做的 ,
筆者是一直對於沒把離散跟線代給學好 , 覺得有些遺憾 ,
當然本身不是數學相關科系出身 , 所以知道的也不是很多,
對於常常有人在討論數學到底有沒有用的議題 ,
我想學習對於簡化事情都是有正面幫助的.
無趣的碎碎念與閒話談的夠多了 , 讓我們進下一個部份吧.
@副作用?
像我紅色點的軌跡紀錄中是用多個div 當紀錄點 , 這在本來就很龐大的
網頁的話就可能會造成負擔 , 當然像這種額外插幾個元素進去處理
在各plug-in都是很常見的作法 .
有時候可能一來是需要考慮運算的複雜度 , 二來是要考慮到多個元件
會不會有互相干擾的狀況 , 這些都是需要列入考慮的 .
在底下兩個前提下 , js能透過計算作不少事情.
1.不繪圖:
雖然js可以做到類似點陣繪圖的效果 ,
可是效能很差 ,而且又不能存成圖片 , 基本上是接近廢物 ,
2.不需要對圖片做特別處理(扭曲翻轉 )
但是相對的 js 只要一多 , 對瀏覽器來講負擔就很重 ,
使用者應該有經驗就是逛網頁逛一逛突然間記憶體用量暴增 ,
那通常都是 js 跟 圖片過多且沒有好好的釋放掉所導致的 ,
這點在 map 類的網頁特別常見 , firefox以前有一隻叫leak Monitor的
plug-in可以觀察哪些資料沒被釋放掉 , 不過後來一直看到各網站都有,
就乾脆關掉了...有興趣者可參考下方連結.
https://addons.mozilla.org/zh-TW/firefox/addon/2490
雖然由一個推廣 js的人來講很奇怪 , 不過請不要覺得 javascript 是萬靈藥,
很多事情不是不存在 ,只是還沒遇上(淚目),
在要考慮到 js solution時 , 記得把對應的 loding風險列入評估.
基本上我會建議不會再用到的物件可以用 [delete]這個關鍵字順手刪掉,
雖然把需要用到的東西順手delete掉的情況也是偶爾會發生 . (攤手)
關於js coding上得一些減輕負擔或增加體驗的經驗 , 有機會再跟大家分享 .
@關於 js 我們談的夠多了 , 來點 jQuery吧
基本上在特效這點 jQuery可說沒什麼特別好幫忙的 .(才怪!)
它只是幫你處理許多做動態效果所需要的跨平台支援 ,
跟提供了數種基本實用的基本動態實做效果而已嘛...^^
接下來就來看看兩種最常見的特效 fadeIn跟 slideDown 吧
像是fadeIn/fadeOut/fadeTo (採透明度方案的) ,
還有 slideDown / slideUp 這類花俏的彈出彈入 , 幾乎是各家都不會少的.
簡單demo就好 :)
http://tonyq.org/jqtalk/jq6_jqEffectsDemo.html
@我可以簡單的做到其他的效果嗎?
這裡要特別介紹的是 animate( ) 這個方法 , 他可以讓你提供多個參數,
包括 param
duration (經過時間,也可填'fast','slow','normal')
easing(緩和方式,目前預設是'inear' 線性法 ,另有 'swing'可選)
還有callback 指的是在animate動作結束後要呼叫的方法.
我想應該看到這裡還有很多人跟我一樣不曉得這能幹麻吧?
他的概念其實很簡單 , 你結果想要達到什麼 , 就寫在 param 裡面 ,
過程想要什麼效果 , 就交給 easing決定 .
比方說我現在想從現在的 , 寬度變400px ,高度變200px.
並且希望他在 1.5秒內完成 , 就這樣寫
$("
#helloButton").click(
function(){
$("#anNode").animate(
{
width: "400px",
height: "200px"
}
,
1500
);
}
);
簡單示例
http://tonyq.org/jqtalk/jq6_jqAnimateDemo.html
不過比較遺憾的是 animate目前只支援可成為單一數字化的欄位,
比方說border寬度 , height , width , left, top 之類的
像color跟background color 目前都得透過 plug-in做到 .
關於color的相關的mailing 問題
http://www.mail-archive.com/[email protected]/msg17329.html
擴充 animate color的 plug-in
http://plugins.jquery.com/project/color
目前試用過 , 至少backgroundColor沒問題 (background不行就是了:P)
加上顏色變換之後的簡單demo
http://tonyq.org/jqtalk/jq6_jqAnimateColorDemo.html
@還有什麼好東西?
新版目前還支援 queue的效果 , 可以讓你依序執行多個 function ,
用這東西寫的話我本來的code就不用寫那麼長了...:P
直接看doc上得demo頁 , 把多個效果組合在一起 .
http://docs.jquery.com/Effects/queue
@體驗時間
由於這整章幾乎都在體驗時間...這次就先不介紹了 :P
(另外是這章的撰寫時間破歷史新高 , 害我打破一天一篇的計畫..)
---
這篇看起來好像寫了很多 , 其實又好像什麼都沒寫 ,真的是學了越多忘了越多 .XD
順便祝賀一下 , 家裏網路終於在請假半天的代價下搞定了 ,
希望晚上回來能有比較正常的網路頻寬可以用 ,逛個ptt打個字都要0.5秒 delay
還要寫長文真是太折磨我了些... 如果有錯字或者缺字就是頻寬害的(牽托ing...)
總之 , 第六篇希望給大家有一點驚豔的感覺 ,
下一篇我們要回頭講新增/刪除網頁元素 , 一樣會很有趣的 . :)
--
What do you want to have ? / What do you have?
從書本中,你可以發現我的各種興趣。
從CD中,你可以瞭解我所喜歡的偶像明星。
或許從文字你很難以瞭解一個人,但從物品可以。
My PPolis , My past. http://ppolis.tw/user/Tony
---
重新修整一些我覺得極度不通暢的文句 , 跟放上我忘記放的兩個sample link.
另摘於下
http://tonyq.org/jqtalk/jq6_jqAnimateDemo.html
http://tonyq.org/jqtalk/jq6_jqAnimatecolorDemo.html
/*加入color plug-in*/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.132.59.247
推 JYHuang:網路斷線推 XD08/12 12:38
推 gpmm:push08/12 12:48
推 ateclean:推08/12 13:21
推 chrisQQ:推,終於逃出舊的慢網路…08/12 13:22
推 dspswen:推 !08/12 13:33
※ 編輯: TonyQ 來自: 220.128.219.202 (08/12 13:58)
--
What do you want to have ? / What do you have?
從書本中,你可以發現我的各種興趣。
從CD中,你可以瞭解我所喜歡的偶像明星。
或許從文字你很難以瞭解一個人,但從物品可以。
My PPolis , My past. http://ppolis.tw/user/Tony
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.128.219.202
推 awpadam:推!認真的範例網頁!! 08/12 17:25
推 ilake:推推推 08/13 07:06
→ TonyQ:ilake欸 好久不見 , 改天再去你那搶鳥(誤) XD 08/13 11:43
推 superGA:push 08/13 19:49
→ kosgroup:推 05/04 02:43
※ 編輯: TonyQ 來自: 61.224.239.208 (12/16 00:00)