圖形比數據有感染力,動(dòng)起來(lái)的圖形比靜態(tài)的圖形更有感染力。
轉場(chǎng)是一種過(guò)渡,提供兩個(gè)穩定狀態(tài)間的一種動(dòng)態(tài)漸進(jìn)的變化。轉場(chǎng)的概念來(lái)源于電影。 電影中存在不同場(chǎng)景之間的切換,比如,從室內鏡頭切換到室外鏡頭。直接拼接兩段 膠片很生硬,所以在后期處理中,會(huì )將前一個(gè)鏡頭漸漸隱去,后一個(gè)鏡頭漸漸浮現,這個(gè) 在鏡頭間插入的變化過(guò)程就是轉場(chǎng)。
轉場(chǎng)雖然也是一種動(dòng)畫(huà)實(shí)現,但是和我們通??吹降幕?em>幀的動(dòng)畫(huà)不同(比如:游戲), d3的轉場(chǎng)/transition是基于差值的動(dòng)畫(huà),這意味著(zhù)我們只需要 聲明可視化元素顯示屬性的初始值和最終值,d3將 自動(dòng)地構造完整的動(dòng)畫(huà)過(guò)程。
使用選擇集的transition()方法為當前選擇集啟動(dòng)一個(gè)轉場(chǎng)效果,不過(guò), 從開(kāi)發(fā)者的角度來(lái)講,我們說(shuō),這個(gè)方法返回了一個(gè)轉場(chǎng)對象:
參數name指定所創(chuàng )建轉場(chǎng)效果對象的名字,不指定該參數時(shí)使用默認值""(空字符串)作為名字。 這個(gè)參數的用途在于啟動(dòng)多個(gè)轉場(chǎng)效果:如果在一個(gè)指定的DOM元素上啟動(dòng)一個(gè)新的轉場(chǎng)效果, 與其同名的過(guò)渡效果將被終止。
轉場(chǎng)效果有一個(gè)默認的時(shí)長(cháng):250ms,我們可以使用duration()操作符修改這個(gè)轉場(chǎng)時(shí)長(cháng):
如果不指定轉場(chǎng)時(shí)長(cháng)參數value,duration()操作符就返回當前的默認時(shí)長(cháng)值。
在示例(http://www.hubwiz.com/course/54fd40cfe564e50d50dcf284/)增加感染力第一頁(yè)的代碼中,為了能看清過(guò)渡效果,我設置了一個(gè)2秒的轉場(chǎng)時(shí)間。你可以試著(zhù)調整一下, 看看變換在哪里?
和選擇集/selection一樣,轉場(chǎng)效果/transition也是一個(gè)集合對象:包含一組DOM元素。轉場(chǎng) 也有一些和選擇集一樣的選擇符,比如attr()、style()和text()等,用來(lái)對所管理的DOM元素 進(jìn)行屬性的修改:

和選擇集不同的是,轉場(chǎng)對象對DOM元素的修改不是立即完成的,它會(huì )對每個(gè) DOM元素啟動(dòng)一個(gè)17ms間隔的定時(shí)器用來(lái)逐步地修改DOM元素的屬性(我們 已經(jīng)知道,這些定時(shí)器默認只會(huì )持續250ms,所以不用擔心瀏覽器撐不?。?。
在上面的圖中,第一個(gè)style()是在選擇集上執行的,這意味著(zhù)這些div元素的y坐標 初始值被設定為10px;第二個(gè)style()是在轉場(chǎng)對象上執行的,這意味著(zhù) 這些div元素的y坐標的目標值被設定為100px,而它們將在250ms內逐漸移動(dòng) 到這個(gè)位置。
轉場(chǎng)對象根據這些值,進(jìn)行了一個(gè)簡(jiǎn)短的計算:
根據這個(gè)值在每次定時(shí)器觸發(fā)時(shí)進(jìn)行繪制,轉場(chǎng)效果就實(shí)現了。
前面的示例中,我們使用style()操作符指定了一組DOM元素 的top屬性的起始值和終止值,看起來(lái)transition()方法自己 完成了動(dòng)畫(huà)中整個(gè)的計算過(guò)程。
這只是便于理解API用途的方便說(shuō)法,計算機沒(méi)那么聰明。計算邏輯實(shí)際 上是在轉場(chǎng)對象的style()調用時(shí)確定的。
轉場(chǎng)過(guò)程的計算細節,我們可以使用tween()操作符指定:
類(lèi)似于訪(fǎng)問(wèn)器函數,tween工廠(chǎng)函數被調用時(shí)將傳入當前DOM對象對應 的數據和其順序,并將this指向當前DOM對象,tween工廠(chǎng)函數的定義如下:
請注意,轉場(chǎng)對象在每幀刷新時(shí)調用的是tween工廠(chǎng)函數返回的tween函數,參數t代表 歸一到0~1區間的時(shí)間值,比如,默認的250ms轉場(chǎng)時(shí)間,那么0ms對應0,125ms對應 0.5,250ms對應1.0。
轉場(chǎng)的attr()操作符和style()操作符,其內部實(shí)現都是使用 的tween()操作符??纯础鷂→的示例代碼,你能理解style()是 怎么運作的了吧。
我們看到,tween函數封裝了插值動(dòng)畫(huà)計算的細節,它接受一個(gè)歸一化的時(shí)間值t 作為參數,我們根據這個(gè)時(shí)間值進(jìn)行計算,最終表現為可視元素的運動(dòng)或形態(tài)的變化。
在默認情況下,轉場(chǎng)對象利用一個(gè)簡(jiǎn)單的公式計算應給傳給tween函數的時(shí)間值t:
比如,默認的轉場(chǎng)時(shí)間是250ms,從轉場(chǎng)開(kāi)始到現在已經(jīng)過(guò)了100ms,那么:t = 100/250 =0.4。
那么,如果我們在傳入tween之前改變一下這個(gè)t呢?比如,讓t在開(kāi)始時(shí)增長(cháng)的慢些, 最后突然快起來(lái),會(huì )有怎樣的視覺(jué)效果?

在tween函數看來(lái),開(kāi)始時(shí)時(shí)間過(guò)得慢了,所以運動(dòng)也會(huì )在開(kāi)始時(shí)慢了!
d3中easing就是這個(gè)意思,通過(guò)調整時(shí)間的映射,來(lái)影響tween的執行效果:
參數value如果是一個(gè)字符串,轉場(chǎng)對象將使用預置的easing效果進(jìn)行時(shí)間映射。 參數value也可以是一個(gè)函數,用來(lái)指定對時(shí)間t的映射,所以它有一個(gè)參數t,返回值 也應當在0~1范圍內。轉場(chǎng)對象將在每一幀調用tween函數之前,先使用這個(gè)函數對時(shí)間進(jìn)行 變換。
d3預置了幾種ease效果:
style()操作符用來(lái)設置轉場(chǎng)集中每個(gè)DOM元素的CSS樣式目標值:
name參數指定樣式名稱(chēng)。style()操作符使用轉場(chǎng)集中這些DOM元素的 CSS樣式的當前值作為初始值,value指定的值作為最終值,構造一個(gè)tween 工廠(chǎng)函數加入到轉場(chǎng)集的tween序列中,在每幀時(shí)被調用。
當value參數是一個(gè)具體值時(shí),所有的DOM元素的CSS樣式都被設置為這個(gè)值。 value參數也可以是一個(gè)訪(fǎng)問(wèn)器函數,這意味著(zhù)每個(gè)DOM元素 的樣式目標值可以各自不同。
可以使用對象方式同時(shí)定義幾個(gè)樣式的目標值:
你可能好奇插值怎么會(huì )能處理JSON對象。是的,插值只能用在數字上。但d3為了方便我們,內部 進(jìn)行了處理。所以,盡管用好了。
attr()操作符用來(lái)設置轉場(chǎng)集中每個(gè)DOM元素的指定屬性的目標值:
name參數指定屬性名稱(chēng)。attr()操作符使用轉場(chǎng)集中這些DOM元素的 屬性當前值作為初始值,value指定的值作為最終值,構造一個(gè)tween 工廠(chǎng)函數加入到轉場(chǎng)集的tween序列中,在每幀時(shí)被調用。
當value參數是一個(gè)具體值時(shí),所有的DOM元素的指定屬性都被設置為這個(gè)值。 value參數也可以是一個(gè)訪(fǎng)問(wèn)器函數,這意味著(zhù)每個(gè)DOM元素 的屬性目標值可以各自不同。
對于HTML元素,我們通常使用style()操作符來(lái)指定顯示效果,很少使用 attr()操作符。
而SVG元素,有些效果必須設置在屬性上,所以,在使用SVG做可視化元素時(shí),經(jīng)常 會(huì )使用attr()操作符。
聯(lián)系客服