(function(){ if (document.getElementById("gif-recorder")) return; var canvases = document.getElementsByTagName("canvas") if (canvases.length == 0) { alert("no canvas found"); return; } var source = canvases[0] var encoder = new GifEncoder() encoder.on("encoded-frame", encoded_frame) encoder.on("rendered", rendered_bytes) encoder.on("rendered-url", rendered_url) var w, h, x, y; var w_el, h_el, x_el, y_el; var last_t, frame_t, count, delay, done; var frames = [] var curtain, outline var dragging = false var lastGif init() function init(){ document.body.style.width = "100%" document.body.style.height = "100%" document.body.parentNode.style.width = "100%" document.body.parentNode.style.height = "100%" // var template = document.getElementById("template").innerHTML var el = document.createElement("div") el.id = "gif-recorder" // el.innerHTML = template el.innerHTML = UI_TEMPLATE document.body.appendChild(el) bind() } function bind(){ curtain = document.getElementById("curtain") outline = document.getElementById("outline") controls = document.getElementById("controls") w_el = document.getElementById("w_el") h_el = document.getElementById("h_el") x_el = document.getElementById("x_el") y_el = document.getElementById("y_el") document.getElementById("record").addEventListener("click", record, false) document.getElementById("save").addEventListener("click", save, false) curtain.addEventListener("mousedown", box_start, false) curtain.addEventListener("mousemove", box_size, false) curtain.addEventListener("mouseup", box_end, false) w_el.addEventListener("change", box_position, false) h_el.addEventListener("change", box_position, false) x_el.addEventListener("change", box_position, false) y_el.addEventListener("change", box_position, false) outline.style.display = "none" controls.style.display = "block" } function defer(callback){ var timeout = null return function(){ clearTimeout(timeout) timeout = setTimeout(callback, 300) } } function box_start(e){ e.stopPropagation() x = e.pageX y = e.pageY w = 1 h = 1 dragging = true box_resize() } function box_position(){ w = _int(w_el) h = _int(h_el) x = _int(x_el) y = _int(y_el) box_resize() } function box_resize(){ if (isNaN(w) || isNaN(h) || isNaN(x) || isNaN(y)) return w_el.value = ~~(w) h_el.value = ~~(h) x_el.value = ~~(x) y_el.value = ~~(y) outline.style.left = px(x-1) outline.style.top = px(y-1) outline.style.width = px(w) outline.style.height = px(h) outline.style.display = "block" enable("record") } function box_size(e){ if (! dragging) return e.stopPropagation() w = e.pageX - x h = e.pageY - y box_resize() } function box_end(e){ e.preventDefault() dragging = false controls.style.display = "block" document.getElementById("record").focus() } function _int(el){ return parseInt(typeof el == "string" ? document.getElementById(el).value : el.value) } function _float(el){ return parseFloat(typeof el == "string" ? document.getElementById(el).value : el.value) } function show(id){ document.getElementById(id).style.display="block" } function hide(id){ document.getElementById(id).style.display="none" } function enable(id){ document.getElementById(id).removeAttribute("disabled") } function disable(id){ document.getElementById(id).setAttribute("disabled","disabled") } function px(n){ return (~~n) + "px" } function record(e){ e.stopPropagation() count = _int("framecount") delay = _float("framedelay") * 1000 console.log(count, delay) if (isNaN(count) || isNaN(delay)) return done = 0 frame_t = 0 build() capture() last_t = +new Date() requestAnimationFrame(recordloop) status("recording") disable("record") } function recordloop(){ var canvas = document.createElement("canvas") var t = +new Date() frame_t += t - last_t last_t = t if (frame_t > delay) { frame_t -= delay capture() } if (done == count) { render() } else { requestAnimationFrame(recordloop) } } function build(){ frames = new Array(count) for (var i = 0; i < count; i++){ frames[i] = document.createElement("canvas") frames[i].height = h frames[i].width = w } } function capture(){ var frame = frames[done++] var ctx = frame.getContext('2d') ctx.fillStyle = document.body.backgroundColor ctx.fillRect(0,0,w,h) ctx.drawImage(source, x, y, w, h, 0, 0, w, h) } function render(){ encoder.reset() encoder.addFrames(frames, delay) status("encoding") try { encoder.encode() } catch (e) { rendering = false status(e) throw e } } function status(s){ document.getElementById("status").innerHTML = s } function encoded_frame(done,count){ status("encoded " + done + " / " + count) } function rendered_bytes(bytes){ status(filesize(bytes.length)) } function rendered_url(url){ var image = new Image () lastGif = image.src = url document.getElementById("preview").innerHTML = "" document.getElementById("preview").appendChild(image) rendering = false enable("record") enable("save") } function save (e){ e.stopPropagation() if (! lastGif) return; var filename = (window.location.host + window.location.pathname).replace(/[^a-zA-Z0-9]/g,"-").replace(/-+/,"-") var blob = dataUriToBlob(lastGif) saveAs(blob, filename + "-" + (+new Date()) + ".gif"); } function filesize(n) { if (n < 1e3) return n + " bytes" if (n < 1e6) return decimalString(n/1e3) + " kb" if (n < 1e9) return decimalString(n/1e6) + " mb" return "WAY TOO BIG DUDE" } function decimalString(n){ var m = Math.floor(n); return m + "." + Math.round((n-m)*10) } })()