tangled
alpha
login
or
join now
moth11.net
/
xcvr
2
fork
atom
frontend for xcvr appview
2
fork
atom
overview
issues
pulls
pipelines
added trails maybe
moth11.net
6 months ago
32b15fbc
1ecd5fda
+176
-3
2 changed files
expand all
collapse all
unified
split
src
app.html
lib
components
AutoGrowTextArea.svelte
+176
-1
src/app.html
···
74
74
</filter>
75
75
</defs>
76
76
</svg>
77
77
-
<div style="display: flex; flex-direction:column; justify-content: space-between; height:100vh; height: 100dvh;">%sveltekit.body%</div>
77
77
+
<div style="display: flex; flex-direction:column; justify-content: space-between; height:100vh; height: 100dvh;">%sveltekit.body%</div><script type="module">
78
78
+
import {
79
79
+
Polyline,
80
80
+
Renderer,
81
81
+
Transform,
82
82
+
Geometry,
83
83
+
Program,
84
84
+
Mesh,
85
85
+
Vec3,
86
86
+
Vec2,
87
87
+
Color,
88
88
+
} from "https://cdn.jsdelivr.net/npm/ogl@0.0.32/dist/ogl.mjs";
89
89
+
90
90
+
const vertex = `
91
91
+
attribute vec3 position;
92
92
+
attribute vec3 next;
93
93
+
attribute vec3 prev;
94
94
+
attribute vec2 uv;
95
95
+
attribute float side;
96
96
+
97
97
+
uniform vec2 uResolution;
98
98
+
uniform float uDPR;
99
99
+
uniform float uThickness;
100
100
+
101
101
+
vec4 getPosition() {
102
102
+
vec2 aspect = vec2(uResolution.x / uResolution.y, 1);
103
103
+
vec2 nextScreen = next.xy * aspect;
104
104
+
vec2 prevScreen = prev.xy * aspect;
105
105
+
106
106
+
vec2 tangent = normalize(nextScreen - prevScreen);
107
107
+
vec2 normal = vec2(-tangent.y, tangent.x);
108
108
+
normal /= aspect;
109
109
+
normal *= 1.0 - pow(abs(uv.y - 0.5) * 1.9, 2.0);
110
110
+
111
111
+
float pixelWidth = 1.0 / (uResolution.y / uDPR);
112
112
+
normal *= pixelWidth * uThickness;
113
113
+
114
114
+
// When the points are on top of each other, shrink the line to avoid artifacts.
115
115
+
float dist = length(nextScreen - prevScreen);
116
116
+
normal *= smoothstep(0.0, 0.02, dist);
117
117
+
118
118
+
vec4 current = vec4(position, 1);
119
119
+
current.xy -= normal * side;
120
120
+
return current;
121
121
+
}
122
122
+
123
123
+
void main() {
124
124
+
gl_Position = getPosition();
125
125
+
}
126
126
+
`;
127
127
+
128
128
+
{
129
129
+
const renderer = new Renderer({ dpr: 2 });
130
130
+
const gl = renderer.gl;
131
131
+
document.body.appendChild(gl.canvas);
132
132
+
gl.clearColor(0.9, 0.9, 0.9, 1);
133
133
+
134
134
+
const scene = new Transform();
135
135
+
136
136
+
const lines = [];
137
137
+
138
138
+
function resize() {
139
139
+
renderer.setSize(window.innerWidth, window.innerHeight);
140
140
+
141
141
+
// We call resize on the polylines to update their resolution uniforms
142
142
+
lines.forEach((line) => line.polyline.resize());
143
143
+
}
144
144
+
window.addEventListener("resize", resize, false);
145
145
+
146
146
+
// If you're interested in learning about drawing lines with geometry,
147
147
+
// go through this detailed article by Matt DesLauriers
148
148
+
// https://mattdesl.svbtle.com/drawing-lines-is-hard
149
149
+
// It's an excellent breakdown of the approaches and their pitfalls.
150
150
+
151
151
+
// In this example, we're making screen-space polylines. Basically it
152
152
+
// involves creating a geometry of vertices along a path - with two vertices
153
153
+
// at each point. Then in the vertex shader, we push each pair apart to
154
154
+
// give the line some width.
155
155
+
156
156
+
// Just a helper function to make the code neater
157
157
+
function random(a, b) {
158
158
+
const alpha = Math.random();
159
159
+
return a * (1.0 - alpha) + b * alpha;
160
160
+
}
161
161
+
162
162
+
// We're going to make a number of different coloured lines for fun.
163
163
+
["#e18f39", "#c5c042", "#387f4d", "#1d4633", "#000000"].forEach(
164
164
+
(color, i) => {
165
165
+
// Store a few values for each lines' randomised spring movement
166
166
+
const line = {
167
167
+
spring: random(0.02, 0.1),
168
168
+
friction: random(0.7, 0.95),
169
169
+
mouseVelocity: new Vec3(),
170
170
+
mouseOffset: new Vec3(random(-1, 1) * 0.02),
171
171
+
};
172
172
+
173
173
+
// Create an array of Vec3s (eg [[0, 0, 0], ...])
174
174
+
const count = 20;
175
175
+
const points = (line.points = []);
176
176
+
for (let i = 0; i < count; i++) points.push(new Vec3());
177
177
+
178
178
+
line.polyline = new Polyline(gl, {
179
179
+
points,
180
180
+
vertex,
181
181
+
uniforms: {
182
182
+
uColor: { value: new Color(color) },
183
183
+
uThickness: { value: random(20, 50) },
184
184
+
},
185
185
+
});
186
186
+
187
187
+
line.polyline.mesh.setParent(scene);
188
188
+
189
189
+
lines.push(line);
190
190
+
}
191
191
+
);
192
192
+
193
193
+
// Call initial resize after creating the polylines
194
194
+
resize();
195
195
+
196
196
+
// Add handlers to get mouse position
197
197
+
const mouse = new Vec3();
198
198
+
if ("ontouchstart" in window) {
199
199
+
window.addEventListener("touchstart", updateMouse, false);
200
200
+
window.addEventListener("touchmove", updateMouse, false);
201
201
+
} else {
202
202
+
window.addEventListener("mousemove", updateMouse, false);
203
203
+
}
204
204
+
205
205
+
function updateMouse(e) {
206
206
+
if (e.changedTouches && e.changedTouches.length) {
207
207
+
e.x = e.changedTouches[0].pageX;
208
208
+
e.y = e.changedTouches[0].pageY;
209
209
+
}
210
210
+
if (e.x === undefined) {
211
211
+
e.x = e.pageX;
212
212
+
e.y = e.pageY;
213
213
+
}
214
214
+
215
215
+
// Get mouse value in -1 to 1 range, with y flipped
216
216
+
mouse.set(
217
217
+
(e.x / gl.renderer.width) * 2 - 1,
218
218
+
(e.y / gl.renderer.height) * -2 + 1,
219
219
+
0
220
220
+
);
221
221
+
}
222
222
+
223
223
+
const tmp = new Vec3();
224
224
+
225
225
+
requestAnimationFrame(update);
226
226
+
function update(t) {
227
227
+
requestAnimationFrame(update);
228
228
+
229
229
+
lines.forEach((line) => {
230
230
+
// Update polyline input points
231
231
+
for (let i = line.points.length - 1; i >= 0; i--) {
232
232
+
if (!i) {
233
233
+
// For the first point, spring ease it to the mouse position
234
234
+
tmp
235
235
+
.copy(mouse)
236
236
+
.add(line.mouseOffset)
237
237
+
.sub(line.points[i])
238
238
+
.multiply(line.spring);
239
239
+
line.mouseVelocity.add(tmp).multiply(line.friction);
240
240
+
line.points[i].add(line.mouseVelocity);
241
241
+
} else {
242
242
+
// The rest of the points ease to the point in front of them, making a line
243
243
+
line.points[i].lerp(line.points[i - 1], 0.9);
244
244
+
}
245
245
+
}
246
246
+
line.polyline.updateGeometry();
247
247
+
});
248
248
+
249
249
+
renderer.render({ scene });
250
250
+
}
251
251
+
}
252
252
+
</script>
78
253
</body>
79
254
</html>
-2
src/lib/components/AutoGrowTextArea.svelte
···
26
26
let inputEl: HTMLTextAreaElement;
27
27
function adjust(event: Event) {
28
28
onInput?.(event as InputEvent);
29
29
-
console.log("next message is emoji check: ");
30
30
-
console.log(inputEl.selectionStart, inputEl.selectionEnd);
31
29
console.log(checkEmoji(inputEl.selectionStart, inputEl.selectionEnd));
32
30
}
33
31