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.
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="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> | |
| <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.js"></script> | |
| <div class="caffeine"> | |
| <div class="startText"> | |
| <p>move your mouse here</p> | |
| <img src="https://raw.github.com/TomaszFoster/tomaszfoster.github.io/master/img/arrow.png" class="arrow"> | |
| </div> | |
| <div id="container" style="height:200px;width:200px"></div> | |
| <h2>caffeine</h2> | |
| </div> | |
| <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></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 = {}; | |
| for(i=0;i<15;i++){ | |
| 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 | |
| layer.add(list[temp]); | |
| 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] | |
| }); | |
| }else{ | |
| //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 | |
| stage.add(layer); | |
| var keys = Object.keys(tweens); | |
| //on mouseover, play all the tweens | |
| stage.getContainer().addEventListener('mouseover', function() { | |
| for(i=0;i<15;i++){ | |
| tweens[keys[i]].play(); | |
| } | |
| }); | |
| //on mouseout, reverse the tweens | |
| stage.getContainer().addEventListener('mouseout', function() { | |
| for(i=0;i<16;i++){ | |
| tweens[keys[i]].reverse(); | |
| } | |
| }); | |
| // here's the transform for the alternative text | |
| $("#container").hover( | |
| function(){ | |
| $(".altText").animate({ color: "#CCC" }, 2000); | |
| $(".startText").animate({ color: "#301E12" }, 1000); | |
| $(".arrow").animate({opacity: 0}, 1000); | |
| }, | |
| function(){ | |
| $(".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; | |
| color:#DDD; | |
| text-align: center; | |
| text-shadow: 2px 2px #666; | |
| margin-top:0px; | |
| } | |
| .caffeine .altText { | |
| font-family: helvetica; | |
| font-size: 20px; | |
| color:#301E12; | |
| text-align: center; | |
| } | |
| .startText { | |
| font-family: helvetica; | |
| font-size: 15px; | |
| color:#CCC; | |
| text-align: center; | |
| margin-right: 50px; | |
| } | |
| .startText img { | |
| position: absolute; | |
| margin-left: 100px; | |
| margin-top: -40px; | |
| } | |
| .altText { | |
| margin-top:-20px; | |
| } |