Made for #MakeSomethingDay 2014, beloved by two-year-olds.
Smudge: a multi-touch drawing experiment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="initial-scale=1,maximum-scale=1"/> | |
<script src="http://d3js.org/d3.v3.js"></script> | |
<body bgcolor="black"> | |
<script> | |
var base = d3.select("body"), | |
chart = base.append("canvas"), | |
context = chart.node().getContext("2d"), | |
color = d3.scale.category10(), | |
penradius, | |
lastimage; | |
var sketch = d3.select("body").append("custom:sketch"); | |
// "responsive" design: fill window regardless of size | |
resize_chart(); | |
d3.select(window).on('resize', resize_chart); | |
// hook up all other event triggers | |
d3.select("body") | |
.on("touchstart", touchstart) | |
.on("touchmove", touch) | |
.on("touchend", touch) | |
.on("keydown", function() { | |
console.log(d3.event.keyCode); | |
if (d3.event.ctrlKey && (d3.event.keyCode == 90)) { // ctrl-z => undo | |
revertToLastImage(); | |
} else if (d3.event.ctrlKey && (d3.event.keyCode == 83)) { // ctrl-s => save | |
saveImage(); | |
} else if (d3.event.keyCode == 78) { // n => new canvas | |
clearImage(); | |
} | |
}); | |
function touchstart() { | |
scramblePens(); | |
saveCurrentImage(); | |
touch(); | |
} | |
function scramblePens() { | |
// scramble order of colors for multitouch | |
color = d3.scale.category10(); | |
for (var i = 0; i < 20; i++) { | |
color(Math.floor(10*Math.random())); | |
} | |
} | |
function touch() { | |
d3.event.preventDefault(); | |
var data = d3.touches(chart.node()); | |
penradius = 15; | |
context.globalAlpha=.35; | |
data.forEach(function(d,i) { | |
context.beginPath(); | |
context.fillStyle=color(i); | |
context.arc(d[0], d[1], penradius, 0, 2*Math.PI); | |
context.fill(); | |
context.closePath(); | |
}); | |
} | |
function resize_chart() { | |
var imagedata = context.getImageData(0, 0, | |
parseInt(chart.style("width")), | |
parseInt(chart.style("height"))); | |
chart | |
.attr("width", window.innerWidth-20) | |
.attr("height", window.innerHeight-20); | |
context.putImageData(imagedata, 0, 0); | |
} | |
function saveCurrentImage() { | |
lastimage = context.getImageData(0, 0, | |
parseInt(chart.style("width")), | |
parseInt(chart.style("height"))); | |
} | |
function revertToLastImage() { | |
var image = lastimage; | |
saveCurrentImage(); | |
context.putImageData(image, 0, 0); | |
} | |
function saveImage() { | |
var image = chart.node().toDataURL("image/png"); | |
window.open(image); | |
} | |
function clearImage() { | |
saveCurrentImage(); | |
context.clearRect(0, 0, | |
parseInt(chart.style("width")), | |
parseInt(chart.style("height"))); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment