|
class GifPlayer |
|
constructor: (url) -> |
|
@modal = $('.modal').modal(backdrop: false) |
|
@progressbar = @modal.find('.progress .bar') |
|
@canvas = $('canvas').get(0) |
|
@frames = [] |
|
@handler = |
|
hdr: @proxy(@parserHandlers.header) |
|
gce: @proxy(@parserHandlers.graphicControl) |
|
img: @proxy(@parserHandlers.image) |
|
eof: @proxy(@parserHandlers.end) |
|
@load(url) |
|
|
|
proxy: (callback) -> |
|
$.proxy(callback, this) |
|
|
|
load: (url) -> |
|
self = this |
|
$.ajax |
|
url: url |
|
beforeSend: (req) -> |
|
req.overrideMimeType 'text/plain; charset=x-user-defined' |
|
complete: (req) -> |
|
self.stream = new Stream(req.responseText) |
|
parseGIF(self.stream, self.handler) |
|
|
|
progress: -> |
|
percent = Math.round(@stream.pos / @stream.data.length * 100) |
|
@progressbar.width(percent + '%') |
|
|
|
parserHandlers: |
|
header: (header) -> |
|
@progress() |
|
@header = header |
|
@canvas.width = @header.width |
|
@canvas.height = @header.height |
|
graphicControl: (gce) -> |
|
@progress() |
|
if @context |
|
@frames.push(@context.getImageData(0, 0, @header.width, @header.height)) |
|
@context = null |
|
@transparency = if gce.transparencyGiven then gce.transparencyIndex else null |
|
@disposal_method = gce.disposalMethod |
|
image: (image) -> |
|
@progress() |
|
self = this |
|
unless @context |
|
@context = @canvas.getContext('2d') |
|
color_table = if image.lctFlag then image.lct else @header.gct |
|
image_data = @context.getImageData(image.leftPos, image.topPos, image.width, image.height) |
|
$.each image.pixels, (index, pixel) -> |
|
if self.transparency != pixel |
|
image_data.data[index * 4 + 0] = color_table[pixel][0] |
|
image_data.data[index * 4 + 1] = color_table[pixel][1] |
|
image_data.data[index * 4 + 2] = color_table[pixel][2] |
|
image_data.data[index * 4 + 3] = 255 |
|
else if self.disposal_method == 2 || self.disposal_method == 3 |
|
image_data.data[i * 4 + 3] = 0 |
|
@context.putImageData(image_data, image.leftPos, image.topPos) |
|
end: -> |
|
@progress() |
|
if @context |
|
@frames.push(@context.getImageData(0, 0, @header.width, @header.height)) |
|
@modal.hide() |
|
new Player(@frames).play() |
|
|
|
class Player |
|
constructor: (frames)-> |
|
@canvas = $('canvas').get(0) |
|
@context = @canvas.getContext('2d') |
|
@frames = frames |
|
@index = 0 |
|
@playing = false |
|
@delay = 100 |
|
@before = null |
|
$(document).keydown(@proxy(@action)) |
|
|
|
proxy: (callback) -> |
|
$.proxy(callback, this) |
|
|
|
set: -> |
|
@context.putImageData(@frames[@index], 0, 0) |
|
|
|
step: -> |
|
return unless @playing |
|
@set(@index) |
|
@index += 1 |
|
if @index >= @frames.length |
|
@index = 0 |
|
setTimeout(@proxy(@step), @delay) |
|
|
|
play: -> |
|
@playing = true |
|
@step() |
|
|
|
stop: -> |
|
@playing = false |
|
|
|
toggle: -> |
|
if @playing |
|
@stop() |
|
else |
|
@play() |
|
|
|
next: -> |
|
return if @playing |
|
@index += 1 |
|
if @index >= @frames.length |
|
@index = 0 |
|
@set() |
|
|
|
prev: -> |
|
return if @playing |
|
@index -= 1 |
|
if @index < 0 |
|
@index = @frames.length - 1 |
|
@set() |
|
|
|
setDelay: -> |
|
if @before |
|
time = new Date() - @before |
|
if time <= 1000 |
|
@delay = time / 8 |
|
@before = new Date() |
|
|
|
action: (event) -> |
|
switch event.which |
|
when 13 |
|
event && event.preventDefault() |
|
@toggle() |
|
when 39, 74 |
|
event && event.preventDefault() |
|
@next() |
|
when 37, 75 |
|
event && event.preventDefault() |
|
@prev() |
|
when 32 |
|
event && event.preventDefault() |
|
@setDelay() |
|
|
|
$(document).ready -> |
|
images = ["baaaaa.gif", "dog.gif", "driver.gif", "hoshi.gif", "imamachine.gif", "madohomu.gif", "nuko.gif", "sporty.gif", "circle.gif", "dokan.gif", "facebook.gif", "hutomomo.gif", "kawaii.gif", "mine.gif", "perfume.gif", "tile.gif"] |
|
new GifPlayer('/images/' + images[Math.round(Math.random() * images.length)]) |