Skip to content

Instantly share code, notes, and snippets.

@domwashburn
Created January 15, 2017 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domwashburn/748991764519c9d79d53166953bf8b8f to your computer and use it in GitHub Desktop.
Save domwashburn/748991764519c9d79d53166953bf8b8f to your computer and use it in GitHub Desktop.
Visualizing Rhythm (SVG)
<svg class="metronome" id="metronome"></svg>
<!--
for finding the end point of the arcs:
http://stackoverflow.com/questions/12342102/html5-get-coordinates-of-arcs-end
-->
class Metronome {
constructor(parentSvg) {
this.parent = document.getElementById(parentSvg);
this.s = Snap(`#${parentSvg}`);
this.beatRing = {
cx: this.parent.clientWidth / 2,
cy: this.parent.clientHeight / 2,
radius: 130
};
this.beats = 8;
// this.beats = 8;
// this.subBeat = .25;
// this.bpm = 80;
// this.beatsPerSecond = this.bpm / 60;
this.beatSizes = {
down: 15,
beat: 10,
sub: 5
};
this.arcAngle = (360 / this.beats);
this.arc = 2 * Math.PI * this.beatRing.radius * (this.arcAngle / 360);
this.arcLength = (this.arc / (this.beats * this.arc)) * 2;
this.arcOffset = this.arcLength * Math.PI;
this.allBeatCoordinates = [];
}
build() {
this.buildBeatRing();
this.plotBeats();
this.drawBeat();
// console.log(this.allBeatCoordinates)
}
buildBeatRing() {
var { cx, cy, radius } = this.beatRing;
var main = this.s.circle(cx, cy, radius);
main.attr({
class: 'beat-ring'
})
}
plotBeats() {
var { cx, cy, radius } = this.beatRing;
var curBeatX,
curBeatY
for (let i = 0; i < this.beats; i++) {
var arcStart = this.arcLength * i + 1;
// var arcEnd = (arcLength * i + 1) + arcLength;
var curAngle = this.arcAngle * i;
curBeatX = cx + Math.sin(arcStart*Math.PI)*radius;
curBeatY = cy + Math.cos(arcStart*Math.PI)*radius;
var beatCoordinates = {cx: curBeatX, cy: curBeatY};
this.allBeatCoordinates.push(beatCoordinates);
}
}
drawBeat() {
this.allBeatCoordinates.map( (coordinates, i) => {
let { cx, cy } = coordinates;
let { down, beat, sub } = this.beatSizes;
let curBeat;
if ( i === 0 ) {
curBeat = this.s.circle(cx, cy, down);
curBeat.attr({class: 'beat__down'})
// return beat
} else {
curBeat = this.s.circle(cx, cy, beat);
curBeat.attr({class: 'beat__up'})
}
return curBeat
})
}
}
const visualizer = new Metronome('metronome');
visualizer.build();
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
// variables
$beatStroke: hsla(168, 89%, 30%, 1);
$beat: hsla(168, 89%, 70%, 1);
$downBeat: hsla(13, 89%, 70%, 1);
.metronome {
width: 100vw;
height: 100vh;
}
body {
padding: 0;
margin: 0;
}
.beat-ring {
fill: hsla(0, 0, 0, 0);
stroke: $beatStroke;
stroke-width: 5px;
}
.beat {
stroke: $beatStroke;
stroke-width: 5px;
&__down {
@extend .beat;
fill: $downBeat;
}
&__up {
@extend .beat;
fill: $beat;
}
}
.stats {
position: absolute;
top: 0;
color: rgba(150, 60, 30, 1);
background: rgba(240, 140, 70, .5);
border: 1px solid rgba(150, 60, 30, 1);
font-weight: 100;
font-family: 'Helvetica neue', Helvetica, Arial, sans-serif;
font-size: 24px;
padding: 8px 18px;
border-radius: 5px;
transition: background .2s;
}

Visualizing Rhythm (SVG)

Visualizing Rhythm

I stumbled upon this great TED Ed presenation about reimagining rhythm visualization and of course the wheels in my mind began to turn. I thought this would be the perfect project to start learning how to work with snap.svg and GSAP.

"I'm not a math major"

I'm willing to admit that walking into this I had no idea how to calculate the pieces of this circle. I just knew that I wanted to do it so ... I googled until I got it right.

I found helpful tips and formulae here:
These may be helpful in the future

A Pen by Dominick Washburn on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment