最近做控制項遇到含有波浪圖的圖表,一開始用Echarts雖然很快完成了,但Echarts的波浪圖與其他圖表的響應式不同步,於是學習了D3js,D3js寫起來確實複雜一些,但能夠實現的效果也更豐富,做的時候查了不少資源,講真的,網上教程挺少的,很多都重覆,我分享下我的方法。 先看一下效果: 我只做了簡單 ...
最近做控制項遇到含有波浪圖的圖表,一開始用Echarts雖然很快完成了,但Echarts的波浪圖與其他圖表的響應式不同步,於是學習了D3js,D3js寫起來確實複雜一些,但能夠實現的效果也更豐富,做的時候查了不少資源,講真的,網上教程挺少的,很多都重覆,我分享下我的方法。
先看一下效果:
我只做了簡單的效果,想控制波浪的流速、高度就跟據應用場景自己設計,我在控制項中是用比例尺。
D3中有一種叫區域生成器的東西,可以生成一個上方是不規則形狀,其餘三邊都是直線的區域,主要就圍繞這個來做。
先定義一個畫布
var width = 200;
var height = 500;
var svg = d3.select("#body")
.append("svg")
.attr("width", width)
.attr("height", height)
然後用數組控制波浪的形狀
var values = 0
var dataList0 = [values - 2, values - 3, values - 4, values - 3, values - 2, values - 1, values, values - 1]
網上的50行代碼的版本大家應試都看到過,是將數組的每一個數組放到最後,迴圈這個操作就可以了,本人比較小白,有幾個地方看不懂,所以用了比較直觀的方法,多定義些數組
var values = 0
var dataList0 = [values - 2, values - 3, values - 4, values - 3, values - 2, values - 1, values, values - 1]
var dataList1 = [values - 3, values - 4, values - 3, values - 2, values - 1, values, values - 1, values - 2]
var dataList2 = [values - 4, values - 3, values - 2, values - 1, values, values - 1, values - 2, values - 3]
var dataList3 = [values - 3, values - 2, values - 1, values, values - 1, values - 2, values - 3, values - 4]
var dataList4 = [values - 2, values - 1, values, values - 1, values - 2, values - 3, values - 4, values - 3]
var dataList5 = [values - 1, values, values - 1, values - 2, values - 3, values - 4, values - 3, values - 2]
var dataList6 = [values, values - 1, values - 2, values - 3, values - 4, values - 3, values - 2, values - 1]
var dataList7 = [values - 1, values - 2, values - 3, values - 4, values - 3, values - 2, values - 1, values]
現在我們把區域生成器放上去,網上很多教程都是v3的,生成時用的 d3.svg.area() ,新版本是 d3.area() 曲線用的是 .interpolate("basis") ,新的版本是 .curve(d3.curveBasis)
var areaPath = d3.area()
.x(function (d, i) { return i * 20 })
.y0(function (d, i) { return height / 2 })
.y1(function (d, i) { return - d })
.curve(d3.curveBasis)
最後加屬性,並讓數組波浪起來
function run() {
svg.append("path")
.attr("d", areaPath(dataList0))
.attr("fill", "rgba(0,118,184,.4)")
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList1))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList2))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList3))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList4))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList5))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList6))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList7))
.transition().duration(100).delay(0).ease(d3.easeLinear)
.attr("d", areaPath(dataList0))
.remove()
.on('end', run)
}
requestAnimationFrame(run);
不建議用計時器, requestAnimationFrame(run) 配合 on('end', run) 的效果更好,.remove() 是讓刪除之前的動畫,ease(d3.easeLinear) 一定要加,會讓動畫看上去更流暢,不加就是幻燈片-_-b