Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
129 lines (111 loc) · 4.06 KB
/
Copy pathscript.js
File metadata and controls
129 lines (111 loc) · 4.06 KB
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
(function () {
'use strict';
window.hopalongUtil = {
identity
};
window.addEventListener('load', init);
function init() {
const SCALE_ID = 'scale';
const canvas = document.getElementById('canvas');
window.hopalong = new Hopalong(canvas);
bindParameterControl('iterations');
bindParameterControl(SCALE_ID);
initScaleLimits(SCALE_ID);
bindControlEvent('new-seed', newSeed);
bindZoom(SCALE_ID);
bindDragging(canvas);
}
function newSeed() {
window.hopalong.parameters.seed = Math.random();
}
function bindControlEvent(controlId, listener) {
const controlEl = document.getElementById(controlId);
if (!controlEl) {
throw new Error(`Control with id '${controlId}' not found`);
}
if (!listener) {
throw new Error('Listener not defined');
}
if (isButton()) {
controlEl.addEventListener('click', listener);
} else {
controlEl.addEventListener('change', listener);
controlEl.addEventListener('input', listener);
}
return controlEl;
function isButton() {
return controlEl.tagName.toLowerCase() === 'button'
|| controlEl.attributes.type && controlEl.attributes.type.name === 'button';
}
}
function bindParameterControl(parameter) {
if (typeof window.hopalong.parameters[parameter] === 'undefined') {
throw new Error(`Parameter with name '${parameter}' does not exist`);
}
const controlEl = bindControlEvent(parameter, onChange);
controlEl.value = window.hopalong.parameters[parameter];
function onChange({target: {value}}) {
const parsedValue = parseInt(value, 10);
window.hopalong.parameters[parameter] = isNaN(parsedValue) ? 0 : parsedValue;
}
}
function bindZoom(scaleId) {
document.body.addEventListener('wheel', onZoom);
function onZoom({deltaY}) {
window.hopalong.parameters.scale = window.hopalong.parameters.scale - deltaY;
setInputValue(scaleId, window.hopalong.parameters.scale);
}
}
function initScaleLimits(scaleId) {
const {SCALE_MIN, SCALE_MAX} = window.hopalong._constants;
const scaleEl = document.getElementById(scaleId);
if (!scaleEl) {
return console.error('Scale element not found');
}
scaleEl.setAttribute('min', SCALE_MIN);
scaleEl.setAttribute('max', SCALE_MAX);
}
function bindDragging(canvas) {
let prevX = null, prevY = null;
let initalIterations = null;
canvas.addEventListener('dragstart', onDragStart);
canvas.addEventListener('drag', onDrag);
canvas.addEventListener('dragend', onDragEnd);
function onDragStart({clientX, clientY, dataTransfer}) {
prevX = clientX;
prevY = clientY;
const img = this.cloneNode(true);
img.style.opacity = 0;
dataTransfer.setDragImage(img, 0, 0);
window.hopalong.toggleDragging();
}
function onDrag({clientX, clientY}) {
if (
(clientX !== 0 && clientY !== 0)
&& (prevX !== clientX || prevY !== clientY)
) {
window.hopalong.setOffset(
window.hopalong.parameters.offsetLeft - (prevX - clientX),
window.hopalong.parameters.offsetTop - (prevY - clientY)
);
prevX = clientX;
prevY = clientY;
window.hopalong.run();
}
}
function onDragEnd() {
window.hopalong.toggleDragging();
window.hopalong.run();
}
}
function setInputValue(id, value) {
const inputEl = document.getElementById(id);
if (!inputEl) {
return console.error(`Input with id '${id}' not found`);
}
inputEl.value = value;
}
function identity(value) {
return value;
}
})();