Skip to content

Instantly share code, notes, and snippets.

@Grace
Created December 16, 2015 06:27
Show Gist options
  • Save Grace/397971fad020e64839c2 to your computer and use it in GitHub Desktop.
Save Grace/397971fad020e64839c2 to your computer and use it in GitHub Desktop.
Line graph animation
<svg id="svg" viewBox="0 0 600 600">
</svg>
<button id="draw">Draw</button>
/*
******************
LINE DRAWING ANIMATION WITH SNAP SVG
I coded a line drawing animating with snap svg. The graph is not created out of a single line because the animating with separate paths and easing on each section simply looks better :)
1.The step of the points is evenly spread on the x axis depending on how many points your graph has.
2.Values passed to the graph should have a negative prefix because of the graph's coordinate system (-x = up).
3.Below you will find an array of prices into which you can insert your own custom values.
******************
*/
//INVERTED VALUES BECAUSE -X = Up direction because of coord system
// FEEL FREE TO INSERT YOUR OWN VALUES
var price = [0,-95, -30, -65, -35, -215, -95, -70, -115];
/* FOR FUTURE USE OF PARSING DATA.
function updatePrice(){
var inputPrices = $('#values').val();
var priceArr = inputPrices.split(',');
price = priceArr;
for (i=0;i<priceArr.length;i++){
var parsedPrice = parseInt(priceArr[i]);
function isNeg(parsedPrice){
if(parsedPrice > 0){
parsedPrice *= -1;
return parsedPrice
}else {
parsedPrice = 0;
return parsedPrice;
}
}
price[i] = isNeg(parsedPrice);
}
console.log(price);
}*/
//CHART VALUES
var chartH = $('#svg').height();
var chartW = $('#svg').width();
// PARSE PRICES TO ALIGN WITH BOTTOM OF OUR SVG
var prices = [];
for (i = 0; i < price.length; i++) {
prices[i] = price[i] + $('#svg').height();
}
function draw() {
//DEFINE SNAP SVG AND DETERMINE STEP NO.
var paper = Snap('#svg');
var steps = prices.length;
// EVENLY DISTRIBUTE OUR POINTS ALONG THE X AXIS
function step(i, chartW) {
return chartW / prices.length * i;
}
var points = [];
var breakPointsX = [];
var breakPointsY = [];
var point = {};
for (i = 1; i < prices.length; i++) {
//CALCULATE CURRENT POINT
var currStep = step(i, chartW);
var y = prices[i];
point.x = Math.floor(currStep);
point.y = y;
//CALCULATE PREVIOUS POINT
var prev = i - 1;
var prevStep = step(prev, chartW);
var prevY = prices[prev];
point.prevX = Math.floor(prevStep);
point.prevY = prevY;
if (point.prevX === 0 || point.prevY === 0){
point.prevX = 15;
point.prevY = chartH - 15;
}
// SAVE PATH TO ARRAY
points[i] = " M" + point.prevX + "," + point.prevY + " L" + point.x + "," + point.y;
// SAVE BREAKPOINTS POSITION
var r = 30;
breakPointsX[i] = point.x;
breakPointsY[i] = point.y;
}
// DRAW LINES
for (i = 0; i < points.length; i++) {
var myPath = paper.path(points[i]);
var len = myPath.getTotalLength();
myPath.attr({
'stroke-dasharray': len,
'stroke-dashoffset': len,
'stroke': 'white',
'stroke-linecap': 'round',
'stroke-width': 4,
'stroke-linejoin': 'round',
'id': 'myLine' + i,
'class': 'line'
});
}
// DRAW BREAKPOINTS
for (i = 0; i < points.length; i++) {
var circle = paper.circle(breakPointsX[i], breakPointsY[i], 5);
circle.attr({
'fill': '#FF4864',
'stroke': 'white',
'stroke-width': 3,
'id': 'myCirc' + i,
'class':'breakpoint'
});
}
// DRAW COORDINATE SYSTEM
var xAxis = paper.path('M0,'+chartH+'L'+chartW+","+chartH);
var yAxis = paper.path('M0,'+chartH+'L0,0');
var xOff = xAxis.getTotalLength();
var yOff = yAxis.getTotalLength();
var start = (prices.length*250+"ms");
yAxis.attr({
'stroke':'white',
'stroke-width':1,
'stroke-dasharray':yOff,
'stroke-dashoffset':yOff,
'id':'yAxis'
});
xAxis.attr({
'stroke':'white',
'stroke-width':1,
'stroke-dasharray':xOff,
'stroke-dashoffset':xOff,
'id':'xAxis'
});
console.log(start);
$('#yAxis').css({
'-webkit-transition-delay':start,
'-webkit-transition':'all 200ms ease-in'
});
$('#xAxis').css({
'-webkit-transition-delay':start,
'-webkit-transition':'all 200ms ease-in'
});
$('#xAxis').animate({
'stroke-dashoffset':'0'
});
$('#yAxis').animate({
'stroke-dashoffset': '0'
});
}
function animate(){
for (i=0;i<prices.length;i++){
var circ = $('#myCirc'+i);
var line = $('#myLine'+i);
circ.css({
'-webkit-transition':'all 550ms cubic-bezier(.84,0,.2,1)',
'-webkit-transition-delay':375+(i*125)+"ms"
});
line.css({
'-webkit-transition':'all 250ms cubic-bezier(.84,0,.2,1)',
'-webkit-transition-delay':i*125+"ms"
});
line.animate({
'stroke-dashoffset':0
});
circ.css({
'transform':'scale(1)'
});
}
}
$(window).load(function(){
draw();
animate();
})
$('#draw').on('click',function(){
$('#svg').empty();
draw();
animate();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
html,body {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/176026/noise.png);
width:100%;
height:100%;
background-color:#F79A7A;
}
#draw {
cursor:pointer;
left:0;
position:absolute;
top:0%;
width:10%;
padding: 15px 10px;
border-radius: 20px;
margin:20px;
background:#F79A7A;
border:4px solid white;
text-transform:uppercase;
letter-spacing: 4px;
color:white;
}
#draw:focus {
outline:none;
}
#svg {
top: 60%;
left:50%;
width:30%;
height:80%;
position:relative;
-webkit-transform:translate3d(-50%,-50%,0);
}
.line {
stroke-dashoffset:0;
box-shadow: 10px 10px 1px black;
}
.breakpoint{
transform:scale(0);
position:absolute;
-webkit-transform-origin:50% 50%;
}
.active{
transform:scale(1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment