Skip to content

Instantly share code, notes, and snippets.

Last active August 29, 2015 14:07
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
in response to SFPC assignment & greatartbot on Twitter


This project is in response to Ramsey's SFPC homework to choose an image from the Twitter Great Art Bot and write code to create it. The project was meant to be rather thearetical, to try and describe how to create it. But, I thought it would be fun to try and implement. I chose this image because I liked that it looked a bit like rain.

To do

I need a better algorithm for walking through the space than a random walk, as I don't want it to trend to either extreme.

Might also be fun to set it up to refresh on it's own every 10 seconds, or freeze. But, maybe not.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Great Art Bot Pixelator</title>
<link href='' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="meyerReset.css">
<link rel="stylesheet" href="pixelBotBW.css">
<script src="" charset="utf-8"></script>
<!--[if lt IE 9]>
<script src=""></script>
<h3>For a new image, <span id="refreshButton">click here</span> and wait a few seconds.</h3>
<section id="box" class="main">
<!-- <img src="image.png"/> -->
<p>As part of the School for Poetic Computation, we were challenged to select a pattern from the <a href="">"Great Art" Twitter bot</a> and describe how to create it in code. This D3 example creates images with a style similar to the original <a href="image.png">image</a> that I chose. Each time you refresh the screen, or click update, you'll see a different variation of the image.</p>
<!-- call JS files -->
<script src="pixelBotBW.js"></script>
/* Meyer Reset
v2.0 | 20110126
License: none (public domain)
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
body {
line-height: 1;
ol, ul {
list-style: none;
blockquote, q {
quotes: none;
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
table {
border-collapse: collapse;
border-spacing: 0;
body {
background-color: #E5E5E5;
margin-top: 50px;
margin-left: 50px;
font-family: 'Arimo', sans-serif;
.squares {
stroke: none;
stroke-width: 0px;
#refreshButton:hover {
color: #2B5Bb2;
h3 {
font-size: 18px;
width: 450px;
color: #434343;
p {
margin-bottom: 10px;
width: 450px;
font-size: 12px;
color: #434343;
"use strict";
// note: does not work when seconds surpass 2 to 53rd. Need to use big numbers, get library
var sideLength = 3;
var bigBoxDim = 150;
var boxWidth = sideLength * bigBoxDim;
// set variables
var margin = {
top: 20,
right: 0,
bottom: 10,
left: 0
width = boxWidth + margin.left + margin.right,
height = boxWidth + + margin.bottom;
var fullDim = bigBoxDim * bigBoxDim;
function getRandomInt(min, max) {
// +1 due to "floor"
return Math.floor(Math.random() * (max + 1 - min)) + min;
function walkWithin(input, hardMin, hardMax, walkVar) {
var variation = getRandomInt(-walkVar, walkVar);
var k = input + variation;
if (k < hardMin) {
return hardMin + getRandomInt(0, 2);
} else if (k > hardMax) {
return hardMax - getRandomInt(0, 2);
} else {
return k;
var domain = [0, 15, bigBoxDim / 3, 2 * bigBoxDim / 3, bigBoxDim - 15, bigBoxDim]
var vary = 3;
function setUpRandData() {
var df = [];
for (var i = 0; i < bigBoxDim; i++) {
// random walk
domain[1] = walkWithin(domain[1], 10, 40, vary);
domain[2] = walkWithin(domain[2], 50, 80, vary);
domain[3] = walkWithin(domain[3], 90, 115, vary);
domain[4] = walkWithin(domain[4], 125, 143, vary);
var color = d3.scale.linear()
.range(["black", "#252525", "#636363", "#969696", "#d9d9d9", "white"]);
for (var j = 0; j < bigBoxDim; j++) {
x: i,
y: j,
fill: color(j)
return df;
// standard svg intro
var svg =".main").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + + ")");
// attributes for rectangles
var squareAttr = {
"x": function(d) {return d.x * sideLength;},
"y": function(d) {return d.y * sideLength;},
"height": sideLength,
"width": sideLength,
"class": 'squares'
// updates the image based on new colors in data
function update(df) {
.attr("fill", function(d) {
return d.fill;
}'#refreshButton').on("click", function(d) {console.log("clicked!"); update(setUpRandData())})
// update with new data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment