D3.js SVG繪圖實踐:波浪動畫
效果圖
TALK IS CHEAP
原始碼就50多行,比較好看懂。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>svg動畫</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg id="svg-area" width="500" height="200" >
<path fill="rgba(33, 150, 243, 0.4)"></path>
<path fill="rgba(33, 150, 243, 0.6)"></path>
</svg>
<script>
//波浪動畫
var svg_height = 200,
svg_width = 500,
wave_data = [[],[]],
area = d3.area().y0(svg_height).curve(d3.curveBasis), //curve會進行平滑處理
svg_paths = [];
var max = 100; //控制速度
for (var i=0; i<max; i++) {
var r = i / max * 2;
wave_data[0].push(r); //波浪一
wave_data[1].push(r + 1); //波浪二(+1代表偏移π)
}
var d = svg_width/(wave_data[0].length-1);
svg_paths.push(d3.select('#svg-area path:first-child' ));
svg_paths.push(d3.select('#svg-area path:last-child'));
function area_generator(data) {
var wave_height = 0.15; //波浪高度
var area_data = data.map( function(y,i) {
return [i * d, svg_height*(1 - (wave_height*Math.sin(y*Math.PI) + 2)/3)]; //+2將範圍[-1,1]轉成[1,3]
} );
return function() {
return area(area_data);
};
}
function renderWave() {
svg_paths.forEach(function(svg_path,i){
svg_path.attr('d', area_generator(wave_data[i]));
wave_data[i] = getNextData(wave_data[i]);
});
requestAnimationFrame(renderWave);
}
function getNextData(data) {
var r = data.slice(1);
r.push(data[0]);
return r;
}
requestAnimationFrame(renderWave);
</script>
</body>
</html>
補充
這估計是我寫得最簡短的部落格之一了,看到這裡的同學估計是我的程式碼沒寫好,沒有簡單易懂,下面補充一下實現的思路和涉及到的一些知識點吧。
實現思路
因為之前畫過趨勢圖(D3.js SVG繪圖實踐:趨勢縮圖),所以看到波浪動畫,第一想法就是,這不是兩個帶透明度重疊的區域嘛,讓區域動起來就好。
畫區域已經在上一篇部落格中解決了,這次只不過加了平滑處理:
area = d3.area().y0(svg_height).curve(d3.curveBasis) //curve會進行平滑處理
重點是怎麼動起來:
- 方案一:
用transform實現平移(一般思路,從左到右,然後移到與開始視覺一樣時瞬間移回原點) - 方案二:
區域不動,區域上邊界按照波浪的規律動,重繪區域(實現比較複雜) - 方案三:將區域資料平移,重繪區域
function getNextData(data) {
var r = data.slice(1);
r.push(data[0]);
return r;
}
一些知識點:
總結
實現上沒很大的難度,但一開始因為用了Math.sin
,波浪起伏的幅度較大,看著不像波浪在上下動,而是在從右往左移動,一開始都想嘗試之前的方案二了,後來去看了波浪的效果,發現主要問題出在波浪本來就不是正弦圖形那樣的,於是改成了0.15 * Math.sin
,效果就好多了。
最近在計劃手上的React專案重構的事,也在看各類庫的原始碼,希望能有更多的東西和大家分享,共勉。
相關推薦
D3.js SVG繪圖實踐:波浪動畫
效果圖 TALK IS CHEAP 原始碼就50多行,比較好看懂。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &
D3.js SVG繪圖實踐:趨勢縮圖
前言 寫碼,看書,思考,這周挺多感觸的。 因為手上的專案前端用了Angular,所以UI改版的時候考慮了Angular-material,學校的專案前端用了React,所以也想接入ant-design mobile的那套設計規範,這兩個都是業界非常不錯的UI
CSS3動畫(二):波浪效果
col -1 loading ack css代碼 code load width ase 實現效果 如圖所示: 首先得準備三張圖,一張是淺黃色的背景圖loading_bg.png,一張是深紅色的圖loading.png,最後一張為bolang.png。 css代碼
Vue.js 開發實踐:實現精巧的無限加載與分頁功能
cti head 設定 命令 webpack transform style time default https://segmentfault.com/a/1190000005351971#articleHeader9 本篇文章是一篇Vue.js的教程,目標在於用一
D3.js 基於資料的繪圖
繪製直線圖 條形圖實際上是矩形,而 HTML 的 div 元素是繪製矩形的最簡單手段。(對於瀏覽器來說,HTML 中的一切元素都可以喲ing來表示矩形)。 所以我們可以定義一個叫 bar 的 div 類,用於存放圖表的公共屬性。(除了高度,其他的屬性應該是共享的) div.bar {
D3.js 基於數據的繪圖
除了 存在 style inline bar 同時 () 設定 pre 繪制直線圖 條形圖實際上是矩形,而 HTML 的 div 元素是繪制矩形的最簡單手段。(對於瀏覽器來說,HTML 中的一切元素都可以喲ing來表示矩形)。 所以我們可以定義一個叫 bar 的 div 類
d3.js學習筆記(二):完整的柱狀圖示例
本示例採用d3的3.x版本庫,示例程式碼如下: d3.fullAxisExample = function() { var width = 240; var height = 240; //在 body 裡新增一個 SVG 畫布
D3.js 動畫 過度屬性
import * as D3 from 'd3' export default class DThree { createSvg (result) { let svg = D3.select(result) .append('svg') .attr('width
D3.js 動畫 建立過度
建立過度有兩種方式;d3.transition 和 selection.transition, 它們都返回一個過度物件。前者是直接建立一個過度物件再指定作用物件,後者是通過作用物件建立過度。 d3.transition([selection], [name]) 建立一個過度物件,引數是選擇集
用d3.js對訊號處理的結果資料作圖,得到可縮放互動的動態SVG圖
d3.js 有何用 D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. D3’s
d3.js 動畫選擇子元素
import * as D3 from 'd3' export default class DThree { createSvgG (result) { let svg = D3.select(result) .append('svg') .attr('widt
蘇寧的Node.js實踐:不低於Java的渲染效能、安全穩定迭代快
前端 Node.js 的使用場景大多集中在前端工具上,當前的前端主要把它定位為輔助。蘇寧易購使用 Node.js 作為前後端分離的主要手段,經歷了從技術引進到全面開花,從邊緣功能到核心業務,從紛亂到穩定的過程。同時 Node.js 作為新引入的技術,與公司原有架構融合銜接面臨著怎樣的挑
D3.js實現帶動畫效果的柱狀圖
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content
關於d3.js 生成的 SVG轉化成圖片
因為工作需要使用到SVG,然後使用了d3.js. 然後甲方爸爸想要看到版本記錄。 那麼我就需要將d3.js 生成的SVG轉化成圖片儲存。在這裡經歷了很多坑。 分享一下,讓各位可以避坑! 使用方法就是 var canvas = $("#svg-wrap
【d3.js實踐教程特別篇】PornHub釋出基於d3的網民觀看成人視訊時長分佈互動式地圖
學習d3.js(以下都簡稱d3)也有一段時間了,執行d3做了幾個專案。我發現中文的d3教程很少,國外資料多但要求有一定的英文閱讀能力(推薦網址:http://bl.ocks.org/mbostock),於是就萌發了寫一個d3實際運用系列文章的想法,現在開始付之行動。在系列
大資料視覺化第三天——D3.js初探:餅形圖
在找了許多參考資料後,我發現大部分關於D3.js的講解不滿足我的需求,有些講的太過冗長,舉了很多不需要的點,比如用D3來做排序過濾這種分析階段就應該做完的事;有些又太簡單,很多省略的細節讓人看的似是而非。這篇我在網上找了一個餅狀圖的小例子來幫助自己理解D3一般圖形繪製過程,在程式碼中涉及到某個知識點
Vue.js實踐:一個Node.js+mongoDB+Vue.js的部落格內容管理系統
專案來源 以前曾用過WordPress搭建自己的部落格網站,但感覺WordPress很是臃腫。所以一直想自己寫一個部落格內容管理器。 正好近日看完了Vue各個外掛的文件,就用著Vue嘗試寫了這個簡約的部落格內容管理器(CMS)。 完成的功能 一個基本的
Vue.js 開發實踐:實現精巧的無限載入與分頁功能
https://segmentfault.com/a/1190000005351971#articleHeader9 需求分析 當一個頁面中資訊量過大時(例如一個新聞列表中有200條新聞需要展示),就會產生問題,例如: 資料量過大,影響載入速度 使用者體驗差,很難定位到之前自己看
【D3.js資料視覺化系列教程】(十六)--更新、過度和動畫
//(1) 準備資料集 var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ]; //(2) 設定SVG的高寬 var w=600; va
D3.JS之別人家的餅圖動畫
原文連結 最近看到D3的demo庫中有一個例子,他是從無到有旋轉開來。他這個動畫效果的。 效果如下: 在來看看我之前寫的效果: 對比一下就很容易看出來兩個餅圖旋轉開來的區別了: 第一個是所有的弧都開始從無到有變化 第二個:是一個弧選旋轉完成在到到下一弧開始旋轉(具