Pausing + time display
This commit is contained in:
parent
5e05b0d1cb
commit
aa3c28701d
@ -2,4 +2,42 @@ class AsciiIo.HudView extends Backbone.View
|
||||
tagName: 'div'
|
||||
className: 'hud'
|
||||
|
||||
events:
|
||||
'click .toggle': 'togglePlay'
|
||||
|
||||
initialize: (options) ->
|
||||
@duration = undefined
|
||||
@createChildViews()
|
||||
|
||||
createChildViews: ->
|
||||
toggle = '<div class="toggle">'
|
||||
progress = '<div class="progress"><div class="gutter">'
|
||||
time = '<div class="time">'
|
||||
|
||||
@$el.append(toggle)
|
||||
@$el.append(progress)
|
||||
@$el.append(time)
|
||||
|
||||
setDuration: (@duration) ->
|
||||
|
||||
togglePlay: ->
|
||||
@trigger('hud-play-click')
|
||||
|
||||
onPause: ->
|
||||
@$('.toggle').addClass('paused')
|
||||
|
||||
onResume: ->
|
||||
@$('.toggle').removeClass('paused')
|
||||
|
||||
updateTime: (time) ->
|
||||
@$('.time').html(@formattedTime(time))
|
||||
|
||||
if @duration
|
||||
progress = 100 * time / 1000 / @duration
|
||||
@setProgress progress
|
||||
|
||||
setProgress: (percent) ->
|
||||
@$('.gutter').width("#{percent}%")
|
||||
|
||||
formattedTime: (time) ->
|
||||
(time / 1000).toFixed(2)
|
||||
|
@ -3,30 +3,26 @@ class AsciiIo.Movie
|
||||
SPEED: 1.0
|
||||
|
||||
constructor: (@model) ->
|
||||
@reset()
|
||||
@startTimeReporter()
|
||||
_.extend(this, Backbone.Events)
|
||||
|
||||
reset: ->
|
||||
@frameNo = 0
|
||||
@dataIndex = 0
|
||||
@currentTime = 0
|
||||
@processedFramesTime = 0
|
||||
_.extend(this, Backbone.Events)
|
||||
@playedTimeSum = 0
|
||||
@playing = false
|
||||
@lastFrameTime = undefined
|
||||
@timeElapsedBeforePause = undefined
|
||||
|
||||
isLoaded: ->
|
||||
@model.get('escaped_stdout_data') != undefined
|
||||
|
||||
load: ->
|
||||
@model.fetch
|
||||
success: => @play()
|
||||
|
||||
play: ->
|
||||
@nextFrame()
|
||||
|
||||
pause: ->
|
||||
# TODO
|
||||
|
||||
togglePlay: ->
|
||||
# TODO
|
||||
|
||||
seek: (percent) ->
|
||||
# TODO
|
||||
success: =>
|
||||
@trigger('movie-loaded', @model)
|
||||
@play()
|
||||
|
||||
timing: ->
|
||||
@model.get('stdout_timing_data')
|
||||
@ -40,56 +36,123 @@ class AsciiIo.Movie
|
||||
|
||||
@_data
|
||||
|
||||
nextFrame: () ->
|
||||
# return if @currentData.length > 100
|
||||
play: ->
|
||||
return if @isPlaying()
|
||||
|
||||
if frame = @timing()[@frameNo++] # @frameNo += 1
|
||||
if @isFinished()
|
||||
@restart()
|
||||
else if @isPaused()
|
||||
@resume()
|
||||
else
|
||||
@start()
|
||||
|
||||
start: ->
|
||||
@playing = true
|
||||
@lastFrameTime = (new Date()).getTime()
|
||||
@nextFrame()
|
||||
|
||||
stop: ->
|
||||
@playing = false
|
||||
clearInterval @nextFrameTimeoutId
|
||||
@timeElapsedBeforePause = (new Date()).getTime() - @lastFrameTime
|
||||
|
||||
restart: ->
|
||||
@reset()
|
||||
@start()
|
||||
@startTimeReporter()
|
||||
|
||||
pause: ->
|
||||
return if @isPaused()
|
||||
|
||||
@stop()
|
||||
@trigger('movie-playback-paused')
|
||||
|
||||
resume: ->
|
||||
return if @isPlaying()
|
||||
|
||||
@playing = true
|
||||
frame = @timing()[@frameNo]
|
||||
[delay, count] = frame
|
||||
delay -= @timeElapsedBeforePause
|
||||
@processFrameWithDelay(delay)
|
||||
@trigger('movie-playback-resumed')
|
||||
|
||||
togglePlay: ->
|
||||
if @isPlaying() then @pause() else @play()
|
||||
|
||||
isPlaying: ->
|
||||
@playing
|
||||
|
||||
isPaused: ->
|
||||
!@isPlaying() and !@isFinished()
|
||||
|
||||
isFinished: ->
|
||||
!@isPlaying() and @isLoaded() and @frameNo >= @timing().length
|
||||
|
||||
seek: (percent) ->
|
||||
@pause()
|
||||
@rewindTo(percent)
|
||||
@play()
|
||||
|
||||
rewindTo: (percent) ->
|
||||
# TODO
|
||||
|
||||
startTimeReporter: ->
|
||||
@timeReportId = setInterval(
|
||||
=> @trigger('movie-time', @currentTime())
|
||||
100
|
||||
)
|
||||
|
||||
stopTimeReporter: ->
|
||||
clearInterval @timeReportId
|
||||
|
||||
currentTime: ->
|
||||
if @isPlaying()
|
||||
now = (new Date()).getTime()
|
||||
delta = now - @lastFrameTime
|
||||
@playedTimeSum + delta
|
||||
else if @isPaused()
|
||||
@playedTimeSum + @timeElapsedBeforePause
|
||||
else if @isFinished()
|
||||
@playedTimeSum
|
||||
else
|
||||
0 # not started
|
||||
|
||||
nextFrame: ->
|
||||
if frame = @timing()[@frameNo]
|
||||
[delay, count] = frame
|
||||
|
||||
frameData = @data().slice(@dataIndex, @dataIndex + count)
|
||||
@dataIndex += count
|
||||
|
||||
if delay <= @MIN_DELAY
|
||||
@triggerAndSchedule(frameData)
|
||||
@processFrame()
|
||||
else
|
||||
realDelay = delay * 1000 * (1.0 / @SPEED)
|
||||
setTimeout(
|
||||
=>
|
||||
@trigger('movie-awake')
|
||||
@triggerAndSchedule(frameData)
|
||||
realDelay
|
||||
)
|
||||
@processFrameWithDelay(realDelay)
|
||||
|
||||
true
|
||||
else
|
||||
@playing = false
|
||||
@stopTimeReporter()
|
||||
@trigger('movie-finished')
|
||||
# @terminal.stopCursorBlink()
|
||||
# console.log "finished in #{((new Date()).getTime() - @startTime) / 1000} seconds"
|
||||
|
||||
false
|
||||
|
||||
triggerAndSchedule: (data) ->
|
||||
@trigger('movie-frame', data)
|
||||
processFrameWithDelay: (delay) ->
|
||||
@nextFrameTimeoutId = setTimeout(
|
||||
=>
|
||||
@trigger('movie-awake')
|
||||
@processFrame()
|
||||
delay
|
||||
)
|
||||
|
||||
processFrame: ->
|
||||
frame = @timing()[@frameNo]
|
||||
[delay, count] = frame
|
||||
|
||||
frameData = @data().slice(@dataIndex, @dataIndex + count)
|
||||
@trigger('movie-frame', frameData)
|
||||
|
||||
@frameNo += 1
|
||||
@dataIndex += count
|
||||
@playedTimeSum += delay * 1000
|
||||
@lastFrameTime = (new Date()).getTime()
|
||||
|
||||
@nextFrame()
|
||||
|
||||
# processFrame: (count) ->
|
||||
# # return
|
||||
# # @currentData += @data.slice(@dataIndex, @dataIndex + count)
|
||||
# data = @data.slice(@dataIndex, @dataIndex + count)
|
||||
# # console.log data
|
||||
# @dataIndex += count
|
||||
# @trigger('movie-frame', data)
|
||||
|
||||
# @currentData = @interpreter.feed(@currentData)
|
||||
|
||||
# if @currentData.length > 0
|
||||
# @logStatus(count)
|
||||
|
||||
# logStatus: (count) ->
|
||||
# console.log 'rest: ' + Utf8.decode(@currentData)
|
||||
|
||||
# if @currentData.length > 100
|
||||
# head = @currentData.slice(0, 100)
|
||||
# hex = ("0x#{c.charCodeAt(0).toString(16)}" for c in head)
|
||||
# console.log "failed matching: '" + Utf8.decode(head) + "' (" + hex.join() + ") [pos: " + (@dataIndex - count) + "]"
|
||||
# return
|
||||
|
@ -31,6 +31,18 @@ class AsciiIo.PlayerView extends Backbone.View
|
||||
@hudView.on 'hud-seek-click', (percent) =>
|
||||
@movie.seek(percent)
|
||||
|
||||
@movie.on 'movie-loaded', (asciicast) =>
|
||||
@hudView.setDuration(asciicast.get('duration'))
|
||||
|
||||
@movie.on 'movie-playback-paused', =>
|
||||
@hudView.onPause()
|
||||
|
||||
@movie.on 'movie-playback-resumed', =>
|
||||
@hudView.onResume()
|
||||
|
||||
@movie.on 'movie-time', (time) =>
|
||||
@hudView.updateTime(time)
|
||||
|
||||
@movie.on 'movie-frame', (frame) =>
|
||||
@vt.feed(frame)
|
||||
|
||||
@ -39,7 +51,4 @@ class AsciiIo.PlayerView extends Backbone.View
|
||||
|
||||
@movie.on 'movie-finished', =>
|
||||
@terminalView.stopCursorBlink()
|
||||
|
||||
play: ->
|
||||
if @movie.isLoaded()
|
||||
@movie.play()
|
||||
@hudView.setProgress(100)
|
||||
|
@ -12,9 +12,6 @@ class AsciiIo.TerminalView extends Backbone.View
|
||||
@startCursorBlink()
|
||||
# this.updateScreen();
|
||||
# this.render();
|
||||
#
|
||||
# this.renderLine(0); // we only need 1 line
|
||||
# this.element.css({ width: this.element.width(), height: this.element.height() });
|
||||
|
||||
createChildElements: ->
|
||||
i = 0
|
||||
|
@ -45,18 +45,51 @@
|
||||
|
||||
.hud {
|
||||
background-color: #333;
|
||||
opacity: 0.85;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
bottom: 10px;
|
||||
display: none;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
height: 30px;
|
||||
color: white;
|
||||
|
||||
-webkit-transition: opacity 0.3s ease-in-out;
|
||||
|
||||
.toggle {
|
||||
background-color: blue;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
float: left;
|
||||
|
||||
&.paused {
|
||||
background-color: orange;
|
||||
}
|
||||
}
|
||||
|
||||
.player:hover .hud {
|
||||
display: block;
|
||||
.progress {
|
||||
background-color: black;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
float: left;
|
||||
|
||||
.gutter {
|
||||
background-color: #333;
|
||||
width: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
background-color: green;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .hud {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ module AsciicastsHelper
|
||||
lines: #{asciicast.terminal_lines},
|
||||
model: new AsciiIo.Asciicast({ id: #{asciicast.id} })
|
||||
});
|
||||
|
||||
window.player.play();
|
||||
});
|
||||
</script>
|
||||
EOS
|
||||
|
Loading…
Reference in New Issue
Block a user