diff options
| -rw-r--r-- | dither-localstorage.html | 132 | ||||
| -rw-r--r-- | js/api/get.js (renamed from cgi-bin/shader_api.js) | 25 | ||||
| -rw-r--r-- | js/api/set.js (renamed from cgi-bin/javascript_example.js) | 0 | ||||
| -rw-r--r-- | js/frames.js | 170 | ||||
| -rw-r--r-- | js/render.js | 106 | ||||
| -rw-r--r-- | js/shader.js | 2 | ||||
| -rw-r--r-- | shader-animate.html | 71 | ||||
| -rw-r--r-- | shader-api.html | 156 | ||||
| -rw-r--r-- | shader-picker.html | 324 |
9 files changed, 605 insertions, 381 deletions
diff --git a/dither-localstorage.html b/dither-localstorage.html new file mode 100644 index 0000000..5e9bff9 --- /dev/null +++ b/dither-localstorage.html @@ -0,0 +1,132 @@ +<!doctype html> +<html> +<head> +<title>Dither</title> +<style> + form { display: inline-block; } + #gallery-images { display: block; max-height: 210px; overflow-y: auto; } + #gallery-images img, #gallery-images canvas { max-width: 200px; height: 100px; margin: 5px; cursor: pointer; } +</style> +</head> +<body> + +<div id="gallery"> + <form id="gallery-search"> + <input type="text" id="dumpfm-search-query" value="duck bill"> + <button id="gallery-search">DUMP SEARCH</button> + </form> + <button id="gallery-random">IM RANDOM</button> + <span id="status"></span> + <div id="gallery-images"></div> +</div> + +<div id="dither"> +<button id="random">random</button> +<button id="pattern2">pattern2</button> +<button id="pattern3">pattern3</button> +<button id="pattern4">pattern4</button> +<button id="pattern2Lite">pattern2lite</button> +<button id="pattern3Lite">pattern3lite</button> +<button id="pattern4Lite">pattern4lite</button> +<button id="floydSteinberg">floyd-steinberg</button> +<button id="right">right</button> +</div> +<div id="images"></div> + + +</body> +<script type="text/javascript" src="js/vendor/jquery/jquery.min.js"></script> +<script type="text/javascript" src="js/vendor/canvasquery.js"></script> +<script type="text/javascript" src="js/vendor/gif.js"></script> +<script type="text/javascript" src="js/canvasquery.dither.js"></script> +<script type="text/javascript" src="js/asdf.js"></script> +<script type="text/javascript" src="js/image.js"></script> +<script type="text/javascript" src="js/gallery.js"></script> +<script type="text/javascript"> + +var algo = 'random'; +var url = "img/abyss.png"; +var imgs = [] +var anim = [] +var complete = 0 +var viewport = cq(100, 100) +$("#images").append(viewport.canvas) + +var ui = function(){} + +ui.init = function(){ + gallery.choose = ui.choose + gallery.init() + ui.bind() + ui.animate() + asdf.random() +} + +ui.bind = function(){ + var buttons = $("#dither button") + for (var i = 0; i < buttons.length; i++) { + (function(n){ + buttons[n].onclick = function(){ + algo = buttons[n].id; + ui.build() + } + })(i) + } +} + +ui.choose = function(){ + status("loading image..") + loadImage( this.src, ui.ready ); +} + +ui.ready = function(){ + status("ready") + loading = false + if (window.gif) { + frames = gif.frames + } + else { + fc = cq(img.width, img.height) + fc.drawImage(img, 0, 0) + frames = [ { ctx: fc.context } ] + } + w = viewport.canvas.width = frames[0].ctx.canvas.width + h = viewport.canvas.height = frames[0].ctx.canvas.height + ui.build() +} + +ui.build = function (){ + anim = [] + for (var i in frames) { + anim.push( ui.dither(frames[i].ctx).context ) + } +} + +ui.animate = function(t){ + requestAnimationFrame(ui.animate) + if (! anim.length) return; + + if (window.gif && window.gif.currentFrame) { + var idx = gif.currentFrame(t) + var frame = anim[idx] + } + else { + var frame = anim[0] + } + viewport.clearRect(0,0,w,h).drawImage(frame.canvas, 0, 0, w, h); +} + +ui.dither = function (frame){ + var cc = cq(w, h) + cc.drawImage(frame.canvas, 0, 0, w, h); + cc[algo + "Dither"]( ) + return cc +} + +function status(s){ $("#status").html(s); console.log(s) } + +$(ui.init) + +</script> +</html> + diff --git a/cgi-bin/shader_api.js b/js/api/get.js index dd43130..ae06dbd 100644 --- a/cgi-bin/shader_api.js +++ b/js/api/get.js @@ -31,6 +31,10 @@ ShaderAPI.range = function(limit, offset, cb){ // latest - get the latest N shaders // limit: number of shaders to fetch ShaderAPI.latest = function(limit, cb){ + if (! cb) { + cb = limit + limit = ShaderAPI.limit + } ShaderAPI.fetch({ f: "range", limit: limit || ShaderAPI.limit @@ -66,7 +70,7 @@ ShaderAPI.username = function(username, cb){ } // list_users - list all users -ShaderAPI.list_users = function(list_users, cb){ +ShaderAPI.list_users = function(cb){ ShaderAPI.fetch({ f: "list_users" }, cb) @@ -81,12 +85,17 @@ ShaderAPI.originals = function(cb){ // fetch - AJAX wrapper ShaderAPI.fetch = function(params, cb){ - $.getJSON("/cgi-bin/im/shader/view", params, function(data){ - if (data.SUCCESS) { - cb(null, data.data) - } - else if (data.ERROR) { - cb(data.ERROR, data.data) - } + $.ajax({ + url: "http://asdf.us/cgi-bin/im/shader/view", + data: params, + dataType: "jsonp", + success: function(data){ + if (data.SUCCESS) { + cb(null, data.data) + } + else if (data.ERROR) { + cb(data.ERROR, data.data) + } + } }) } diff --git a/cgi-bin/javascript_example.js b/js/api/set.js index 1e7e31f..1e7e31f 100644 --- a/cgi-bin/javascript_example.js +++ b/js/api/set.js diff --git a/js/frames.js b/js/frames.js new file mode 100644 index 0000000..0ae256c --- /dev/null +++ b/js/frames.js @@ -0,0 +1,170 @@ + +function add_frame(){ + var frame_count = $("#framecount").int() + if (frame_count < 2) { + add_single_frame() + } + else { + add_frames(frame_count) + } +} +function add_single_frame(){ + var $el = $("<div>") + $el.html( $("#frame-template").html() ) + $el.attr('index', $("#frames div").length) + var frame = cc.clone().appendTo($el.find(".frame")[0]) + frame.canvas.className = "fullsize" + frame.canvas.style.display = "none" + var thumb = cc.clone().resize(100,100).appendTo($el.find(".frame")[0]) + $("#frames").append($el) + $("#render").enable() +} +function add_frames(frame_count){ + rendering = true + var t = old_t - start_t - pause_t + var frame_delay = $("#frameinterval").float() * 1000 + var frame + for (var i = 0; i < frame_count; i++) { + frame = giveFrame(t) + t += frame_delay + shade(frame, t) + add_single_frame() + } + rendering = false +} +function remove_frame(){ + $(this).closest("div").remove() + if ($("#frames div").length == 0) { + $("#render").disable() + } +} +function remove_all_frames(){ + $("#frames").empty() +} +function shuffle_frames(){ + var shuffled = [] + var $frames = $("#frames div") + $("#frames").empty().append(shuffle($frames)) +} +function reverse_frames(){ + var $frames = $("#frames div") + $("#frames").empty().append(reverse($frames)) +} +function weave_frames(){ + var $frames = $("#frames div") + $("#frames").empty().append(weave($frames)) +} +function sort_frames(){ + var $frames = $("#frames div") + var sorted = $frames.map(function(i,el){ console.log(i,el); return [[ el.getAttribute('index'), el ]] }) + .sort(function(a,b){ return a[0]-b[0] }) + .map(function(i,e){ console.log( e ); return e[1] }) + $("#frames").empty().append(sorted) +} + +function render (){ + if (rendering) return + rendering = true + encoder.reset() + var delay = $("#framedelay").float() * 1000 || 100 + $("#frames canvas.fullsize").each(function(){ + var frame = cq(this.width, this.height).fillStyle($("#background").string()).fillRect(0,0,this.width, this.height).drawImage(this,0,0) + encoder.addFrame(frame.canvas, delay) + }) + $("#pause,#render,#add-frame").disable() + $("#rendered").find("img").remove() + $("#rendered").show() + // really bad results with neuquant? + // status("quantizing") + // encoder.quantize() + status("encoding") + try { + encoder.encode() + } catch (e) { + $("#pause,#render,#add-frame").enable() + rendering = false + status(e) + throw e + } + $("#render").html("rendering") +} + +function status(s){ $(".status").html(s) } + +var encoder = new GifEncoder() + +encoder.on("quantized", function(url){ + status("encoding") + encoder.encode() +}) + +encoder.on("encoded-frame", function(done,count){ + status("encoded " + done + " / " + count) +}) + +encoder.on("rendered", function(bytes){ + status(filesize(bytes.length)) +}) + +encoder.on("rendered-url", function(url){ + var image = new Image () + lastGif = image.src = url + $("#rendered").append(image) + $("#uploaded-url").hide().val("") + $("#save,#upload,#rendered").show() + $("#pause,#render,#add-frame,#save,#upload").enable() + $("#render").html("render") + rendering = false + pause(true) +}) + +function get_filename(){ + var basename = $("#url").val().replace(/^.*\//,"").replace(/\..*$/,"").replace(/[^-_ a-zA-Z0-9]/g,"") + var username = user.username + var filename = basename + "-" + username + "-" + (+new Date()) + ".gif" + return filename.replace(/ /g,"_").replace(/-+/g,"-") +} +function save (){ + if (! lastGif) return; + var filename = get_filename() + var blob = dataUriToBlob(lastGif) + saveAs(blob, filename); +} +function saveJSON (data, filename) { + var bytes = JSON.stringify(data) + var buf = new ArrayBuffer(bytes.length); + var arr = new Uint8Array(buf); + for (var i = 0; i < bytes.length; i++) { + arr[i] = bytes.charCodeAt(i); + } + + var blob = new Blob([arr], { type: "text/json" }); + blob.slice = blob.slice || blob.webkitSlice; + + saveAs(blob, filename); +} + +function upload(){ + var filename = get_filename() + var username = user.username + var blob = dataUriToBlob(lastGif) + uploadImage({ + blob: blob, + filename: filename, + username: username, + success: function(data){ + + // data.url + // data.filesize + // data.success + + console.log(data); + status("uploaded"); + $("#uploaded-url").show().focus().val(data.url) + }, + error: function(data){ + console.log(data) + status("error uploading: " + data.error) + } + }); +} diff --git a/js/render.js b/js/render.js new file mode 100644 index 0000000..fdb0125 --- /dev/null +++ b/js/render.js @@ -0,0 +1,106 @@ +var frame, img_frame; +var timeout, raf_id, start_t = 0, old_t = 0, pause_t = 0 +var paused = false, dragging = false, rendering = false, scrolling = false, deferring = false, scrollTimeout = null; +var fps = 30; + +function choose (){ + imageURL = this.src + loading = true + $("#url").val(imageURL) + loadImage(imageURL, ready) +} +function load(){ + loading = true + var imageURL = $("#url").val() + loadImage(imageURL, ready) +} + +function ready(){ + loading = false + if (window.gif) { + frame = gif.frames[0] + w = cc.canvas.width = frame.ctx.canvas.width + h = cc.canvas.height = frame.ctx.canvas.height + for (var i=0, f; f=gif.frames[i]; i++){ + f.cloneData = f.ctx.getImageData(0,0,w,h) + } + } + else { + fc = cq(img.width, img.height) + fc.drawImage(img, 0, 0) + frame = img_frame = { ctx: fc.context } + w = cc.canvas.width = frame.ctx.canvas.width + h = cc.canvas.height = frame.ctx.canvas.height + frame.cloneData = frame.ctx.getImageData(0,0,w,h) + } +} + +function giveFrame(t){ + if (window.gif) { + if (gif.currentFrame) { + return gif.frames[gif.currentFrame(t)] + } + else { + return gif.frames[0] + } + } + else if (window.img) { + return img_frame + } + else { + return cq(w, h) + } +} + +function reset(){ + start_t = old_t + pause_t = 0 + pause(false) + $("#rendered img").remove() + draw(0) +} + +function pause(state){ + $("#pause").toggleClass("paused", paused = typeof state == "boolean" ? state : ! paused).html(paused ? "paused" : "pause") +} + +function step_forward(){ + var step = $("#framedelay").float() * 1000 || 100 + old_t += step + draw(old_t) + pause(true) +} + +function animate(t){ + raf_id = requestAnimationFrame(animate); + + var step_t = t - old_t + old_t = t + + if (paused || dragging || rendering || scrolling || deferring) { + pause_t += step_t + if (scrolling) { + scrolling = false + deferring = true + } + else { + deferring = false + } + return + } + + // var timing = +(new Date()) + draw(t) + // timing = +(new Date()) - timing + fps = avg(fps, 1000/step_t, 4) + // status(~~(fps) + " fps") +} + +function draw(t) { + t -= start_t + t -= pause_t + frame = giveFrame(t) + shade(frame, t) +} + +function status(s){ $("#status").html(s); console.log(s) } diff --git a/js/shader.js b/js/shader.js index 2f5fda1..19c049b 100644 --- a/js/shader.js +++ b/js/shader.js @@ -1,6 +1,6 @@ var shader_build = function(){ var fn_str = document.getElementById('shader').value - if (!fn_str.length) return + if (!fn_str.length) fn_str = "" try { var fn = new Function('x','y','t','d', fn_str) shader = fn diff --git a/shader-animate.html b/shader-animate.html index 80d71aa..6591d6d 100644 --- a/shader-animate.html +++ b/shader-animate.html @@ -33,6 +33,8 @@ delay <input type="text" id="delay" value="60"> <script type="text/javascript" src="js/canvasquery.dither.js"></script> <script type="text/javascript" src="js/color.js"></script> <script type="text/javascript" src="js/image.js"></script> +<script type="text/javascript" src="js/render.js"></script> +<script type="text/javascript" src="js/shader.js"></script> <script type="text/javascript" src="js/util.js"></script> <script type="text/javascript"> @@ -43,67 +45,22 @@ $(init) function init(){ $("#url").change(load) - $("#demo").click(function(){ demo("#first") }) - $("#dither-demo").click(function(){ demo("#second") }) - demo('#first') + $("#demo").click(function(){ run("#first") }) + $("#dither-demo").click(function(){ run("#second") }) + run('#first') + load() - draw() -} -function demo(el){ - $el = $(el) - s = $el.html() - $("#shader").html(s) -} -function load(){ - loading = true - var imageURL = $("#url").val() - loadImage(imageURL, ready) -} -var frame; -function ready(){ - loading = false - if (window.gif) { - frame = gif.frames[0] - } - else { - fc = cq(img.width, img.height) - fc.drawImage(img, 0, 0) - frame = { ctx: fc.context } - } - w = cc.canvas.width = frame.ctx.canvas.width - h = cc.canvas.height = frame.ctx.canvas.height -} + document.getElementById('shader').addEventListener('input', shader_build); + shader_build() -var timeout = null; -function draw(t){ - requestAnimationFrame(draw); - shade(frame, t) + requestAnimationFrame(animate) } -function shade(frame, t){ - try { - if (window.gif) frame = giveImage() - var f = $("#shader").val() - if (!f.length) return; - var shader = new Function('x','y','t', f) - var imageData = frame.ctx.getImageData(0,0,w,h) - var data = imageData.data - for (var x = 0; x < w; x++) { - for (var y = 0; y < h; y++) { - q = 4*(y*w+x) - r = data[q], g = data[q+1], b = data[q+2], a = data[q+3] - result = shader(x,y,t) - data[q] = r - data[q+1] = g - data[q+2] = b - data[q+3] = a - } - } - cc.putImageData(imageData,0,0) - } - catch (e){ - console.log(e) - } +function run(el){ + $el = $(el) + s = $el.html() + $("#shader").html(s) + shader_build() } </script> diff --git a/shader-api.html b/shader-api.html new file mode 100644 index 0000000..9020136 --- /dev/null +++ b/shader-api.html @@ -0,0 +1,156 @@ +<!doctype html> +<html> +<head> +<style type="text/css"> +#url { width: 300px; } +#width,#height,#frames,#delay {width: 30px; } +#shader { width: 400px; height: 247px; font-family: fixed; } +div { float: left; padding: 10px;} +form { display: inline-block; } +#shader-api,#gallery { clear: right; width:100%; padding: 0; } +#shader-gallery,#gallery-images { display: block; max-height: 210px; overflow-y: auto; width: 100%; } +#shader-gallery img,#shader-gallery canvas,#gallery-images img, #gallery-images canvas { max-width: 200px; height: 100px; margin: 5px; cursor: pointer; } +.shader { + width: 100px; +} +#username { width: 40px; } +a { color: #00f; } +#shader-id { width: 40px; } +</style> +</head> +<body> + +<!-- +<div id="gallery"> + <div id="gallery-form"> + <form id="gallery-search"> + <input type="text" id="dumpfm-search-query" value="duck bill"> + <button id="gallery-search">DUMP SEARCH</button> + </form> + <button id="gallery-random">IM RANDOM</button> + <span class="status"></span> + </div> + <div id="gallery-images"></div> +</div> +--> + +<div id="shader-api"> + <input type="text" id="shader-id" disabled><button id="fetch-info" disabled>info</button> + <button id="fetch-history" disabled>history</button> + | + <button id="fetch-originals" disabled>originals</button> + <button id="fetch-all">all</button> + <button id="fetch-latest">latest</button> + <button id="fetch-next-page" disabled>next page</button> + <select id="pick-user"> + <option>fetching users..</option> + </select> + + <div id="shader-gallery"> + </div> +</div> + +<div id="controls"> + <input type="text" id="url" value="img/1376516658960-dumpfm-DoritoWitch-TimeFLyTrans0001.png"> + <br> + <br> + + <textarea id="shader"></textarea> + <br> + <br> + +</div> + +<div id="workspace"></div> + +</body> +<script type="text/javascript" src="js/vendor/jquery/jquery.min.js"></script> +<script type="text/javascript" src="js/vendor/canvasquery.js"></script> +<script type="text/javascript" src="js/vendor/gif.js"></script> +<script type="text/javascript" src="js/util.js"></script> +<script type="text/javascript" src="js/color.js"></script> +<script type="text/javascript" src="js/image.js"></script> +<script type="text/javascript" src="js/gallery.js"></script> +<script type="text/javascript" src="js/render.js"></script> +<script type="text/javascript" src="js/shader.js"></script> +<script type="text/javascript" src="js/api/get.js"></script> +<script type="text/javascript" src="js/api/set.js"></script> +<script type="text/html" id="shader-gallery-template"> +<img src="{thumbnail_url}"> +{username} +</script> +<script type="text/javascript"> + +var cc = cq(0,0).appendTo("#workspace") +var w, h + +$(init) + +function init(){ + $("#url").change(load) +// run('#first') + +// $("#shader-id") +// $("#fetch-info") + $("#fetch-all").click(function(){ + ShaderAPI.all(load_shaders) + }) + $("#fetch-latest").click(function(){ + ShaderAPI.latest(load_shaders) + }).trigger("click") +// $("#fetch-next-page") +// $("#fetch-history") + + function load_shaders(err, shaders){ + var $el = $("#shader-gallery").empty() + var template = $("#shader-gallery-template").html() + + for (var i in shaders) { + var $shader = $("<div>").addClass("shader") + $shader.data("shader", shaders[i]) + var html = template + for (var field in shaders[i]) { + html = html.replace("{" + field + "}", shaders[i][field]) + } + $shader.html(html) + + $el.append( $shader ) + } + } + + ShaderAPI.list_users(function(err, users){ + var $el = $("#pick-user").empty() + for (var i in users) { + var $option = $("<option>") + var username = users[i].username + $option.val(username).html(username) + $el.append( $option ) + } + }) + + $(document).on("change", "#pick-user", function(){ + var name = $(this).val() + ShaderAPI.username(name, load_shaders) + }) + $(document).on("click", ".shader", function(){ + run( $(this).data("shader") ) + }) + + load() + + document.getElementById('shader').addEventListener('input', shader_build); + shader_build() + + requestAnimationFrame(animate) +} +function run(shader_object){ + console.log(shader_object) + $("#url").val( shader_object.image_url ) + $("#shader").html(shader_object.script) + $("#shader-id").val(shader_object.id) + load() + shader_build() +} + +</script> +</html> diff --git a/shader-picker.html b/shader-picker.html index 59b3e27..d482a6b 100644 --- a/shader-picker.html +++ b/shader-picker.html @@ -119,8 +119,10 @@ a { color: #00f; } <script type="text/javascript" src="js/image.js"></script> <script type="text/javascript" src="js/gallery.js"></script> <script type="text/javascript" src="js/color.js"></script> +<script type="text/javascript" src="js/frames.js"></script> <script type="text/javascript" src="js/image.js"></script> <script type="text/javascript" src="js/user.js"></script> +<script type="text/javascript" src="js/render.js"></script> <script type="text/javascript" src="js/shader.js"></script> <script type="text/javascript" src="js/util.js"></script> <script type="text/javascript" src="shaders.json"></script> @@ -139,15 +141,16 @@ function init(){ $("#reset").click(reset) $("#pause").click(pause) $("#step-forward").click(step_forward) + $(document).on("mousemove", function(e) { + mousex = e.pageX + mousey = e.pageY + }) + $("#add-frame").click(add_frame) $("#frames").sortable({ start: drag_start, stop: drag_stop }); - $(document).on("mousemove", function(e) { - mousex = e.pageX - mousey = e.pageY - }) $(document).on("click","#frames .remove",remove_frame) $("#framecount").change(function(){ var val = $(this).int() @@ -158,6 +161,7 @@ function init(){ $("#background").change(function(){ document.body.style.backgroundColor = $("#background").string() }) + $("#frames").disableSelection(); $("#remove-all-frames").click(remove_all_frames) $("#weave-frames").click(weave_frames) @@ -188,329 +192,19 @@ function init(){ user.shaders.init() user.shaders.loadLastAccessed() - - $("#test-js").click(function(){ - var script = $("#shader").val() - var params = {script: script, verbose: 1} - $.post("/cgi-bin/js/test_javascript.py", params, function(data){ - $("pre").remove() - $("#rendered").show() - var $pre = $("<pre>") - $pre.html(data) - $("#rendered").append($pre) - console.log(data) - }) - }) - + document.getElementById('shader').addEventListener('input', shader_build); shader_build() requestAnimationFrame(animate) } -function choose (){ - imageURL = this.src - loading = true - $("#url").val(imageURL) - loadImage(imageURL, ready) -} -function load(){ - loading = true - var imageURL = $("#url").val() - loadImage(imageURL, ready) -} - function drag_start(){ dragging = true; $(this).addClass("dragging") } function drag_stop(){ dragging = false; $(".dragging").removeClass("dragging") } -function reset(){ - start_t = old_t - pause_t = 0 - pause(false) - $("#rendered img").remove() - draw(0) -} -function pause(state){ - $("#pause").toggleClass("paused", paused = typeof state == "boolean" ? state : ! paused).html(paused ? "paused" : "pause") -} -function step_forward(){ - var step = $("#framedelay").float() * 1000 || 100 - old_t += step - draw(old_t) - pause(true) -} -var timeout, raf_id, start_t = 0, old_t = 0, pause_t = 0 -var paused = false, dragging = false, rendering = false, scrolling = false, deferring = false, scrollTimeout = null; -var fps = 30; -function animate(t){ - raf_id = requestAnimationFrame(animate); - - var step_t = t - old_t - old_t = t - - if (paused || dragging || rendering || scrolling || deferring) { - pause_t += step_t - if (scrolling) { - scrolling = false - deferring = true - } - else { - deferring = false - } - return - } - - // var timing = +(new Date()) - draw(t) - // timing = +(new Date()) - timing - fps = avg(fps, 1000/step_t, 4) - status(~~(fps) + " fps") -} -function draw(t) { - t -= start_t - t -= pause_t - frame = giveFrame(t) - shade(frame, t) -} - -var frame, img_frame; -function giveFrame(t){ - if (window.gif) { - if (gif.currentFrame) { - return gif.frames[gif.currentFrame(t)] - } - else { - return gif.frames[0] - } - } - else if (window.img) { - return img_frame - } - else { - return cq(w, h) - } -} - -function ready(){ - loading = false - if (window.gif) { - frame = gif.frames[0] - w = cc.canvas.width = frame.ctx.canvas.width - h = cc.canvas.height = frame.ctx.canvas.height - for (var i=0, f; f=gif.frames[i]; i++){ - f.cloneData = f.ctx.getImageData(0,0,w,h) - } - } - else { - fc = cq(img.width, img.height) - fc.drawImage(img, 0, 0) - frame = img_frame = { ctx: fc.context } - w = cc.canvas.width = frame.ctx.canvas.width - h = cc.canvas.height = frame.ctx.canvas.height - frame.cloneData = frame.ctx.getImageData(0,0,w,h) - } -} - -function add_frame(){ - var frame_count = $("#framecount").int() - if (frame_count < 2) { - add_single_frame() - } - else { - add_frames(frame_count) - } -} -function add_single_frame(){ - var $el = $("<div>") - $el.html( $("#frame-template").html() ) - $el.attr('index', $("#frames div").length) - var frame = cc.clone().appendTo($el.find(".frame")[0]) - frame.canvas.className = "fullsize" - frame.canvas.style.display = "none" - var thumb = cc.clone().resize(100,100).appendTo($el.find(".frame")[0]) - $("#frames").append($el) - $("#render").enable() -} -function add_frames(frame_count){ - rendering = true - var t = old_t - start_t - pause_t - var frame_delay = $("#frameinterval").float() * 1000 - var frame - for (var i = 0; i < frame_count; i++) { - frame = giveFrame(t) - t += frame_delay - shade(frame, t) - add_single_frame() - } - rendering = false -} -function remove_frame(){ - $(this).closest("div").remove() - if ($("#frames div").length == 0) { - $("#render").disable() - } -} -function remove_all_frames(){ - $("#frames").empty() -} -function shuffle_frames(){ - var shuffled = [] - var $frames = $("#frames div") - $("#frames").empty().append(shuffle($frames)) -} -function reverse_frames(){ - var $frames = $("#frames div") - $("#frames").empty().append(reverse($frames)) -} -function weave_frames(){ - var $frames = $("#frames div") - $("#frames").empty().append(weave($frames)) -} -function sort_frames(){ - var $frames = $("#frames div") - var sorted = $frames.map(function(i,el){ console.log(i,el); return [[ el.getAttribute('index'), el ]] }) - .sort(function(a,b){ return a[0]-b[0] }) - .map(function(i,e){ console.log( e ); return e[1] }) - $("#frames").empty().append(sorted) -} - -function render (){ - if (rendering) return - rendering = true - encoder.reset() - var delay = $("#framedelay").float() * 1000 || 100 - $("#frames canvas.fullsize").each(function(){ - var frame = cq(this.width, this.height).fillStyle($("#background").string()).fillRect(0,0,this.width, this.height).drawImage(this,0,0) - encoder.addFrame(frame.canvas, delay) - }) - $("#pause,#render,#add-frame").disable() - $("#rendered").find("img").remove() - $("#rendered").show() - // really bad results with neuquant? - // status("quantizing") - // encoder.quantize() - status("encoding") - try { - encoder.encode() - } catch (e) { - $("#pause,#render,#add-frame").enable() - rendering = false - status(e) - throw e - } - $("#render").html("rendering") -} - -function status(s){ $(".status").html(s) } - -var encoder = new GifEncoder() - -encoder.on("quantized", function(url){ - status("encoding") - encoder.encode() -}) - -encoder.on("encoded-frame", function(done,count){ - status("encoded " + done + " / " + count) -}) - -encoder.on("rendered", function(bytes){ - status(filesize(bytes.length)) -}) - -encoder.on("rendered-url", function(url){ - var image = new Image () - lastGif = image.src = url - $("#rendered").append(image) - $("#uploaded-url").hide().val("") - $("#save,#upload,#rendered").show() - $("#pause,#render,#add-frame,#save,#upload").enable() - $("#render").html("render") - rendering = false - pause(true) -}) - -function get_filename(){ - var basename = $("#url").val().replace(/^.*\//,"").replace(/\..*$/,"").replace(/[^-_ a-zA-Z0-9]/g,"") - var username = user.username - var filename = basename + "-" + username + "-" + (+new Date()) + ".gif" - return filename.replace(/ /g,"_").replace(/-+/g,"-") -} -function save (){ - if (! lastGif) return; - var filename = get_filename() - var blob = dataUriToBlob(lastGif) - saveAs(blob, filename); -} -function saveJSON (data, filename) { - var bytes = JSON.stringify(data) - var buf = new ArrayBuffer(bytes.length); - var arr = new Uint8Array(buf); - for (var i = 0; i < bytes.length; i++) { - arr[i] = bytes.charCodeAt(i); - } - - var blob = new Blob([arr], { type: "text/json" }); - blob.slice = blob.slice || blob.webkitSlice; - - saveAs(blob, filename); -} - -function upload(){ - var filename = get_filename() - var username = user.username - var blob = dataUriToBlob(lastGif) - uploadImage({ - blob: blob, - filename: filename, - username: username, - success: function(data){ - - // data.url - // data.filesize - // data.success - - console.log(data); - status("uploaded"); - $("#uploaded-url").show().focus().val(data.url) - }, - error: function(data){ - console.log(data) - status("error uploading: " + data.error) - } - }); -} - </script> <script type="text/html" id="frame-template"> <button class="remove">x</button> <span class="frame"></span> </script> -<script type="text/javascript-shader" id="first"> - -u = x + t/10 -v = y * sin(b/100) - -rgbpixel(d,u,v) - -</script> -<script type="text/javascript-shader" id="second"> -xx = x, yy = y - -var d = ((x % 2) + 2 * (y % 2)) - 2 - -x += w/2 -y -= h/2 -t/=-200 -y/=96 -x/=50 -v = (Math.sin(t+x*y) + 1.0) / 2 -v = (0.6) * v - 0.4 + Math.random() - -v = clamp( v*64 + 128 , 0, 255) -v += d*32 -if (a == 0) r = g = b = xx/w * 255 -a = v > 128 ? v:0 - -</script> </html> |
