Spaces:
Runtime error
Runtime error
Arrcttacsrks
commited on
Commit
•
c0adbf1
1
Parent(s):
26c4797
Upload 4 files
Browse files- app.py +10 -0
- static/interactive_spider.css +5 -0
- static/interactive_spider.js +150 -0
- templates/index.html +17 -0
app.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, render_template
|
2 |
+
|
3 |
+
app = Flask(__name__)
|
4 |
+
|
5 |
+
@app.route('/')
|
6 |
+
def index():
|
7 |
+
return render_template('index.html')
|
8 |
+
|
9 |
+
if __name__ == '__main__':
|
10 |
+
app.run(debug=True)
|
static/interactive_spider.css
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {
|
2 |
+
overflow: hidden;
|
3 |
+
margin: 0;
|
4 |
+
cursor: pointer;
|
5 |
+
}
|
static/interactive_spider.js
ADDED
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
let w, h;
|
2 |
+
const ctx = canvas.getContext("2d");
|
3 |
+
const { sin, cos, PI, hypot, min, max } = Math;
|
4 |
+
|
5 |
+
function spawn() {
|
6 |
+
|
7 |
+
const pts = many(333, () => {
|
8 |
+
return {
|
9 |
+
x: rnd(innerWidth),
|
10 |
+
y: rnd(innerHeight),
|
11 |
+
len: 0,
|
12 |
+
r: 0
|
13 |
+
};
|
14 |
+
});
|
15 |
+
|
16 |
+
const pts2 = many(9, (i) => {
|
17 |
+
return {
|
18 |
+
x: cos((i / 9) * PI * 2),
|
19 |
+
y: sin((i / 9) * PI * 2)
|
20 |
+
};
|
21 |
+
});
|
22 |
+
|
23 |
+
let seed = rnd(100)
|
24 |
+
let tx = rnd(innerWidth);
|
25 |
+
let ty = rnd(innerHeight);
|
26 |
+
let x = rnd(innerWidth)
|
27 |
+
let y = rnd(innerHeight)
|
28 |
+
let kx = rnd(0.8, 0.8)
|
29 |
+
let ky = rnd(0.8, 0.8)
|
30 |
+
let walkRadius = pt(rnd(50,50), rnd(50,50))
|
31 |
+
let r = innerWidth / rnd(100, 150);
|
32 |
+
|
33 |
+
function paintPt(pt){
|
34 |
+
pts2.forEach((pt2) => {
|
35 |
+
if (!pt.len )
|
36 |
+
return
|
37 |
+
drawLine(
|
38 |
+
lerp(x + pt2.x * r, pt.x, pt.len * pt.len),
|
39 |
+
lerp(y + pt2.y * r, pt.y, pt.len * pt.len),
|
40 |
+
x + pt2.x * r,
|
41 |
+
y + pt2.y * r
|
42 |
+
);
|
43 |
+
});
|
44 |
+
drawCircle(pt.x, pt.y, pt.r);
|
45 |
+
}
|
46 |
+
|
47 |
+
return {
|
48 |
+
follow(x,y) {
|
49 |
+
tx = x;
|
50 |
+
ty = y;
|
51 |
+
},
|
52 |
+
|
53 |
+
tick(t) {
|
54 |
+
|
55 |
+
const selfMoveX = cos(t*kx+seed)*walkRadius.x;
|
56 |
+
const selfMoveY = sin(t*ky+seed)*walkRadius.y;
|
57 |
+
let fx = tx + selfMoveX;
|
58 |
+
let fy = ty + selfMoveY;
|
59 |
+
|
60 |
+
x += min(innerWidth/100, (fx - x)/10)
|
61 |
+
y += min(innerWidth/100, (fy - y)/10)
|
62 |
+
|
63 |
+
let i = 0
|
64 |
+
pts.forEach((pt) => {
|
65 |
+
const dx = pt.x - x,
|
66 |
+
dy = pt.y - y;
|
67 |
+
const len = hypot(dx, dy);
|
68 |
+
let r = min(2, innerWidth / len / 5);
|
69 |
+
pt.t = 0;
|
70 |
+
const increasing = len < innerWidth / 10
|
71 |
+
&& (i++) < 8;
|
72 |
+
let dir = increasing ? 0.1 : -0.1;
|
73 |
+
if (increasing) {
|
74 |
+
r *= 1.5;
|
75 |
+
}
|
76 |
+
pt.r = r;
|
77 |
+
pt.len = max(0, min(pt.len + dir, 1));
|
78 |
+
paintPt(pt)
|
79 |
+
});
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
const spiders = many(2, spawn)
|
85 |
+
|
86 |
+
addEventListener("pointermove", (e) => {
|
87 |
+
spiders.forEach(spider => {
|
88 |
+
spider.follow(e.clientX, e.clientY)
|
89 |
+
})
|
90 |
+
});
|
91 |
+
requestAnimationFrame(function anim(t) {
|
92 |
+
if (w !== innerWidth) w = canvas.width = innerWidth;
|
93 |
+
if (h !== innerHeight) h = canvas.height = innerHeight;
|
94 |
+
ctx.fillStyle = "#000";
|
95 |
+
drawCircle(0, 0, w * 10);
|
96 |
+
ctx.fillStyle = ctx.strokeStyle = "#fff";
|
97 |
+
t/=1000
|
98 |
+
spiders.forEach(spider => spider.tick(t))
|
99 |
+
requestAnimationFrame(anim);
|
100 |
+
});
|
101 |
+
|
102 |
+
function recalc(X, Y) {
|
103 |
+
tx = X;
|
104 |
+
ty = Y;
|
105 |
+
}
|
106 |
+
|
107 |
+
function rnd(x = 1, dx = 0) {
|
108 |
+
return Math.random() * x + dx;
|
109 |
+
}
|
110 |
+
|
111 |
+
function drawCircle(x, y, r, color) {
|
112 |
+
ctx.beginPath();
|
113 |
+
ctx.ellipse(x, y, r, r, 0, 0, PI * 2);
|
114 |
+
ctx.fill();
|
115 |
+
}
|
116 |
+
|
117 |
+
function drawLine(x0, y0, x1, y1) {
|
118 |
+
ctx.beginPath();
|
119 |
+
ctx.moveTo(x0, y0);
|
120 |
+
|
121 |
+
many(100, (i) => {
|
122 |
+
i = (i + 1) / 100;
|
123 |
+
let x = lerp(x0, x1, i);
|
124 |
+
let y = lerp(y0, y1, i);
|
125 |
+
let k = noise(x/5+x0, y/5+y0) * 2;
|
126 |
+
ctx.lineTo(x + k, y + k);
|
127 |
+
});
|
128 |
+
|
129 |
+
ctx.stroke();
|
130 |
+
}
|
131 |
+
|
132 |
+
function many(n, f) {
|
133 |
+
return [...Array(n)].map((_, i) => f(i));
|
134 |
+
}
|
135 |
+
|
136 |
+
function lerp(a, b, t) {
|
137 |
+
return a + (b - a) * t;
|
138 |
+
}
|
139 |
+
|
140 |
+
function noise(x, y, t = 101) {
|
141 |
+
let w0 = sin(0.3 * x + 1.4 * t + 2.0 +
|
142 |
+
2.5 * sin(0.4 * y + -1.3 * t + 1.0));
|
143 |
+
let w1 = sin(0.2 * y + 1.5 * t + 2.8 +
|
144 |
+
2.3 * sin(0.5 * x + -1.2 * t + 0.5));
|
145 |
+
return w0 + w1;
|
146 |
+
}
|
147 |
+
|
148 |
+
function pt(x,y){
|
149 |
+
return {x,y}
|
150 |
+
}
|
templates/index.html
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="utf-8">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='interactive_spider.css') }}">
|
8 |
+
<title>Interactive Spider</title>
|
9 |
+
</head>
|
10 |
+
|
11 |
+
<body>
|
12 |
+
<p>Visit my TikTok <a href="https://www.tiktok.com/@Meowish" target="_blank">Meowish</a> for more code!</p>
|
13 |
+
<canvas id="canvas"></canvas>
|
14 |
+
<script src="{{ url_for('static', filename='interactive_spider.js') }}"></script>
|
15 |
+
</body>
|
16 |
+
|
17 |
+
</html>
|