Based on http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6 made by Curtis Bratton [brattonc]
You should keep SVG structure and hierarchy:
- <svg id={name} ... />
- <path id="area" ...> area to be animated
Based on http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6 made by Curtis Bratton [brattonc]
You should keep SVG structure and hierarchy:
| d3.liquid = function(parent_, index_, object_) { | |
| var x = object_.x, y = object_.y; | |
| var g = parent_.append("g").attr("id", "shape" + index_).attr("transform", "translate(" + (x) + ", " + (y) + " )"); | |
| d3.xml(object_.asset).mimeType("image/svg+xml").get(function(error, xml) { | |
| if (error) throw error; | |
| var imported = document.importNode(xml.documentElement, true); | |
| d3.select("#shape" + index_) | |
| .each(function() { this.appendChild(imported); }); | |
| d3.select("#" + object_.name).select("#area").attr("fill", "#228CC8"); | |
| var o = d3.select("#" + object_.name).select("#area"); | |
| this.xy = o.node().getBBox(); | |
| d3.select("#" + object_.name).append("clipPath").attr("id", "clip").append("rect") | |
| .attr("id", "clip") | |
| .attr("x", this.xy.x - object_.strokeWidth / 2) | |
| .attr("y", this.xy.y - object_.strokeWidth / 2) | |
| .attr("width", this.xy.width + object_.strokeWidth) | |
| .attr("height", this.xy.height + object_.strokeWidth) | |
| .attr("fill", "#FF00FF") | |
| .attr("opacity", 0.4); | |
| d3.select("#" + object_.name).append("text") | |
| .attr("id", "full") | |
| .attr("dx", this.xy.x + this.xy.width / 2 + object_.offset.x) | |
| .attr("dy", this.xy.y + this.xy.height / 1.75 + object_.offset.y) | |
| .attr("text-anchor", "middle") | |
| .attr("font-size", object_.fontsize) | |
| .attr("fill", "#FFFFFF") | |
| .attr("stroke", "#none") | |
| .html("<tspan>" + map(object_.value, 0, 1, 0, object_.units).toFixed(object_.decimals) + "</tspan><tspan style='font-size: " + object_.fontsize / 2 + "'>" + "ml</tspan>"); | |
| d3.select("#" + object_.name).append("text") | |
| .attr("id", "clipped") | |
| .attr("dx", this.xy.x + this.xy.width / 2 + object_.offset.x) | |
| .attr("dy", this.xy.y + this.xy.height / 1.75 + + object_.offset.y) | |
| .attr("fill", "#FFFFFF") | |
| .attr("text-anchor", "middle") | |
| .attr("font-size", object_.fontsize) | |
| .attr("fill", "#000000") | |
| .attr("stroke", "#000000") | |
| .attr("stroke-width", 2) | |
| .html("<tspan>" + map(object_.value, 0, 1, 0, object_.units).toFixed(object_.decimals) + "</tspan><tspan style='font-size: " + object_.fontsize / 2 + "'>" + "ml</tspan>"); | |
| this.cx = this.xy.x + this.xy.width / 2, this.cy = + this.xy.y + this.xy.height / 2; | |
| this.halfWidth = this.xy.width / 2, this.halfHeight = this.xy.height / 2; | |
| this.ratio = this.halfHeight/this.halfWidth; | |
| this.waveCount = 1; | |
| this.waveOffset = 0; | |
| this.waveHeight = 5; | |
| this.waveLength = this.halfWidth * 2 / this.waveCount; | |
| this.waveClipCount = 1 + this.waveCount; | |
| this.waveClipWidth = this.waveLength * this.waveClipCount; | |
| this.gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]); | |
| this.gaugeCircleY = d3.scaleLinear().range([0, this.halfWidth]).domain([0, this.halfWidth]); | |
| this.waveScaleX = d3.scaleLinear().range([0, this.waveClipWidth]).domain([0, 1]); | |
| this.waveScaleY = d3.scaleLinear().range([0, this.waveHeight]).domain([0, 1]); | |
| waveAnimateScale = d3.scaleLinear().range([0, this.waveClipWidth - this.halfWidth * 2]).domain([0, 1]); | |
| this.data = []; | |
| for(var i = 0; i <= 32 * this.waveClipCount; i++){ this.data.push({x: i / (32 * this.waveClipCount), y: (i / (32))}); } | |
| this.clipArea = d3.area() | |
| .x(function(d) { return this.waveScaleX(d.x); } ) | |
| .y0(function(d) { return this.waveScaleY(Math.sin(Math.PI * 2 * this.waveOffset * -1 + Math.PI * 2 * ( 1 - this.waveCount) + d.y * 2 * Math.PI));} ) | |
| .y1(function(d) { return (this.halfWidth * this.ratio * 2 + this.waveHeight); } ); | |
| this.clip = d3.select("#" + object_.name).append("clipPath") | |
| .attr("id", "clipWave" + index_) | |
| .attr("transform", "translate(" + (this.cx + this.halfWidth - this.waveClipWidth) + ", " + (this.cy + map(object_.value, 0, 1, this.halfWidth * this.ratio, -this.halfWidth * this.ratio)) + ")"); | |
| this.wave = this.clip.append("path") | |
| .datum(this.data) | |
| .attr("d", this.clipArea) | |
| .attr("T", 0) | |
| .attr("fill", "#0FFFF0"); | |
| d3.select("#" + object_.name).select("#area").attr("clip-path","url(#clipWave" + index_ + ")"); | |
| d3.select("#" + object_.name).select("#clipped").attr("clip-path","url(#clipWave" + index_ + ")"); | |
| animate(this.wave, this.waveAnimateScale); | |
| }); | |
| function animate(wave_, waveAnimateScale_){ | |
| wave_.attr("transform","translate("+ waveAnimateScale_(wave_.attr("T"))+", 0)"); | |
| wave_.transition() | |
| .ease(d3.easeLinear) | |
| .duration(object_.waveAnimateTime * (1 - wave_.attr("T"))) | |
| .attr("transform","translate(" + waveAnimateScale_(1)+", 0)") | |
| .attr("T", 1) | |
| .on("end", function(){ wave_.attr("T", 0); animate(wave_, waveAnimateScale_); }); | |
| } | |
| } |
| <!DOCTYPE html> | |
| <html> | |
| <head lang="en"> | |
| <meta charset="UTF-8"> | |
| <title>D3.JS Liquid Shapes</title> | |
| <link rel="stylesheet" href="styles.css?v=1.0"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="d3.liquid.js"></script> | |
| </head> | |
| <body> | |
| <script> | |
| function map(value_, min0_, max0_, min1_, max1_){ return min1_ + (value_ - min0_) / (max0_ - min0_) * (max1_- min1_); } | |
| var objects = [ | |
| { name : "sampleA", asset: "sampleA.svg", waveAnimateTime: 1800, x: -150, y: window.innerHeight / 4, value: 0.75, units: 568, strokeWidth: 3, fontsize: 28, decimals: 0, offset: { x: 0, y: 0 } }, | |
| { name : "sampleB", asset: "sampleB.svg", waveAnimateTime: 1800, x: 150, y: window.innerHeight / 4, value: 0.33, units: 0.5, strokeWidth: 3, fontsize: 48, decimals: 2, offset: { x: 0, y: 24 } } | |
| ] | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", window.innerWidth) | |
| .attr("height", window.innerHeight); | |
| var shapeA = d3.liquid(svg, 0, objects[0]); | |
| var shapeB = d3.liquid(svg, 1, objects[1]); | |
| </script> | |
| </body> | |
| </html> |
| <?xml version="1.0" encoding="utf-8"?> | |
| <svg version="1.1" id="sampleA" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |
| viewBox="-450 -450 900 900" xml:space="preserve"> | |
| <path stroke="#228CC8" stroke-width="3" fill="none" d="M0,0c21.3-0.5,25.2-0.9,28-1.3c2.8-0.4,4.6-0.9,6.4-1.6s3.7-1.5,5.6-2.5s3.7-2,4.9-3.5 | |
| c1.2-1.5,1.6-3.3,1.9-14.1s0.3-30.4,0.1-54.9c-0.2-24.5-0.7-53.8-1.1-69.6s-0.7-18.1-1.2-20.4c-0.5-2.3-1.3-4.5-2.1-6.8 | |
| c-0.8-2.3-1.7-4.7-2.7-7.2s-2.1-5.1-3.5-8.1c-1.4-2.9-3.1-6.2-4.6-9.1c-1.5-2.9-2.8-5.3-4.4-8.9c-1.5-3.5-3.3-8.1-4.3-11.6 | |
| s-1.3-6-1.8-13s-1.2-18.6-1.5-24.6s-0.3-6.5-0.2-6.9c0.2-0.4,0.5-0.7,0.9-1c0.4-0.4,1-0.8,1.2-1.9c0.3-1,0.3-2.6,0.2-4 | |
| c-0.1-1.4-0.3-2.6-0.6-3.5c-0.3-0.8-0.6-1.2-0.9-1.6s-0.6-0.8-0.8-1.4c-0.2-0.6-0.4-1.3-0.3-1.9s0.4-1,0.9-1.3 | |
| c0.4-0.4,0.9-0.7,1.2-1.3c0.3-0.6,0.4-1.5,0.1-2.3s-0.9-1.5-1.8-2s-2.1-0.8-3.7-1s-3.7-0.4-15.9-0.5c-12.3,0.1-14.3,0.2-15.9,0.5 | |
| c-1.6,0.2-2.8,0.6-3.7,1c-0.9,0.5-1.5,1.2-1.8,2s-0.2,1.7,0.1,2.3c0.3,0.6,0.8,0.9,1.2,1.3s0.8,0.8,0.9,1.3c0.1,0.6-0.1,1.3-0.3,1.9 | |
| s-0.5,1-0.8,1.4s-0.7,0.8-0.9,1.6c-0.3,0.8-0.5,2.1-0.6,3.5s-0.1,3,0.2,4s0.8,1.5,1.2,1.9s0.7,0.7,0.9,1c0.2,0.4,0.2,0.9-0.2,6.9 | |
| c-0.3,6-1,17.6-1.5,24.6s-0.8,9.5-1.8,13s-2.8,8.1-4.3,11.6s-2.8,6-4.4,8.9c-1.5,2.9-3.2,6.1-4.6,9.1c-1.4,2.9-2.5,5.5-3.5,8.1 | |
| c-1,2.5-1.9,4.9-2.7,7.2c-0.8,2.3-1.6,4.5-2.1,6.8s-0.8,4.6-1.2,20.4s-0.9,45.1-1.1,69.6S-47-33.7-46.8-23 | |
| c0.3,10.8,0.8,12.6,1.9,14.1c1.2,1.5,3,2.5,4.9,3.5c1.9,1,3.8,1.8,5.6,2.5s3.6,1.2,6.4,1.6S-21.3-0.5,0,0z"/> | |
| <path id="area" fill="#228CC8" d="M-17.3-250.2c0,0.4-0.1,0.8-0.1,1.3c-0.2,3.1-0.4,6.3-0.6,9.4c-0.1,1.9-0.3,3.9-0.4,5.8 | |
| c-0.1,1-0.1,2.1-0.2,3.1c-0.1,0.7-0.1,1.4-0.2,2.1c0,0.6-0.1,1.2-0.2,1.8c-0.1,0.5-0.1,1.1-0.2,1.6c-0.1,0.5-0.1,1-0.2,1.4 | |
| c-0.1,0.5-0.1,0.9-0.2,1.3c-0.1,0.4-0.2,0.9-0.3,1.3c-0.1,0.4-0.2,0.8-0.3,1.3c-0.1,0.4-0.2,0.9-0.4,1.3c-0.1,0.5-0.3,0.9-0.4,1.3 | |
| c-0.1,0.5-0.3,0.9-0.5,1.4s-0.3,1-0.5,1.4c-0.2,0.5-0.4,1-0.5,1.5c-0.3,0.9-0.7,1.9-1.1,2.8c-0.4,0.9-0.7,1.8-1.1,2.7 | |
| c-0.4,0.8-0.7,1.6-1.1,2.5c-0.3,0.7-0.7,1.5-1,2.2s-0.7,1.4-1,2c-0.3,0.7-0.7,1.3-1,2c-0.4,0.7-0.7,1.3-1.1,2 | |
| c-0.2,0.3-0.4,0.7-0.6,1c-0.7,1.4-1.5,2.8-2.2,4.3c-0.3,0.7-0.7,1.4-1,2.1c-0.2,0.5-0.5,1-0.7,1.5c-0.3,0.6-0.6,1.3-0.9,1.9 | |
| c-0.5,1.2-1,2.4-1.5,3.6c-0.2,0.6-0.5,1.2-0.7,1.8s-0.4,1.1-0.7,1.7c-0.4,1.1-0.8,2.2-1.2,3.3c-0.2,0.5-0.4,1.1-0.6,1.6 | |
| c-0.1,0.3-0.2,0.6-0.3,0.8c-0.2,0.5-0.4,1-0.5,1.6c-0.2,0.5-0.3,1-0.5,1.5c-0.1,0.5-0.3,1-0.4,1.5c-0.1,0.4-0.2,0.8-0.3,1.2 | |
| c-0.1,0.2-0.1,0.5-0.1,0.7c-0.1,0.3-0.1,0.6-0.1,0.8c-0.1,0.4-0.1,0.8-0.1,1.1c-0.1,0.5-0.1,1.1-0.1,1.6c0,0.6-0.1,1.2-0.1,1.7 | |
| c0,0.9-0.1,1.8-0.1,2.7c0,1.2-0.1,2.3-0.1,3.5c0,1.5-0.1,2.9-0.1,4.4c0,0.9,0,1.7-0.1,2.6c0,1.7-0.1,3.5-0.1,5.2 | |
| c0,2.3-0.1,4.5-0.1,6.8c-0.1,2.5-0.1,5.1-0.1,7.6c-0.1,5.6-0.2,11.3-0.3,16.9c-0.1,6-0.2,12-0.2,18c-0.1,5.9-0.1,11.8-0.2,17.6 | |
| c0,5.4-0.1,10.7-0.1,16.1c0,4.7,0,9.4,0,14.2c0,2.1,0,4.3,0,6.4c0,1.9,0,3.8,0,5.7c0,1.7,0,3.3,0.1,5c0,1.4,0,2.9,0.1,4.3 | |
| c0,1.2,0.1,2.4,0.1,3.6c0,1,0.1,1.9,0.1,2.9c0,0.6,0.1,1.1,0.1,1.7s0.1,1.3,0.2,1.9c0,0.3,0.1,0.5,0.1,0.8c0,0.2,0.1,0.4,0.1,0.6 | |
| c0,0.2,0.1,0.3,0.1,0.5c0,0.1,0.1,0.3,0.1,0.4c0,0.1,0.1,0.2,0.1,0.3s0,0.2,0.1,0.2c0,0.1,0,0.1,0.1,0.2c0,0,0,0.1,0.1,0.1 | |
| c0,0,0,0.1,0.1,0.1l0.1,0.1l0.1,0.1c0,0.1,0.1,0.1,0.1,0.1c0.1,0.1,0.2,0.2,0.3,0.3c0.1,0.1,0.2,0.2,0.4,0.3 | |
| c0.1,0.1,0.3,0.2,0.4,0.3c0.3,0.2,0.7,0.4,1,0.6c0.4,0.2,0.8,0.4,1.2,0.6c0.3,0.2,0.7,0.4,1,0.5c0.8,0.4,1.7,0.8,2.5,1.2 | |
| c0.8,0.3,1.5,0.6,2.3,0.9c0.4,0.1,0.8,0.3,1.2,0.4c0.1,0.6,0.5,0.7,0.9,0.8c0.2,0.1,0.5,0.1,0.7,0.2c0.5,0.1,1,0.2,1.5,0.3 | |
| c0.3,0.1,0.6,0.1,0.9,0.1c0.2,0,0.4,0.1,0.6,0.1c0.3,0.1,0.7,0.1,1,0.1c0.6,0.1,1.1,0.1,1.7,0.2c0.6,0.1,1.3,0.1,1.9,0.1 | |
| c0.9,0.1,1.7,0.1,2.6,0.1c1.1,0.1,2.3,0.1,3.4,0.2c1.5,0.1,2.9,0.1,4.4,0.2c1.8,0.1,3.7,0.1,5.5,0.2C-4.5-3-2.2-3,0-2.9 | |
| C2.2-3,4.5-3,6.7-3.1c1.8,0,3.7-0.1,5.5-0.2c1.5,0,2.9-0.1,4.4-0.2c1.1,0,2.3-0.1,3.4-0.2c0.9,0,1.7-0.1,2.6-0.1 | |
| c0.6,0,1.3-0.1,1.9-0.1C25-3.9,25.6-4,26.1-4c0.3,0,0.7-0.1,1-0.1c0.2,0,0.4-0.1,0.6-0.1c0.3,0,0.6-0.1,0.9-0.1 | |
| c0.5-0.1,1-0.2,1.5-0.3c0.2-0.1,0.5-0.1,0.7-0.2C31.2-4.9,31.6-5,32-5.1c0.4-0.1,0.8-0.3,1.2-0.4c0.8-0.3,1.6-0.6,2.3-0.9 | |
| c0.8-0.4,1.7-0.8,2.5-1.2c0.3-0.2,0.7-0.4,1-0.5c0.4-0.2,0.8-0.4,1.2-0.6c0.3-0.2,0.7-0.4,1-0.6c0.1-0.1,0.3-0.2,0.4-0.3 | |
| s0.2-0.2,0.4-0.3c0.1-0.1,0.2-0.2,0.3-0.3l0.1-0.1l0.1-0.1l0.1-0.1c0,0,0-0.1,0.1-0.1c0,0,0-0.1,0.1-0.1c0-0.1,0-0.1,0.1-0.2 | |
| c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.2,0.1-0.3s0.1-0.3,0.1-0.4c0-0.2,0.1-0.3,0.1-0.5s0.1-0.4,0.1-0.6c0-0.3,0.1-0.5,0.1-0.8 | |
| s0.1-0.6,0.1-0.9c0-0.3,0.1-0.7,0.1-1c0-0.6,0.1-1.1,0.1-1.7c0-1,0.1-1.9,0.1-2.9c0-1.2,0.1-2.4,0.1-3.6c0-1.4,0.1-2.9,0.1-4.3 | |
| c0-1.7,0-3.3,0.1-5c0-1.9,0-3.8,0-5.7c0-2.1,0-4.3,0-6.4c0-4.7,0-9.4,0-14.2c0-5.4,0-10.7-0.1-16.1c0-5.9-0.1-11.8-0.2-17.6 | |
| c-0.1-6-0.2-12-0.2-18c-0.1-5.6-0.2-11.3-0.3-16.9c-0.1-4.8-0.2-9.6-0.3-14.4c-0.1-2.6-0.1-5.2-0.2-7.8c0-1.5-0.1-2.9-0.1-4.4 | |
| c0-1.2-0.1-2.3-0.1-3.5c0-0.9-0.1-1.8-0.1-2.7c0-0.6-0.1-1.2-0.1-1.7s-0.1-1.1-0.1-1.6c0-0.4-0.1-0.8-0.1-1.1s-0.1-0.6-0.1-0.8 | |
| s-0.1-0.5-0.1-0.7c-0.2-0.9-0.5-1.8-0.7-2.7c-0.3-1-0.7-2-1-3.1c-0.1-0.3-0.2-0.6-0.3-0.8c-0.2-0.5-0.4-1.1-0.6-1.6 | |
| c-0.4-1.1-0.8-2.2-1.2-3.3c-0.2-0.6-0.4-1.1-0.7-1.7c-0.2-0.6-0.5-1.2-0.7-1.8c-0.5-1.2-1-2.4-1.5-3.6c-0.3-0.6-0.6-1.3-0.9-1.9 | |
| c-0.2-0.5-0.5-1-0.7-1.5c-0.3-0.7-0.7-1.4-1-2.1c-0.7-1.4-1.5-2.8-2.2-4.3c-0.5-1-1.1-2-1.6-3.1c-0.3-0.7-0.7-1.3-1-2s-0.7-1.3-1-2 | |
| c-0.4-0.7-0.7-1.5-1-2.2c-0.4-0.8-0.7-1.6-1.1-2.5s-0.8-1.8-1.1-2.7c-0.4-0.9-0.7-1.8-1.1-2.8c-0.2-0.5-0.4-1-0.5-1.5 | |
| c-0.3-0.9-0.7-1.9-1-2.8c-0.1-0.4-0.3-0.9-0.4-1.3c-0.1-0.4-0.2-0.9-0.4-1.3c-0.1-0.4-0.2-0.8-0.3-1.3c-0.1-0.4-0.2-0.9-0.3-1.3 | |
| c-0.1-0.4-0.2-0.9-0.2-1.3c-0.1-0.5-0.1-1-0.2-1.4c-0.1-0.5-0.1-1.1-0.2-1.6c-0.1-0.6-0.1-1.2-0.2-1.8c-0.1-0.7-0.1-1.4-0.2-2.1 | |
| c-0.1-1-0.1-2.1-0.2-3.1c-0.1-1.9-0.3-3.9-0.4-5.8c-0.1-1.1-0.1-2.1-0.2-3.2c-0.1-2.1-0.3-4.2-0.4-6.3c0-0.4-0.1-0.8-0.1-1.3 | |
| C5.7-250.2-5.8-250.2-17.3-250.2z"/> | |
| </svg> |
| body { margin : 0; font-family: "Open Sans", sans-serif; background: #000; } |