I'm playing around with making a script that would let me make a simple svg path tween (smooth morph animation) between two or more keyframes with the same number of values. The shapes I've input should morph an oval shape (keyframe[0]) to a speech bubble shape (keyframe[1]).
The problem I am experiencing is that when I try to debug, it tells me that the svg element has values all of 0.
<path d="M0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, L0, 0, L0, 0, Z" fill="#ffffff" stroke="#000000"></path>
When the console shows me that the values it should have are
M-68.39999999999999, -18.787499999999998, Q-72.9, 0, -97.2, -4.5, L-97.2, -258.525, Q-121.5, -263.02500000000003, -116.99999999999999, -281.8125, L68.39999999999999, -281.8125, Q72.9, -300.59999999999997, 97.2, -296.1, L97.2, -42.075, Q121.5, -37.574999999999996, 116.99999999999999, -18.787499999999998, L48.6, -18.787499999999998, L24.3, 18.787499999999998, L0, -18.787499999999998, ZM-70.93333333333334, -19.483333333333334, Q-75.60000000000001, 0, -100.8, -4.666666666666666, L-100.8, -268.09999999999997, Q-126, -272.76666666666665, -121.33333333333333, -292.25, L70.93333333333334, -292.25, Q75.60000000000001, -311.73333333333335, 100.8, -307.06666666666666, L100.8, -43.63333333333333, Q126, -38.96666666666667, 121.33333333333333, -19.483333333333334, L50.4, -19.483333333333334, L25.2, 19.483333333333334, L0, -19.483333333333334, Z
There must be an error with my logic somewhere but I'm left scratching my head as to why this doesn't work.
JS:
$(function() {
var sponsorBubble = function(el, html, cornerRad) {
this.html = html,
this.width = el.parent().width(),
this.height = el.parent().height(),
this.arrowWidth = el.parent().width()/4,
this.arrowHeight = el.parent().height()/8,
this.cornerRad = cornerRad;
//ENSURE SAME NUMBER OF PATH SEGMENTS IN ALL KEYFRAMES (START TO END)
this.keypaths = [];
this.keypaths[0] = [
"M",
(this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"Q",
(this.width/2) - (this.arrowWidth/2), this.height - this.arrowHeight,
(this.width/2), this.height - this.arrowHeight,
"L",
(this.width/2), this.height - this.arrowHeight,
"Q",
(this.width/2) + (this.arrowWidth/2), this.height - this.arrowHeight,
(this.width/2) + (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"L",
(this.width/2) + (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"Q",
(this.width/2) + (this.arrowWidth/2), this.height,
(this.width/2), this.height,
"L",
(this.width/2), this.height,
"Q",
(this.width/2) - (this.arrowWidth/2), this.height,
(this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"L",
(this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"L",
(this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"L",
(this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
"Z"
];
this.keypaths[1] = [
"M", //STARTS AT BOTTOM LEFT, GOING CLOCKWISE
this.cornerRad, this.height-this.arrowHeight,
"Q",
0, this.height-this.arrowHeight,
0, this.height-this.arrowHeight-this.cornerRad,
"L",
0, this.cornerRad,
"Q",
0,0,
this.cornerRad, 0,
"L",
this.cornerRad+(this.width - (this.cornerRad*2)), 0,
"Q",
this.width, 0,
this.width, this.cornerRad,
"L",
this.width, this.cornerRad+(this.height-this.arrowHeight-(this.cornerRad*2)),
"Q",
this.width, this.height-this.arrowHeight,
this.width-this.cornerRad, this.height-this.arrowHeight,
"L",
(this.width/2)+(this.arrowWidth/2), this.height-this.arrowHeight,
"L",
this.width/2, this.height,
"L",
(this.width/2)-(this.arrowWidth/2), this.height-this.arrowHeight,
"Z"
];
};
sponsorBubble.prototype.getFrame = function(frame, total_steps, current_step) {
if (this.keypaths[frame + 1]) { //IF THERES FRAMES AFTER
for (var i = 0; i <= this.keypaths[frame].length; i++) {
//IF IS A LETTER
if (isNaN(this.keypaths[frame][i])) {
if (this.newpath && i < this.keypaths[frame].length - 1) {
this.newpath = this.newpath + this.keypaths[frame][i];
}
else if (!this.newpath) {
this.newpath = this.keypaths[frame][i];
}
else if (this.newpath && i == this.keypaths[frame].length - 1) {
this.newpath = this.newpath + this.keypaths[frame][i];
}
}
//IF IS A NUMBER
else {
if (this.newpath && i < this.keypaths[frame].length - 1) {
this.newpath = this.newpath + (((this.keypaths[frame + 1][i] - this.keypaths[frame][i]) / total_steps) * current_step) + ", ";
}
else {
this.newpath = this.newpath + this.keypaths[frame][i];
}
}
}
}
else { //NO FRAMES AFTER
for (var i = 0; i <= this.keypaths[frame].length; i++) {
//IF IS A LETTER
if (isNaN(this.keypaths[frame][i])) {
if (this.newpath && i < this.keypaths[frame].length - 1) {
this.newpath = this.newpath + this.keypaths[frame][i];
}
else if (!this.newpath) {
this.newpath = this.keypaths[frame][i];
}
else if (this.newpath && i === this.keypaths[frame].length - 1) {
this.newpath = this.newpath + this.keypaths[frame][i];
}
}
//IF IS A NUMBER
else {
if (this.newpath && i < this.keypaths[frame].length - 1) {
this.newpath = this.newpath + this.keypaths[frame][i] + ", ";
}
else {
this.newpath = this.newpath + this.keypaths[frame][i];
}
}
}
}
current_step++;
if (current_step < total_steps) {
console.log(this.newpath);
requestAnimationFrame(function() {
bub.getFrame(frame, total_steps, current_step);
});
}
}
snapper = Snap('#svg');
var bub = new sponsorBubble($('#svg'), 'test', 5, 20);
bub.getFrame(0, 30, 0);
var test = snapper.path(bub.newpath);
test.attr({
fill: 'white',
stroke: 'black'
});
});
HTML:
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="bubble.css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="snap.svg-min.js"></script>
<script type="text/javascript" src="bubble.js"></script>
</head>
<body>
<div id="inset">
<div id="inset2">
<svg id="svg" width="100%" height="100%"></svg>
</div>
</div>
</body>
</html>
CSS:
body, html {
width: 100%;
height: 100%;
border: 0;
padding: 0;
margin: 0;
}
#inset {
width: 20%;
height: 50%;
position: absolute;
bottom: 0;
left: 50%;
}
#inset2 {
width: 80%;
height: 100%;
}
JSfiddle: http://jsfiddle.net/bmjkz1rf/