1. 程式人生 > >D3.js SVG繪圖實踐:波浪動畫

D3.js SVG繪圖實踐:波浪動畫

效果圖

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庫中有一個例子,他是從無到有旋轉開來。他這個動畫效果的。 效果如下: 在來看看我之前寫的效果: 對比一下就很容易看出來兩個餅圖旋轉開來的區別了: 第一個是所有的弧都開始從無到有變化 第二個:是一個弧選旋轉完成在到到下一弧開始旋轉(具