vendor/javascripts/prez-controller.js.coffee in prez-0.0.2 vs vendor/javascripts/prez-controller.js.coffee in prez-0.0.3

- old
+ new

@@ -1,8 +1,15 @@ +$.setTimeout = (t, fn) -> setTimeout fn, t +$.setInterval = (t, fn) -> setInterval fn, t + +$.fn.slideDuration = -> + parseInt(@data("duration") || "0", 10) + class Prez DEFAULT_OPTIONS = useHash: true + duration: 0 constructor: (options) -> @options = $.extend {}, DEFAULT_OPTIONS, options @window = options.window @document = @window.document @@ -20,19 +27,32 @@ true else false $(".prez-slide", @document).each (i) -> $(@).attr "data-slide", "#{i + 1}" + @startTime = Date.now() @changeSlideTo 1 unless changeToHashSlide() $(@window).on "hashchange", changeToHashSlide $(@document).on "keydown", Prez.handlers.keyDown changeSlideTo: (nextValue) -> $next = $ ".prez-slide[data-slide='#{nextValue}']", @document return false if $next.size() == 0 $(".prez-slide", @document).hide() $next.show() + @slideStartTime = Date.now() + @slideDuration = $next.slideDuration() + + # When unspecified, the slide duration is an even amount based + # on the remaining slides that don't have a specific duration + if @slideDuration <= 0 + $remainingUntimed = $next.nextAll(".prez-slide").filter -> $(@).slideDuration() <= 0 + @slideDuration = @remainingPresentationSeconds() / ($remainingUntimed.size() + 1) + + if @slideDuration < 0 + @slideDuration = 0 + @options.slideChanged? $next, nextValue true changeSlideBy: (amount) -> current = parseInt $(".prez-slide:visible", @document).data("slide"), 10 @@ -43,10 +63,59 @@ nextSlide: -> @changeSlideBy 1 prevSlide: -> @changeSlideBy -1 end: -> @window.close() + remainingPresentationSeconds: -> + Math.floor(@options.duration - ((Date.now() - @startTime) / 1000)) + + remainingPresentationTime: -> + Prez.secondsToTime @remainingPresentationSeconds(), Prez.timeLevels(@options.duration) + + remainingSlideSeconds: -> + Math.floor(@slideDuration - ((Date.now() - @slideStartTime) / 1000)) + + remainingSlideTime: -> + Prez.secondsToTime @remainingSlideSeconds(), Prez.timeLevels(@slideDuration) + + @timeLevels: (s) -> + if s >= (60 * 60) + 3 + else if s >= 60 + 2 + else + 1 + + @timeToSeconds: (t) -> + values = t.split ":" + result = parseInt(values.pop() || "0", 10) + result += parseInt(values.pop() || "0", 10) * 60 + result += parseInt(values.pop() || "0", 10) * 60 * 60 + result + + @secondsToTime: (s, minLevels = 1) -> + pad = (n, size) -> + result = "#{n}" + + while result.length < size + result = "0#{result}" + + result + + s = Math.floor s + s = Math.abs s + seconds = s % 60 + minutes = Math.floor(s / 60) % 60 + hours = Math.floor(s / 60 / 60) + + if hours > 0 || minLevels >= 3 + "#{hours}:#{pad minutes, 2}:#{pad seconds, 2}" + else if minutes > 0 || minLevels == 2 + "#{minutes}:#{pad seconds, 2}" + else + "#{seconds}" + KEY_ENTER = 13 KEY_SPACE = 32 KEY_LEFT = 37 KEY_RIGHT = 39 @@ -60,23 +129,41 @@ Prez.current?.prevSlide() when KEY_ENTER, KEY_SPACE, KEY_RIGHT e.preventDefault() Prez.current?.nextSlide() + timeChange: -> + return unless Prez.current + $(".prez-total-duration").text Prez.current.remainingPresentationTime() + seconds = Prez.current.remainingPresentationSeconds() + $(".prez-total-duration").toggleClass("prez-danger-time", seconds <= 60 && seconds >= 0) + $(".prez-total-duration").toggleClass("prez-over-time", seconds < 0) + $(".prez-current-slide-duration").text Prez.current.remainingSlideTime() + seconds = Prez.current.remainingSlideSeconds() + $(".prez-current-slide-duration").toggleClass("prez-danger-time", seconds <= 3 && seconds >= 0) + $(".prez-current-slide-duration").toggleClass("prez-over-time", seconds < 0) + + if Math.floor(Date.now() / 250) % 2 == 0 + $(".prez-danger-time").hide() + else + $(".prez-danger-time").show() + + # Ensure transitions stay shown + $(".prez-total-duration:not(.prez-danger-time)").show() + $(".prez-current-slide-duration:not(.prez-danger-time)").show() + $(document).on "click", "#new-window", (e) -> return if Prez.current - callback = => + $.setTimeout 1, => if $(this).is(".active") $("#new-window #launch-message").text "Launch in new window" $("#new-window .glyphicon").addClass("glyphicon-new-window").removeClass("glyphicon-unchecked") else $("#new-window #launch-message").text "Launch in this window" $("#new-window .glyphicon").removeClass("glyphicon-new-window").addClass("glyphicon-unchecked") - setTimeout callback, 1 - $(document).on "click", "#launch", (e) -> e.preventDefault() return if Prez.current unless $("#new-window").is(".active") @@ -95,17 +182,20 @@ iframePrez = new Prez window: iframe useHash: false Prez.current = new Prez + duration: Prez.timeToSeconds($("#prez-duration").val()) window: window.open("", "prez", "width=640,height=480") slideChanged: ($slide, slideNumber) -> notes = $slide.find(".prez-notes").html() || "" $("#slide-notes").html notes $(".current-slide-number").text $slide.data("slide") + Prez.handlers.timeChange() iframePrez.changeSlideTo slideNumber + $(".total-slides").text $(".prez-slide", Prez.current.document).size() $("#pre-launch").hide() $("#post-launch").show() $(Prez.current.window).bind "beforeunload", -> $("#post-launch").hide() @@ -124,8 +214,9 @@ $(document).on "click", ".end-prez", (e) -> e.preventDefault() Prez.current?.end() $(document).on "keydown", Prez.handlers.keyDown +$.setInterval 50, Prez.handlers.timeChange $ -> $("#in-window-not-implemented-modal").modal show: false