-
-
Save davo/ba7061b58d8df615287f64b3ae786066 to your computer and use it in GitHub Desktop.
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
global.THREE = require("three"); | |
const canvasSketch = require('canvas-sketch'); | |
const Random = require('canvas-sketch-util/random'); | |
const gradientHeight = 512; | |
const settings = { | |
dimensions: [ 2048, gradientHeight * 2 ] | |
}; | |
const sketch = (props) => { | |
return ({ context, width, height }) => { | |
context.fillStyle = 'white'; | |
context.fillRect(0, 0, width, height); | |
// your stepped color data, to be filled in | |
const colorsAsHexList = [ /* '#ff0000' */ ]; | |
const colorsAsLabList = [ /* [ 100, 0, 0 ] */ ]; | |
const grd = context.createLinearGradient(0, 0, width, 0); | |
colorsAsHexList.forEach((hex, i, list) => { | |
const t = i / (list.length - 1); | |
grd.addColorStop(t, hex); | |
}); | |
context.fillStyle = grd; | |
context.fillRect(0, 0, width, gradientHeight); | |
img = context.createImageData(width, gradientHeight); | |
// draw curve | |
const labPositions = colorsAsLabList.map(lab => { | |
return new THREE.Vector3().fromArray(lab); | |
}); | |
const curve = new THREE.CatmullRomCurve3(labPositions); | |
curve.curveType = 'catmullrom'; | |
// can play with tension to make sharper or softer gradients | |
curve.tension = 0.5; | |
// uncomment to make a seamless gradient that wraps around | |
// curve.closed = true; | |
const samples = getCurveDivisions(curve, img.width, false) | |
.map(p => p.toArray()) | |
for (let y = 0; y < img.height; y++) { | |
for (let x = 0; x < img.width; x++) { | |
const i = x + y * img.width; | |
let Lab = labJitter(samples[x], 0.5); | |
// lab2rgb not implemented here | |
const [ R, G, B ] = YourColorConverter.lab2rgb(Lab); | |
img.data[i * 4 + 0] = R; | |
img.data[i * 4 + 1] = G; | |
img.data[i * 4 + 2] = B; | |
img.data[i * 4 + 3] = 255; | |
} | |
} | |
context.putImageData(img, 0, gradientHeight); | |
}; | |
// Entirely optional, but as we are doing this per-pixel we may as well | |
// add subtle noise to reduce banding. | |
function labJitter (lab, s = 1) { | |
// fudged jittering in L*a*b* space | |
const lw = 100 / 200; | |
const K = 2.624; | |
const [ x, y, z ] = Random.insideSphere(Random.gaussian(0, s * K)) | |
const [ L, a, b ] = lab; | |
return [ L + x * lw, a + y, b + z ]; | |
} | |
function getCurveDivisions (curve, n, spaced = false) { | |
const points = []; | |
for (let i = 0; i < n; i++) { | |
const t = curve.closed ? (i / n) : (i / (n - 1)); | |
let p = spaced ? curve.getPointAt(t) : curve.getPoint(t); | |
points.push(p); | |
} | |
return points; | |
} | |
}; | |
canvasSketch(sketch, settings); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment