summaryrefslogtreecommitdiff
path: root/js/record.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/record.js')
-rw-r--r--js/record.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/js/record.js b/js/record.js
new file mode 100644
index 0000000..fe8d0a1
--- /dev/null
+++ b/js/record.js
@@ -0,0 +1,162 @@
+(function(){
+ 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 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.innerHTML = template
+ document.body.appendChild(el)
+ bind()
+ }
+ function bind(){
+ curtain = document.getElementById("curtain")
+ outline = document.getElementById("outline")
+ controls = document.getElementById("outline")
+ 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)
+ outline.style.display = "none"
+ controls.style.display = "none"
+ }
+ function box_start(e){
+ x = e.pageX
+ y = e.pageY
+ w = 1
+ h = 1
+ dragging = true
+ 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"
+ }
+ function box_size(e){
+ if (! dragging) return
+ w = e.pageX - x
+ h = e.pageY - y
+ outline.style.width = px(w)
+ outline.style.height = px(h)
+ }
+ function box_end(e){
+ dragging = false
+ controls.style.display = "block"
+ enable("record")
+ document.getElementById("record").focus()
+ }
+ 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(){
+ count = parseInt(document.getElementById("framecount").value)
+ delay = parseFloat(document.getElementById("framedelay").value) * 1000
+ 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 (){
+ 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)
+ }
+})()
+