Created
January 20, 2012 17:58
-
-
Save harrislapiroff/1648690 to your computer and use it in GitHub Desktop.
Oberlin College's Snow Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KEYFRAME_RATE = 200 | |
HORIZONTAL_DELTA = 2 | |
VERTICAL_DELTA = 4 | |
EASING_FUNCTION = "linear" | |
TOTAL_SNOWFLAKES = 50 | |
EXCLUDE_MOBILE = true | |
CANVAS_WIDTH_FN = () -> $('#all').width() | |
CANVAS_HEIGHT_FN = () -> 125 | |
# by_probability will return val1 prob% of the time, val2 otherwise | |
# prob should be a decimal b/w 0 and 1 | |
by_probability = (val1, val2, prob) -> | |
rand = Math.random() | |
if rand < prob | |
return val1 | |
else | |
return val2 | |
class Snowflake | |
constructor: (@registry) -> | |
rand = Math.random() | |
radius = Math.max(2,10*rand) | |
opacity = 1+Math.log(1-rand) | |
@el = @registry.paper.circle(0, 0, radius) | |
@el.attr('opacity', opacity) | |
@el.attr('fill', '#FFF') | |
@el.attr('stroke', 'none') | |
@position(0, 0) | |
position: (x, y) => | |
# place a snowflake instantly at x, y coords | |
@x = x | |
@y = y | |
@el.stop() | |
@el.attr({'cx': x, 'cy': y}) | |
move: (x, y) => | |
# animate a snowflake to a particular location | |
@x = x | |
@y = y | |
@el.animate({'cx': x, 'cy': y}, KEYFRAME_RATE, EASING_FUNCTION) | |
fall: () => | |
# calculate the snowflake's next location and animate it to that location | |
ydelta = VERTICAL_DELTA | |
xdelta = by_probability(HORIZONTAL_DELTA, -HORIZONTAL_DELTA, .5) * Math.random() | |
maxY = @registry.height | |
maxX = @registry.width | |
if @y <= maxY | |
@move(@x + xdelta, @y + ydelta) | |
else if maxY > 0 | |
@position(Math.floor(Math.random()*maxX), -40) | |
class Snowfield | |
constructor: () -> | |
# create the snowfield array | |
@snowflakes = [] | |
# create the canvas | |
@paper = Raphael(0, 0, 0, 0) | |
# add some attributes to the actual HTML element | |
@paper.canvas.id = "snow" | |
if Modernizr.testProp "pointerEvents" | |
$('html').addClass('pointerEvents') | |
$(@paper.canvas).attr('pointer-events', 'none') | |
else | |
$('html').addClass('noPointerEvents') | |
# for some reason pointer events don't work quite right in this version of webkit, so here's how we deal, gross browser sniffing | |
if $.browser.webkit and parseInt($.browser.version) < 535 | |
$('html').removeClass('pointerEvents').addClass('noPointerEvents') | |
# set the canvas size | |
@canvas_size_refresh() | |
# set an interval for making the snowflakes fall | |
@go() | |
# set an event listener to resize the canvas when the window resizes | |
$(window).resize(@canvas_resize_handler) | |
add: (snowflake) => | |
# add a snowflake to the snowfield array | |
@snowflakes.push(snowflake) | |
remove: (snowflake) => | |
# remove a snowflake from the snowfield array | |
for i in [0...@snowflakes.length] | |
do () => | |
if @snowflakes[i] == snowflake | |
@snowflakes.splice(i, i) | |
create_snowflake: () => | |
# create a single snowflake and place it randomly in the snowfield | |
snowflake = new Snowflake(this) | |
@add(snowflake) | |
x = Math.floor(Math.random()*@width) | |
y = Math.floor(Math.random()*@height) | |
snowflake.position(x, y) | |
create_batch: (count) => | |
# create a batch of snowflakes | |
for num in [1..count] | |
do () => | |
@create_snowflake() | |
batch_fall: () => | |
# make every snowflake in the snowfield fall | |
for snowflake in @snowflakes | |
do (snowflake) => | |
if snowflake | |
snowflake.fall() | |
pause: () => | |
clearInterval(@animation_interval) | |
@paused = true | |
go: () => | |
@animation_interval = setInterval(@batch_fall, KEYFRAME_RATE) | |
@paused = false | |
set_dimensions: (width, height) => | |
# low-level method to set the dimensions of the canvas and cache those dimensions as properties on the Snowfield | |
@width = width | |
@height = height | |
@paper.setSize(@width, @height) | |
canvas_resize_handler: () => | |
# this can safely be called on a window resize event and the canvas_size_refresh method will only fire when the window has stopped being resized. | |
unless @paused | |
@pause() | |
if @resize_timeout | |
clearTimeout(@resize_timeout) | |
@resize_timeout = setTimeout(@canvas_size_refresh, 100) | |
canvas_size_refresh: () => | |
# refresh the canvas size based on the values of CANVAS_WIDTH_FN and CANVAS_HEIGHT_FN | |
@set_dimensions(CANVAS_WIDTH_FN(), CANVAS_HEIGHT_FN()) | |
if @paused | |
@go() | |
create_batch = (snowfield) -> | |
# creates a batch of snowflakes in a snowfield | |
snowflake_count = TOTAL_SNOWFLAKES | |
snowfield.create_batch(snowflake_count) | |
init = ($) -> | |
# cut out here if this is a mobile device | |
if EXCLUDE_MOBILE and navigator.userAgent.match(/mobile|opera m(ob|in)/i) | |
return | |
# create and populate a new snowfield | |
snowfield = new Snowfield() | |
create_batch(snowfield) | |
$(window).load(init) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.noPointerEvents #hd, .noPointerEvents #glob{ | |
position:relative; | |
z-index: 1337 !important; | |
} | |
.pointerEvents #snow{ | |
z-index:1337; | |
} | |
#all::before{ | |
content:" "; | |
display:block; | |
position:absolute; | |
top:0; | |
left:0; | |
height:126px; | |
width:100%; | |
background: url('left.png') left bottom no-repeat, url('center.png') left bottom repeat-x, url('right.png') right bottom no-repeat; | |
-webkit-box-reflect:below 0 -webkit-linear-gradient(bottom, rgba(0,0,0,.5), rgba(0,0,0,0) 20%); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment