-
Notifications
You must be signed in to change notification settings - Fork 2
/
scroll.html
144 lines (125 loc) · 4.4 KB
/
scroll.html
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
<!-- vim: sw=2 ts=2 expandtab smartindent ft=javascript
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>WebGL Demo</title>
<style> document, body { margin: 0px; padding: 0px; overflow: hidden; } </style>
</head>
<body>
<canvas id="glcanvas"></canvas>
<script>"use strict";
const canvas = document.getElementById("glcanvas");
const ctx = canvas.getContext('2d');
(window.onresize = () => {
canvas.width = window.innerWidth*window.devicePixelRatio,
canvas.height = window.innerHeight*window.devicePixelRatio
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
})();
function line(a, b, thick, color) {
ctx.lineWidth = thick;
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(window.innerWidth*window.devicePixelRatio*0.5 + a[0], window.innerHeight*window.devicePixelRatio*0.5 + a[1]);
ctx.lineTo(window.innerWidth*window.devicePixelRatio*0.5 + b[0], window.innerHeight*window.devicePixelRatio*0.5 + b[1]);
ctx.stroke();
}
let input_scroll = 0;
let scroll = 0;
window.onwheel = e => {
input_scroll += e.deltaY;
}
window.onpointermove = e => {
if (e.buttons)
input_scroll += e.movementY*1.5;
e.preventDefault();
}
let then = 0;
let deltaTime = 0;
requestAnimationFrame(function render(now) {
requestAnimationFrame(render);
now *= 0.001;
deltaTime = now - then;
then = now;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
const full_height = 800;
const window_height = 100;
{
scroll += input_scroll * 0.7 * deltaTime;
input_scroll *= Math.pow(1 - 0.15, 60*deltaTime);
scroll = Math.max(scroll, 0);
scroll = Math.min(scroll + window_height, full_height) - window_height;
}
ctx.fillStyle = "red";
const window_min_y = scroll;
const window_max_y = scroll + window_height;
const bottom_scroll_x = 100;
const scroll_height = 600;
const scroll_radius = 100;
function draw_scroll(start_x, start_y, scroll_prog, rotation) {
const coils = 4;
const theta_max = coils * Math.PI * 2;
const away_step = scroll_radius / theta_max;
const chord = (scroll_radius / 25);
const start = (scroll_radius / 7 ) / away_step;
for (let theta = theta_max; theta > lerp(start, theta_max-start*2, scroll_prog);) {
const x0 = Math.cos(theta + rotation) * (away_step * theta);
const y0 = Math.sin(theta + rotation) * (away_step * theta);
theta -= chord / (away_step * theta);
const r1 = theta;
const x1 = Math.cos(theta + rotation) * (away_step * theta);
const y1 = Math.sin(theta + rotation) * (away_step * theta);
line(
[start_x + x0, start_y + y0],
[start_x + x1, start_y + y1],
5,
"purple"
);
}
}
{
const scroll_prog = scroll / (full_height - window_height);
draw_scroll(bottom_scroll_x, scroll_height*0.5, 1 - scroll_prog, Math.PI);// );
draw_scroll( 0, -scroll_height*0.5, scroll_prog, 0);// - 0.1);
{
function bezier4_sample(out, p0, p1, p2, p3, t) {
out[0] = Math.pow(1 - t, 3) * p0[0] +
Math.pow(1 - t, 2) * 3 * t * p1[0] +
(1 - t) * 3 * t * t * p2[0] +
t * t * t * p3[0];
out[1] = Math.pow(1 - t, 3) * p0[1] +
Math.pow(1 - t, 2) * 3 * t * p1[1] +
(1 - t) * 3 * t * t * p2[1] +
t * t * t * p3[1];
}
const bezier_i = 30;
const e = scroll_radius * 0.45;
const a = [bottom_scroll_x + -scroll_radius, scroll_height*0.5];
const b = [ 0 + scroll_radius, -scroll_height*0.5];
const control0 = [bottom_scroll_x + -scroll_radius, scroll_height*0.3];
const control1 = [ e + scroll_radius, scroll_height*0.3];
const out_from = [0, 0]
const out_to = [0, 0]
for (let i = 1; i <= bezier_i; i++) {
const t0 = (i - 1)/bezier_i;
bezier4_sample(out_from, a, control0, control1, b, t0);
const t1 = (i + 0)/bezier_i;
bezier4_sample(out_to , a, control0, control1, b, t1);
line(
out_from,
out_to,
5,
"purple"
);
}
}
}
})
function lerp(v0, v1, t) { return (1 - t) * v0 + t * v1; }
function inv_lerp(min, max, p) { return (p - min) / (max - min); }
</script>
</body>
</html>