Published
Edited
Aug 10, 2019
1 star
Insert cell
Insert cell
firstName = "Cameron"
Insert cell
lastName = "Yick"
Insert cell
handle = "hydrosquall"
Insert cell
width
Insert cell
height
Insert cell
// Based on the 10print design, introduced through the Daniel Shiffman Coding Train
function badgeCode(g, ctx, frameNumber) {
// Slightly off black
ctx.fillStyle = '#333'
// Experiments with tinting the background with the d3 background
// ctx.fillStyle = chroma.blend('#2c3e50', "#333", 'screen');
ctx.fillRect(0, 0, width, height);
ctx.lineWidth = 14;
ctx.lineCap = "square";
// Using non-matching xStepSize and lineHeight works nicer for designs where I'm not changing opacity.
const cellSize = 50;
const stepSize = cellSize;
const lineHeight = cellSize;
const probability = .20;
const drawLine = (x0, y0, x1, y1) => {
ctx.beginPath();
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.stroke();
}
const drawRow = (yStart) => {
for (let i = 0; i < width; i += 1) {
const xPoints = [i * stepSize, (i + 1) * stepSize];
const yPoints = [yStart, yStart + lineHeight];
// Generate Gradient Noise for this cell
const noiseVal = noise.simplex3(i * stepSize, yStart, frameNumber);
let isFlip = noiseVal < probability;
// Decide whether to introduce drawing variation
const points = isFlip ?
[xPoints[0], yPoints[0], xPoints[1], yPoints[1]] :
[xPoints[0], yPoints[1], xPoints[1], yPoints[0]];

const grayValue = 1 - Math.round(noiseVal * 255);
// const grayValue = 1;

let opacityValue;
if (gradientDirection === 'horizontal') {
opacityValue = 1 - (i * stepSize / width) + .2;
} else if (gradientDirection === 'vertical') {
opacityValue = opacityValue = 1 - (yStart / height) + .15;
} else {
opacityValue = 1;
}
let strokeStyle;
if (!isFlip) {
strokeStyle = chroma(bgColor).alpha(opacityValue - 0.1);
} else {
strokeStyle = chroma(`rgb(${grayValue}, ${grayValue}, ${grayValue})`).alpha(opacityValue);
}
ctx.strokeStyle = strokeStyle;
drawLine(...points);
}
}
// Render each row of the 10print
for (let i = 0; i < height; i += lineHeight) {
drawRow(i)
}
}
Insert cell
isTextLight = true
Insert cell
viewof gradientDirection = radio({
options: ["vertical","horizontal", 'none'].map(option => ({ value: option, label: option})),
value: 'vertical'
})
Insert cell
// #ffc576 - lighter
// #e19f44 - darker
viewof bgColor = color('#e19f44');
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {preview, animation, download, width, height, d3}
with {firstName, lastName, handle, isTextLight, badgeCode}
from "b93171820ba3f268"
Insert cell
Insert cell
md`
## External Resources

- Prior investigations with [10Print](https://cam-sketch.netlify.com/?path=/info/p5js-code-art--10print)
- chroma.js for color adjustments
- NoiseJS for simplex noise
- Jeremy Ashkenas's input knobs
- Badge Builder Template
`
Insert cell
NoiseJS = require('https://bundle.run/noisejs@2.1.0');
Insert cell
// Tried to get OpenSimplexNoise to work, but ran into issues, Revisit if 4d is needed someday.
noise = {
const localNoise = new NoiseJS.Noise()
const seed = 0;
localNoise.seed(seed);
return localNoise;
}
Insert cell
import {color, radio} from "@jashkenas/inputs"
Insert cell
chroma = require('chroma-js')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more