diff options
| author | Jules Laplace <jules@okfoc.us> | 2014-11-22 23:19:36 -0500 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2014-11-22 23:19:36 -0500 |
| commit | 070b5e6d9d3c7e23c06f0ae0b75026923529c24d (patch) | |
| tree | 89c430dd17ca54ff60f885ecd99cf6cfa0f0b7ff /index.html | |
| parent | 04537ed34d443d0610b77420d1dbef64bc05fbfa (diff) | |
| parent | 1631cdf643283fc71bc9d70b5dcbce03ab9c2386 (diff) | |
Merge branch 'master' of lmno:dither
Diffstat (limited to 'index.html')
| -rw-r--r-- | index.html | 291 |
1 files changed, 246 insertions, 45 deletions
@@ -2,60 +2,261 @@ <html> <head> <title>Dither</title> +<style type="text/css"> +* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } +html,body{width:100%;height:100%;margin:0;padding:0;} +#colors { float: left; width: 16px; height: 100%; background: #eee; padding: 16px 0; margin: 0 10px 0 15px; } +#body { float: left; padding: 20px 10px; background-color:rgba(255,255,255,0.95);height:100%;} +#palette,#colors div { cursor: pointer; } +#dice { font-size: 4em; line-height: 0.8em; position: relative; top: -30px; left: 10px; cursor: pointer; box-shadow: 0 0 4px #b8d6fb,0 0 4px #b8d6fb,0 0 4px #b8d6fb;} +#dice {outline:0; } +h1 { font-size: 26px; font-weight: normal } +</style> </head> <body> -<div> -<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 id="colors"> </div> -<div id="images"></div> -</body> + +<div id="body"> +<img src="img/palette.gif" id="palette"> +<button id="dice">⚛</button> +<button id="upload">→</button> +<input type="text" id="uploaded-url"> +<span id="status"></span> + +<h1>dither</h1> +<a target="_blank" href="dither-picker.html"><button>dither-picker</button></a> +... +<a target="_blank" href="threshold.html"><button>threshold</button></a> +<a target="_blank" href="pattern.html"><button>pattern</button></a> +<a target="_blank" href="halftone.html"><button>halftone</button></a> + +<h1>shader</h1> +<a target="_blank" href="/shader/"><button>shader-combo</button></a> +... +<a target="_blank" href="shader-demo.html"><button>shader-demo</button></a> +<a target="_blank" href="shader-animate.html"><button>shader-animate</button></a> +<a target="_blank" href="shader-gif.html"><button>shader-gif</button></a> +<a target="_blank" href="shader-picker.html"><button>shader-picker</button></a> +<!--<a target="_blank" href="shader-localstorage.html"><button>shader-localstorage</button></a>--> +<a target="_blank" href="shader-api.html"><button>shader-api</button></a> + +<h1>photoblaster</h1> +<a target="_blank" href="/im/"><button>photoblaster</button></a> +<a target="_blank" href="/imgradient/"><button>im-gradient</button></a> +<a target="_blank" href="/imgrid/"><button>im-grid</button></a> +<a target="_blank" href="/imbreak/"><button>im-break</button></a> + +<h1>etc..</h1> +<a target="_blank" href="/gif-recorder/"><button>gif-recorder</button></a> +<a target="_blank" href="/neighbor/"><button>neighbor</button></a> +... +<a target="_blank" href="/dendrite/"><button>dendrite</button></a> +<a target="_blank" href="/dendrite/dendrite-life.html"><button>dendrite-life</button></a> +<a target="_blank" href="/mandel/mandel5.html"><button>mandel5</button></a> +<a target="_blank" href="http://glitchyplop.com/"><button>sortpixels</button></a> +<a target="_blank" href="/strobe/"><button>strobe</button></a> +</div> + <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/vendor/jquery/jquery.min.js"></script> +<script type="text/javascript" src="js/vendor/dataUriToBlob.js"></script> +<script type="text/javascript" src="js/vendor/FileSaver/FileSaver.js"></script> +<script type="text/javascript" src="js/user.js"></script> +<script type="text/javascript" src="js/image.js"></script> +<script type="text/javascript" src="js/save.js"></script> <script type="text/javascript"> -var algo = 'random'; -var urls = ["img/abyss.png","img/building.png","img/gradient.jpg"] -var imgs = [] -var complete = 0 -urls.forEach(function(src){ - var img = new Image () - img.onload = ready - img.src = src - imgs.push(img) - if (img.complete) ready() -}) -function ready(){ - complete += 1 - if (complete < imgs.length) return; - 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) + +// +// color + +function Color (opt) { + if (opt.length == 3) { + this.r = opt[0]; + this.g = opt[1]; + this.b = opt[2]; + this.a = 1; + } + else if (opt.length == 4) { + this.r = opt[0]; + this.g = opt[1]; + this.b = opt[2]; + this.a = opt[3]; } - build() } -function build(){ - document.getElementById("images").innerHTML = "" - imgs.forEach(dither) +Color.prototype.toString = function(){ + return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")"; +} +Color.prototype.rgb = function(){ + return [ this.r, this.g, this.b ]; +} +Color.prototype.rgba = function(){ + return [ this.r, this.g, this.b, this.a ]; +} +Color.prototype.hsl = function(){ +} +Color.prototype.copy = function(){ + return new Color( this.rgba() ); +} +Color.prototype.alpha = function(a){ + var c = this.copy() + c.a = a; + return c; +} +Color.prototype.swatch = function(){ + var el = document.createElement("div"); + el.style.className = "swatch"; + el.style.width = 16 + "px"; + el.style.height = 16 + "px"; + el.style.backgroundColor = this.toString(); + $(el).data("color", this); + return el; +} + +var colors = { + red: new Color([ 255,0,0 ]), + blue: new Color([ 0,0,255 ]), + black: new Color([ 0,0,0 ]), + green: new Color([ 0,128,0 ]), + cyan: new Color([ 0,255,255 ]), + yellow: new Color([ 255,255,0 ]), + peru: new Color([ 205,133,63 ]), +} + + +// +// point + +function Point(e, offset) { + if (e && offset) { + this.x = e.pageX - offset.left; + this.y = e.pageY - offset.top; + } } -function dither(img){ - var w = img.naturalWidth, h = img.naturalHeight; - var cc = cq(w, h) - cc.drawImage(img, 0, 0, w, h); - cc[algo + "Dither"]( ) - cc.appendTo("#images") +Point.prototype.add = function(p) { + this.x += p.x; + this.y += p.y; } +Point.prototype.subtract = function(p) { + this.x -= p.x; + this.y -= p.y; +} +Point.prototype.quantize = function(x, y) { + this.x = Math.floor( this.x / x ) * x; + this.y = Math.floor( this.y / y ) * y; +} + + +// +// util.js + +function trim (s) { + return s.replace(/^\s+/, "").replace(/\s+$/, ""); +} +function strip (s) { + return trim(s).replace(/\W+/, ""); +} +function sanitize (s) { + return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\"/g, """); +} +function scrollToBottom (el) { + try { $(el).scrollTop( $(el)[0].scrollHeight ) } + catch (err) { } +} +var Trig = { + distanceBetween2Points: function ( point1, point2 ) { + var dx = point2.x - point1.x; + var dy = point2.y - point1.y; + return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) ); + }, + angleBetween2Points: function ( point1, point2 ) { + var dx = point2.x - point1.x; + var dy = point2.y - point1.y; + return Math.atan2( dx, dy ); + }, + magnitude: function (point) { + return Math.sqrt( Math.pow( point.x, 2 ) + Math.pow( point.y, 2 ) ); + } +} + +function fib (f) { for (var i = 1, n = 1; n < 200; i++, n += i) f(n) } +function random() { return Math.random() } +function rand(x) { return Math.random() * x } +function randint(x) { return Math.floor(Math.random() * x) } +function clamp(x,a,b) { return Math.min(Math.max(x,a),b) } +function choice(a){ return a[ randint(a.length) ] } + + +// +// main + +var palette = document.querySelector("#palette") +palette.addEventListener("load", load) +if (palette.complete) load() + +function load(){ + console.log("hello"); + user.init() + var offset = $("#palette").offset(); + var paletteImg = $("#palette")[0]; + var palette = cq(paletteImg); + var pattern, mask; + var patternURI; + var color = new Color( 0, 0, 0 ); + + // $("body").append(palette.canvas); + + $("#palette").click(function(e){ + // they are all 8x8 + // the first one starts at (15, 5), next one is 16 pixels down or to the right + // there are 16 rows and 6 columns, so 92 patterns total + var point = new Point(e, offset); + pick(point); + }) + function pick(point){ + point.subtract({ x: 15, y: 5 }); + point.quantize( 18, 16 ); + point.add({ x: 15, y: 5 }); + + pattern = palette.clone().crop( point.x, point.y, 8, 8 ); + mask = pattern.colorToMask("#fff"); + pattern.applyMask(mask); + patternURI = pattern.clone().blend( color.toString(), "screen", 1.0 ).canvas.toDataURL("image/png"); + document.body.style.backgroundImage = 'url(' + patternURI + ')'; + } + + swatches = [] + for (var i in colors) { + var swatch = colors[i].swatch(); + swatches[i] = swatch + $("#colors").append(swatch); + swatch.onclick = function(){ + color = $(this).data("color"); + p = cq(paletteImg); + patternURI = pattern.clone().blend( color.toString(), "screen", 1.0 ).resizePixel(1 << randint(6)).canvas.toDataURL("image/png"); + document.body.style.backgroundImage = 'url(' + patternURI + ')'; + } + } + + function dice() { + var p = new Point() + p.x = randint(palette.canvas.width-20)+20 + p.y = randint(palette.canvas.height) + pick(p) + swatches[choice(["red","yellow"])].onclick() + } + $("#dice").click(dice) + dice() + $("#upload").click(function(){ + if (patternURI) { + upload(patternURI, (+ new Date()) + "-" + user.username + "-dither.png", "dither") + } + }) +} +$("#dice").focus() +$(window).focus(function(){ $("#dice").focus() }) </script> +</body> </html> |
