summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjules <jules@okfoc.us>2013-12-13 17:39:40 -0500
committerjules <jules@okfoc.us>2013-12-13 17:39:40 -0500
commit072f9186f57bb4dcb9c75457efa0f67b7a0225d3 (patch)
treee781730c3be2c5bb2b10c1212373470a70ad76c6
parente6a10925902812fe78732af31f289d7176b2c1a3 (diff)
animated shader
-rw-r--r--gif-dither.html20
-rw-r--r--js/util.js12
-rw-r--r--shader-animate.html133
3 files changed, 144 insertions, 21 deletions
diff --git a/gif-dither.html b/gif-dither.html
index 84217fc..5a9cb09 100644
--- a/gif-dither.html
+++ b/gif-dither.html
@@ -31,6 +31,8 @@
<script type="text/javascript" src="js/util.js"></script>
<script type="text/javascript">
+var algo = "random"
+
document.getElementById("url").onchange = load
setTimeout(init)
@@ -40,6 +42,8 @@ function init () {
}
function load(){
document.getElementById("save").style.display = "none"
+ document.getElementById("encode").style.display = "none"
+ status("loading")
var imageURL = document.getElementById("url").value
loadImage(imageURL, ready)
}
@@ -50,21 +54,10 @@ function status (s){
el.innerHTML = s + "..."
}
function bind(){
- var buttons = document.getElementsByTagName("button")
- for (var i = 0; i < buttons.length; i++) {
- (function(n){
- buttons[n].onclick = function(){
- algo = buttons[n].id;
- build()
- }
- })(i)
- }
document.getElementById("save").onclick = save
document.getElementById("encode").onclick = encode
}
-
-
var encoder = new GifEncoder()
encoder.on("quantized", function(url){
@@ -97,9 +90,6 @@ function ready(){
build()
}
-var algo = "random"
-var frames = []
-
function build(){
status("dithering")
encoder.resetFrames()
@@ -112,7 +102,7 @@ function build(){
if (buttons[i].id != "save" && buttons[i].id != "encode") bz.push(buttons[i].id)
}
gif.frames.forEach(function(frame, i){
- var algo = bz[i % bz.length]
+ algo = bz[i % bz.length]
var cc = dither(frame)
encoder.addFrame(cc.canvas)
})
diff --git a/js/util.js b/js/util.js
index fc27166..d31af47 100644
--- a/js/util.js
+++ b/js/util.js
@@ -1,11 +1,11 @@
-$.fn.int = function(){ return parseInt($(this).val(),10) }
-$.fn.float = function(){ return parseFloat($(this).val()) }
+if (window.$) {
+ $.fn.int = function(){ return parseInt($(this).val(),10) }
+ $.fn.float = function(){ return parseFloat($(this).val()) }
+}
+
function clamp(n,a,b){ return n<a?a:n<b?n:b }
function loadImage(imageURL, callback) {
- document.getElementById("save").style.display = "none"
- document.getElementById("encode").style.display = "none"
- status("loading")
var imageURL = proxify( imageURL );
window.gif = window.img = null
@@ -26,7 +26,7 @@ function loadImage(imageURL, callback) {
}
function giveImage() {
- if (imageURL.substr(-3) === "gif") {
+ if (window.gif) {
return gif.frames[gif.currentFrame()].ctx.canvas;
} else {
return img;
diff --git a/shader-animate.html b/shader-animate.html
new file mode 100644
index 0000000..afacad0
--- /dev/null
+++ b/shader-animate.html
@@ -0,0 +1,133 @@
+<!doctype html>
+<html>
+<head>
+<title>Shader</title>
+<style type="text/css">
+#url { width: 100px; }
+#width,#height,#frames,#delay {width: 30px; }
+#shader { width: 400px; height: 247px; font-family: fixed; }
+div { float: left; padding: 10px;}
+</style>
+</head>
+<body>
+<div id="controls">
+<input type="text" id="url" value="img/1376516658960-dumpfm-DoritoWitch-TimeFLyTrans0001.png">
+frames <input type="text" id="frames" value="7">
+delay <input type="text" id="delay" value="60">
+<button id="render" disabled>render</button>
+<button id="demo">demo</button>
+<button id="dither-demo">dither</button>
+<br>
+<br>
+<textarea id="shader">
+</textarea>
+</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/canvasquery.dither.js"></script>
+<script type="text/javascript" src="js/util.js"></script>
+<script type="text/javascript">
+
+var cc = cq(0,0).appendTo("#workspace")
+var w, h
+
+$(init)
+
+function init(){
+ $("#url").change(load)
+ $("#demo").click(function(){ demo("#first") })
+ $("#dither-demo").click(function(){ demo("#second") })
+ demo('#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
+}
+
+var timeout = null;
+function draw(t){
+ requestAnimationFrame(draw);
+ shade(frame, t)
+}
+function shade(frame, t){
+ try {
+ 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)
+ }
+}
+
+</script>
+<script type="text/javascript-shader" id="first">
+t /= 500
+if (a == 0) { r = g = b = x; t /= -3 }
+r *= (Math.sin(t*x/y) + 1)/2
+g *= (Math.cos(t*y/x) + 0.4)/2
+b *= (Math.sin(t) + 1.5)/2
+a = y
+
+</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>
+