Skip to content

Instantly share code, notes, and snippets.

@bokmann
Forked from madrobby/everytimezone.coffee
Created April 27, 2011 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bokmann/944643 to your computer and use it in GitHub Desktop.
Save bokmann/944643 to your computer and use it in GitHub Desktop.
First conversion of http://everytimezone.com/ JavaScript code to CoffeeScript
# Two things are important to note:
#
# 1) The code is fugly, because it was a JavaScript/iPad experiment.
# I know that it is ugly, so pretty please don't comment on that part.
# 2) I tried to use as many CoffeeScript features as possible,
# including but not limited to list comprehensions,
# heredocs, destructuring assignment and also the "do" operator
#
# I welcome comments about stuff that is not CoffeeScripty enough, or what I should
# write differently.
cities = [
[-10, 'Honolulu', 'HAST UTC-10']
[-7, 'San Francisco', 'PDT UTC-7']
[-5, 'Chicago', 'CDT UTC-5']
[-4, 'New York', 'EDT UTC-4']
[-3, 'Rio de Janeiro', 'BRT UTC-3']
[0, 'London', 'GMT UTC']
[2, 'Vienna', 'CET UTC+1']
[5.5, 'Mumbai', 'IST UTC+5:30'],
[8, 'Hong Kong', 'HKT UTC+8']
[9, 'Tokyo', 'JST UTC+9']
[10, 'Sydney', 'EST UTC+10']
[12, 'Auckland', 'NZST UTC+12']].reverse()
citiesright = false
config =
format: "ampm"
months = 'January February March April May June July August September October November December'.split ' '
ua = navigator.userAgent
webkit = ua.indexOf('AppleWebKit/') > -1
moz = ua.indexOf('Gecko') > -1 and not webkit
opera = ua.indexOf('Opera') > -1
ie = ua.indexOf('MSIE') > -1
offsp = null
transprop =
if webkit then 'webkitTransform'
else if ie then 'msTransform'
else if moz then 'MozTransform'
else if opera then 'OTransform'
else 'transform'
transstr =
if webkit then '-webkit-transform'
else if ie then '-ms-transform'
else if moz then '-moz-transform'
else if opera then '-o-transform'
transitionstr =
if webkit then '-webkit-transition'
else if ie then '-ms-transition'
else if moz then '-moz-transition'
else if opera then '-o-transition'
supportsTouch = document.createTouch?
scale = 72
now = new Date
current = now
day = current.getDate()
month = current.getMonth()
nowminutes = now.getHours() * 60 + now.getMinutes()
localoffset = now.getTimezoneOffset()
dragging = off
Function::delay = (seconds) -> setTimeout @, seconds * 1000
Date::addDays = (days) -> new Date @getTime()+(days * 1000 * 60 * 60 * 24)
$ = (id) ->
document.getElementById id
html = (id, html = '') ->
$(id).innerHTML = html
css = (id, style) ->
$(id).style.cssText += ';' + style
anim = (id, transform, opacity = 1, dur = 0.5) ->
css id, "#{transitionstr}:all #{dur}s; #{transstr}:
#{transform}; opacity:#{opacity}"
translateX = (element, x, anim = false) ->
return if isNaN x
element.style.cssText += ";#{transitionstr}:all 0.4s;" if anim
element.style[transprop] = if webkit and supportsTouch
"translate3d(#{x}px,0,0)"
else
"translateX(#{x}px)"
ctx = $('canvas').getContext '2d'
defaultg = ctx.createLinearGradient 0, 0, 230, 0
activeg = ctx.createLinearGradient 0, 0, 230, 0
localg = ctx.createLinearGradient 0, 0, 230, 0
roundg = ctx.createLinearGradient 0, 0, 0, 23
topg = ctx.createLinearGradient 0, 0, 0, 23
bottomg = ctx.createLinearGradient 0, 23, 0, 0
defaultg.addColorStop stop[0], stop[1] for stop in [
[0, '#4b4c4d'], [0.249,'#4b4c4d'], [0.25,'#575b5c']
[0.329,'#575b5c'], [0.33,'#6b7071'], [0.749,'#6b7071']
[0.75,'#575b5c'], [0.909,'#575b5c'], [0.91,'#4b4c4d']
[1, '#4b4c4d']]
activeg.addColorStop stop[0], stop[1] for stop in [
[0, '#5485b1'], [0.249,'#5485b1'], [0.25,'#3cafc5']
[0.329,'#3cafc5'], [0.33,'#55c8e4'], [0.749,'#55c8e4']
[0.75,'#3cafc5'], [0.909,'#3cafc5'], [0.91,'#5485b1']
[1, '#5485b1']]
localg.addColorStop stop[0], stop[1] for stop in [
[0, '#8abb29'], [0.249,'#8abb29'], [0.25,'#a5df3b']
[0.329,'#a5df3b'], [0.33,'#b8ff41'], [0.749,'#b8ff41']
[0.75,'#a5df3b'], [0.909,'#a5df3b'], [0.91,'#8abb29']
[1, '#8abb29']]
roundg.addColorStop 0, 'rgba(0,0,0,0)'
roundg.addColorStop 1, 'rgba(0,0,0,0.4)'
topg.addColorStop 0, 'rgba(255,255,255,0.3)'
topg.addColorStop 0.025, 'rgba(255,255,255,0)'
bottomg.addColorStop 0, 'rgba(255,255,255,0.3)'
bottomg.addColorStop 0.025, 'rgba(255,255,255,0)'
rr = (w, h, rad) ->
ctx.beginPath()
ctx.moveTo rad, 0
ctx.lineTo w - rad, 0
ctx.bezierCurveTo w, 0, w, 0, w, rad
ctx.lineTo w, h - rad
ctx.bezierCurveTo w, h, w, h, w - rad, h
ctx.lineTo rad, h
ctx.bezierCurveTo 0, h, 0, h, 0, h - rad
ctx.lineTo 0, rad
ctx.bezierCurveTo 0, 0, 0, 0, rad, 0
ctx.fill()
drawBox = (x, y, w, h, gradient = defaultg) ->
ctx.save()
ctx.translate x, y
ctx.fillStyle = gradient
ctx.clearRect 0, 0, w, h
rr w, h, 18
ctx.fillStyle = roundg
rr w, h, 18
ctx.fillStyle = topg
rr w, h, 18
ctx.fillStyle = bottomg
rr w, h, 18
ctx.restore()
hr2p = (hr) -> 50 + (-hr * (100 / scale))
ext = [hr2p(-12 - 24), hr2p(12)]
ext.push Math.abs(ext[1])+Math.abs(ext[0])
cel = []
tz = (id, city, zone, zonedesc) ->
cityWidth = ((700 / scale * 24) | 0) - 5 + 'px'
dy = current.addDays(-1)
dt = current.addDays(1)
el = document.createElement('div')
timeel = document.createElement('div')
nameel = document.createElement('div')
offsetLeft
el.className = "city-wrapper#{if (-zone * 60) == localoffset then ' local' else ''}"
el.id = "city_#{id}"
el.innerHTML = """
<div class="city" style="width:#{cityWidth}" id="city_#{id}_1">#{months[dy.getMonth()]} #{dy.getDate()}</div>
<div class="city" style="width:#{cityWidth}" id="city_#{id}_2">#{months[current.getMonth()]} #{current.getDate()}</div>
<div class="city" style="width:#{cityWidth}" id="city_#{id}_3">#{months[dt.getMonth()]} #{dt.getDate()}</div>
"""
$('cities').appendChild el
timeel.className = 'city-time'
$('time_info').appendChild timeel
timeel.style.cssText += ";top:#{(11 - id) * 60}px"
nameel.className = 'city-name'
nameel.innerHTML = "#{city}<span class='tz'>#{zonedesc}</span>"
$('cities_info').appendChild nameel
nameel.style.cssText += ";top:#{110 + id * 60}px"
css "city_#{id}", "left:#{hr2p(zone + 24)}%"
offsetLeft = $("city_#{id}").offsetLeft
c1 = $("city_#{id}_1")
x = c1.offsetLeft + offsetLeft
y = c1.offsetTop + (80 + (11 - id) * 60)
w = c1.offsetWidth
h = c1.offsetHeight
drawBox x, y, w, h
c2 = $("city_#{id}_2")
x2 = c2.offsetLeft + offsetLeft
y2 = c2.offsetTop + (80 + (11 - id) * 60)
w2 = c2.offsetWidth
h2 = c2.offsetHeight
drawBox x2, y2, w2, h2
c3 = $("city_#{id}_3")
x3 = c3.offsetLeft + offsetLeft
y3 = c3.offsetTop + (80 + (11 - id) * 60)
w3 = c3.offsetWidth
h3 = c3.offsetHeight
drawBox x3, y3, w3, h3
cel.push [
0, 0, 0, 0, 0, 0
$("city_#{id}_1")
$("city_#{id}_2")
$("city_#{id}_3")
false, false, false
timeel,
$("city_#{id}")
zone,
nameel,
false,
[x, y, w, h]
[x2, y2, w2, h2]
[x3, y3, w3, h3]
(-zone * 60) == localoffset
]
renderinfo = ->
n = offsp
p = n - cOffL + 48
cbase = now + localoffset / 60
i = cities.length
while i--
celc = cel[i]
c = cbase + celc[14]
c1 = c < 0
c3 = c >= 24
c2 = c >= 0 and !c3
if c1 and !celc[9]
celc[6].className = 'city active'
celc[9] = true
drawBox(celc[17][0], celc[17][1], celc[17][2], celc[17][3], if celc[20] then localg else activeg)
else if not c1 and celc[9]
celc[6].className = 'city'
celc[9] = false
drawBox(celc[17][0], celc[17][1], celc[17][2], celc[17][3])
if c2 and !celc[10]
celc[7].className = 'city active'
celc[10] = true
drawBox(celc[18][0], celc[18][1], celc[18][2], celc[18][3], if celc[20] then localg else activeg)
else if not c2 and celc[10]
celc[7].className = 'city'
celc[10] = false
drawBox(celc[18][0], celc[18][1], celc[18][2], celc[18][3])
if c3 and !celc[11]
celc[8].className = 'city active'
celc[11] = true
drawBox(celc[19][0], celc[19][1], celc[19][2], celc[19][3], if celc[20] then localg else activeg)
else if not c3 and celc[11]
celc[8].className = 'city'
celc[11] = false
drawBox(celc[19][0], celc[19][1], celc[19][2], celc[19][3])
celc[12].innerHTML = formattime now + celc[14] + (localoffset / 60)
if not celc[16]
celc[16] = true
celc[15].style.cssText += ";top:#{celc[13].offsetTop}px"
translateX $('time_info'), 15 + n + cOffL
if n<170 and not citiesright
translateX $('cities_info'), cOffL + 550, true
citiesright = true
else if n>500 and citiesright
translateX $('cities_info'), cOffL, true
citiesright = false
updateinfo = ->
html 'localtime', formattime now
tn = document.createTextNode ' '
$('localtime').appendChild tn
renderinfo()
formattime = (time) ->
time = 24 - Math.abs time % 24 if time < 0
time = time % 24 if time >= 24
mins = Math.abs ((time * 60) % 60) | 0
mins = "0#{mins}" if mins < 10
time = time | 0
if config.format == "ampm"
suffix = "am"
[time, suffix] = [time % 12, "pm"] if time >= 12
time = 12 if time == 0
"#{time}:#{mins} #{suffix}"
else
"#{time}:#{mins}"
timeselector = (px) ->
p = hr2p -now - localoffset / 60
d = -((p / 100) * 700) + 700 / (24 / now)
if px
css 'now', 'left:0px'
translateX $('now'), px
offsp = px
else
css 'now', "left:#{p}%"
offsp = p * 7
updateinfo()
currenttime = (time) ->
p = hr2p(-time - localoffset / 60)
d = -((p / 100) * 700) + 700 / (24 / time)
css 'cnow', 'left:'+p+'%'
html 'clocaltime', formattime(time)
setupGrid = ->
html 'cities'
html 'cities_info'
cel = []
i = cities.length
while i--
tz i, cities[i][1], cities[i][0], cities[i][2]
translateX $('cities_info'), cOffL
timeselector()
cOffL = $('content').offsetLeft
setupGrid()
if webkit
(-> anim('wrapper','rotateY(0deg)'))
.delay(0.5)
currenttime nowminutes / 60
now = nowminutes / 60
timeselector()
css 'canvas', "left:#{cOffL}px"
updateLocalTime = ->
localNow = new Date
currenttime localNow.getHours() + localNow.getMinutes() / 60
setInterval updateLocalTime, 1000
updateLocalTime()
move = (event) ->
return if not dragging
pageX = event.pageX
pageX = event.touches[0].pageX if event.touches?
now = (pageX - cOffL - 350) / 700 * scale - localoffset / 60
timeselector pageX - cOffL
event.preventDefault() if event.touches?
if window.orientation?
window.changeorientation = do ->
$('wrapper').className = "o#{orientation}"
cOffL = $('content').offsetLeft
arguments.callee
wrapper = $('wrapper')
wrapper[if supportsTouch then "ontouchstart" else "onmousedown"] = (event) ->
element = event.target
element = element.parentNode if element.nodeType isnt 1
return if element.tagName? and element.tagName in ['A', 'IMG']
if event.touches?
return if event.touches[0].pageY < 50
return if event.touches[0].pageX < cOffL
dragging = on
move(event)
wrapper[if supportsTouch then "ontouchmove" else "onmousemove"] = move
wrapper[if supportsTouch then "ontouchend" else "onmouseup"] = -> dragging = off
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment