Introduction

Step-by-step recreation

mrt create Velocity3dDemo cd Velocity3dDemo rm -rf Velocity3dDemo*

mrt add coffeescript mrt add jade mrt add stylus mrt add velocityjs

mkdir -p client/stylesheets

client/stylesheets/app.styl

@import 'nib' * padding: 0 margin: 0 body background-color: #060b14 overflow: hidden color: #ffffff font-family: Helvetica Neue, Open Sans, sans-serif font-weight: 100 a color: #4bc2f1 text-decoration: none &:hover text-decoration: underline #container perspective: 50px transform-origin: 50% 100% pointer-events: none opacity: 0.55 #welcome position: fixed width: 22rem left: 50% top: 45% margin-top: -1rem margin-left: -11rem font-weight: 200 opacity: 0.65 text-align: center font-size: 0.775rem line-height: 1.05rem letter-spacing: 0.135em word-spacing: -0.075rem @media screen and (max-width: 400px) #welcome font-size: 0.45rem !important #logo position: fixed right: 0.75rem bottom: 0.65rem cursor: pointer text-decoration: none color: #d6d6d6 font-size: 2rem letter-spacing: 0.025em #logoDot color: #d74580 .dot position: fixed width: 30px height: 30px border-radius: 30px background-color: #4bc2f1

client/index.jade

head title Velocity 3D demo body +index template(name='index') #welcome No WebGL. No Canvas. Just pure DOM. a#logo(href='http://julian.com/research/velocity/') Velocity . js #container

client/index.coffee

Template.index.rendered = -> # Device detection isWebkit = /Webkit/i.test navigator.userAgent isChrome = /Chrome/i.test navigator.userAgent isMobile = window.ontouchstart isnt undefined isAndroid = /Android/i.test navigator.userAgent isIE = document.documentMode # Redirection if isMobile and isAndroid and not isChrome alert 'Use Chrome on Android' # Helpers # Randomly generate an integer between 2 numbers. r = (min, max) -> Math.floor(Math.random() * (1 + max - min)) + min # Dot creation # Differentiate dot counts on based on device and browser capabilities dotsCount = if isMobile then (if isAndroid then 40 else 60) else ( if isChrome then 175 else 125) dotsHtml = '' for i in [0..dotsCount] dotsHtml += '<div class="dot"></div>' $dots = $ dotsHtml # Setup $container = $ '#container' $welcome = $ '#welcome' screenWidth = window.screen.availWidth screenHeight = window.screen.availHeight chromeHeight = screenHeight - (document.documentElement.clientHeight or screenHeight) translateZMin = - 725 translateZMax = 600 containerAnimationMap = perspective: [215, 50] opacity: [0.90, 0.55] # IE10+ produce odd glitching issues when you rotateZ on a parent element subjected to 3D transforms. containerAnimationMap.rotateZ = [5, 0] if not(isIE) # Animation # Fade out the welcome message. $welcome.velocity opacity: [0, 0.65] , display: 'none' delay: 3500 duration: 1100 # Animate the dot's container. $container .css 'perspective-origin', "#{screenWidth/2}px #{(screenHeight*0.45)-chromeHeight}px" .velocity containerAnimationMap, {duration: 800, loop: 1, delay: 3250} # Special visual enhancement for WebKit browsers which are faster at box-shadow manipulation ($dots.css 'boxShadow', '0px 0px 4px 0px #4bc2f1') if isWebkit $dots .velocity translateX: [ -> '+=' + r -screenWidth/2.5, screenWidth/2.5 -> r 0, screenWidth ] translateY: [ -> '+=' + r -screenHeight/2.75, screenHeight/2.75 -> r 0, screenHeight ] translateZ: [ -> '+=' + r translateZMin, translateZMax -> r translateZMin, translateZMax ] opacity: [ -> Math.random() -> Math.random() + 0.1 ] , duration: 6000 easing: 'easeInOutsine' .velocity 'reverse', {easing: 'easeOutQuad'} .velocity opacity: 0 , duration: 2000 complete: -> $welcome .html "<a href='https://www.youtube.com/watch?v=MDLiVB6g2NY&hd=1'>Watch the making of this demo.</a><br /><br />Go create something amazing.<br />Sincerely, <a href='http://twitter.com/shapiro'>@Shapiro</a>" .velocity opacity: 0.75 , duration: 3500 display: 'block' .appendTo $container

mrt

mrt deploy velocity3ddemo.meteor.com

The original tutorial