Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Caffeine Molecule Animation

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.


<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<script type="text/javascript" src="script.js"></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