-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
145 lines (118 loc) · 3.71 KB
/
script.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
136
137
138
139
140
141
142
143
144
145
import { inputToValidMath } from './functionManipulations.js'
let stop = false
function f(x, y) {
try {
return eval(inputToValidMath(input.value))
} catch (e) {
stop = true
}
}
const input = document.querySelector('input')
input.oninput = debounce(run, 1000)
const size = 12
const results = {}
const steps = 0.5
const maxHeight = 90
const floorContainer = document.createElement('div')
floorContainer.className = 'container floor'
const container = document.createElement('div')
container.className = 'container'
document.body.appendChild(container)
container.appendChild(floorContainer)
function render() {
container.innerHTML = ''
container.appendChild(floorContainer)
let maxValue = result(-size, -size)
let minValue = result(-size, -size)
for (let x = -size; x <= size; x += steps) {
for (let y = -size; y <= size; y += steps) {
const value = result(x, y)
if (isNaN(value)) continue
if (isNaN(maxValue)) maxValue = value
if (isNaN(minValue)) minValue = value
if (value > maxValue) maxValue = value
if (value < minValue) minValue = value
}
}
for (let y = size; y >= -size; y -= steps) {
const lineDiv = document.createElement('div')
lineDiv.className = 'line'
for (let x = -size; x <= size; x += steps) {
const resultDiv = cube()
const current = result(y, x)
if (!isNaN(current)) {
const mapped = map(minValue, maxValue, current)
resultDiv.style.setProperty('--bg', `hsl(${mapped * 360} 100% 50%)`)
resultDiv.style.transform = `translateZ(${current}px)`
//resultDiv.style.transform = `translateZ(${mapped * maxHeight}px)`
}
lineDiv.appendChild(resultDiv)
}
container.appendChild(lineDiv)
}
}
function map(min, max, value) {
return (value - min) / (max - min)
}
function result(x, y) {
return results[`x${x}y${y}`]
}
function setResult(x, y, z) {
results[`x${x}y${y}`] = z
}
function cube() {
const div = document.createElement('div')
div.className = 'result cube'
/*
const front = document.createElement('div')
front.className = 'face front'
const right = document.createElement('div')
right.className = 'face right'
const back = document.createElement('div')
back.className = 'face back'
const left = document.createElement('div')
left.className = 'face left'
const top = document.createElement('div')
top.className = 'face top'
const bottom = document.createElement('div')
bottom.className = 'face bottom'
div.appendChild(front)
div.appendChild(right)
div.appendChild(back)
div.appendChild(left)
div.appendChild(top)
div.appendChild(bottom)
*/
return div
}
function run() {
stop = false
for (let y = size; y >= -size; y -= steps) {
if (stop) break
for (let x = -size; x <= size; x += steps) {
if (stop) break
const z = f(x, y)
setResult(x, y, z)
}
}
render()
}
function debounce(cb, delay = 200, ignoredCb) {
let timeout
return (...args) => {
if (ignoredCb) ignoredCb(...args)
clearTimeout(timeout)
timeout = setTimeout(() => {
cb(...args)
}, delay)
}
}
document.body.onwheel = ({ deltaY }) => {
let curAngle = +getComputedStyle(container).getPropertyValue('--angle').replace('deg', '')
const newAngle = (curAngle += 5 * (deltaY > 0 ? 1 : -1))
container.style.setProperty('--angle', `${clamp(0, 85, newAngle)}deg`)
}
function clamp(min, max, value) {
return Math.max(min, Math.min(max, value))
}
run()