-
Notifications
You must be signed in to change notification settings - Fork 0
/
sketch-05.js
135 lines (108 loc) · 3.19 KB
/
sketch-05.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const canvasSketch = require('canvas-sketch');
const { random } = require('canvas-sketch-util');
const tweakpane = require('tweakpane');
const settings = {
dimensions: [1048, 1048],
animate: true,
};
let manager;
let fontFamily = 'serif';
let params = {
cell: 100,
speed: 2,
frequency: 0.005,
amplitude: 0.5,
};
// const url = 'https://picsum.photos/id/152/3888/2592';
const url = 'assets/bw-face-woman.jpeg';
const loadImage = (url) => {
return new Promise((res, rej) => {
const image = new Image();
image.onload = () => res(image);
image.onerror = () => rej(image);
image.crossOrigin = 'anonymous';
image.src = url;
settings.dimensions = [image.width, image.height];
});
};
let img = '';
const sketch = ({ context, width, height }) => {
return ({ context, width, height, frame }) => {
const cols = Math.floor(width / params.cell);
const rows = Math.floor(height / params.cell);
const numCells = cols * rows;
context.drawImage(img, 0, 0, width / params.cell, height / params.cell);
const typeData = context.getImageData(0, 0, cols, rows).data;
context.fillStyle = 'black';
context.fillRect(0, 0, width, height);
for (i = 0; i < numCells; i++) {
const col = i % cols;
const row = Math.floor(i / cols);
const x = col * params.cell;
const y = row * params.cell;
// Get the rgba values out of the typeData array.
const r = typeData[i * 4 + 0];
const g = typeData[i * 4 + 1];
const b = typeData[i * 4 + 2];
const a = typeData[i * 4 + 3];
const n =
b > 50
? random.noise3D(
x + frame,
y + frame,
params.speed,
params.frequency,
params.amplitude
) * 1.2
: 0;
const angle = n * Math.PI * 0.2;
// Create glyphs based on the red value of every pixel
// const glyph = getGlyph(b);
const glyph = '+';
context.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
context.save();
context.translate(x, y);
context.translate(params.cell * 0.5 + n, params.cell * 0.5 + n);
context.rotate(angle);
context.font = `${params.cell * 2}px ${fontFamily}`;
// if (Math.random() < 0.001) {
// context.font = `${params.cell * 10}px ${fontFamily} `;
// }
// if (Math.random() < 0.005) {
// context.font = `${params.cell * 4}px ${fontFamily}`;
// }
context.fillText(glyph, 0, 0);
context.restore();
}
};
};
const getGlyph = (v) => {
if (v < 50) return `=`;
if (v < 100) return `*`;
if (v < 150) return `"`;
if (v < 200) return `+`;
const glyphs = '= /!()><'.split('');
// return random.pick(glyphs);
return '/';
};
const onKeyUp = (e) => {
e.key == 'r' && manager.render();
e.key == 'p' && manager.togglePlay();
};
document.addEventListener('keyup', onKeyUp);
const createPane = () => {
const pane = new tweakpane.Pane();
let folder;
folder = pane.addFolder({ title: 'Noise' });
folder.addInput(params, 'cell', { min: 1, max: 40, step: 1 });
folder.addInput(params, 'speed', { min: 1, max: 20, step: 1 });
folder.addInput(params, 'frequency', { min: -0.01, max: 0.01 });
folder.addInput(params, 'amplitude', { min: 0, max: 1 });
};
// createPane();
loadImage(url)
.then((res) => {
img = res;
return canvasSketch(sketch, settings);
})
.then((res) => (manager = res));