Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A Pen by Tomasz Foster.

Caffeine Animation

HTML5 and JavaScript animation that shows the molecular structure of Caffeine. The double bonds in Caffeine are displayed by darkening the lines.

A Pen by Tomasz Foster on CodePen.


<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<div class="caffeine">
<div class="startText">
<p>move your mouse here</p>
<img src="" class="arrow">
<div id="container" style="height:200px;width:200px"></div>
<script src=""></script>
/*This JavaScript is an animation that, upon mouseover, will reveal
a caffeine molecule, complete with darker bonds that signify the
double bonds.
One improvement I'd like to make later would be to assign the ending locations
geometrically, versus using key-value pairs for the ending locations.
This would also allow me to dynamically name and create tweens based
upon the number of keys. Another day... */
//first, let's set the stage
var stage = new Kinetic.Stage({
container: 'container',
width: 200,
height: 200
//create a layer in this stage
var layer = new Kinetic.Layer({
y: -30,
x: 10
//hexagon numbers
var h1 = 34.4;
var h2 = 20;
//pentagon numbers
var p1 = 12.3;
var p2 = 38;
var p3 = 23.5;
var p4 = 32.4;
/* here are the key-value pairs for the ending coordinates.*/
var points = {1:[50, 260, 50, 220],
2:[50, 220, 50+h1, 220-h2],
3:[50+h1, 220-h2, 50+(2*h1), 220],
4:[50+(2*h1), 220, 50+(2*h1), 260],
5:[50+(2*h1), 260, 50+h1, 260+h2],
6:[50+h1, 260+h2, 50, 260],
7:[50, 220, 50-h1, 220-h2],
8:[50+h1, 220-h2, 50+h1, 180-h2],
9:[50, 260, 50-h1, 260+h2],
10:[50+h1, 260+h2, 50+h1, 300+h2],
11:[50+(2*h1), 260, 50+(2*h1)+p2, 260+p1],
12:[50+(2*h1), 220, 50+(2*h1)+p2, 220-p1],
13:[50+(2*h1)+p2, 220-p1, 50+(2*h1)+p2+p3, 240],
14:[50+(2*h1)+p2+p3, 240, 50+(2*h1)+p2, 260+p1],
15:[50+(2*h1)+p2, 220-p1, 50+(2*h1)+p2+p1, 220-p2-p1]
//create key-value pairs for the tweens
var tweens = {};
/*now, let's make each 'stick' and assign it (almost) the same
properties, only variation is in the starting points, where I shift
them each by 5 pixels, since they each have a strokeWidth of 5 */
var list = {};
var temp = 'stick'+(i+1);
list[temp] = new Kinetic.Spline({
points: [60+(i*5), 130, 60+(i*5), 90], //here's the only difference
tension: 0.5,
opacity: 0.6,
stroke: '#FFF',
strokeWidth: 5,
lineCap: 'round'
//add each new layer
var temp = 'stick'+i+'Tween';
//the tweens with single bonds depicted with opacity = 0.6
if (i!=3 && i!=7 && i!=8 && i!=13){
tweens[temp] = new Kinetic.Tween({
node: list['stick'+(i+1)],
duration: 1,
easing: Kinetic.Easings.EaseOut,
y: -100,
opacity: 0.5,
points: points[i+1]
//the tweens with double bonds depicted with opacity = 1.0
tweens[temp] = new Kinetic.Tween({
node: list['stick'+(i+1)],
duration: 1,
easing: Kinetic.Easings.EaseOut,
y: -100,
opacity: 1,
points: points[i+1]
//now add all the layers to the stage
var keys = Object.keys(tweens);
//on mouseover, play all the tweens
stage.getContainer().addEventListener('mouseover', function() {
//on mouseout, reverse the tweens
stage.getContainer().addEventListener('mouseout', function() {
// here's the transform for the alternative text
$(".altText").animate({ color: "#CCC" }, 2000);
$(".startText").animate({ color: "#301E12" }, 1000);
$(".arrow").animate({opacity: 0}, 1000);
$(".altText").animate({ color: "#301E12" }, 1000);
body {
background: #301E12;
.caffeine { position: absolute; top:50%; left:50%; margin:-200px 0 0 -100px; }
.caffeine h2 {
font-family: helvetica;
font-size: 50px;
text-align: center;
text-shadow: 2px 2px #666;
.caffeine .altText {
font-family: helvetica;
font-size: 20px;
text-align: center;
.startText {
font-family: helvetica;
font-size: 15px;
text-align: center;
margin-right: 50px;
.startText img {
position: absolute;
margin-left: 100px;
margin-top: -40px;
.altText {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment