Draw triangles based on user input

master
Araozu 2024-09-04 16:49:31 -05:00
parent f16f1360e3
commit 81ca9d1bd6
1 changed files with 64 additions and 26 deletions

View File

@ -1,11 +1,13 @@
import L from "leaflet";
import { createSignal, For, onMount } from "solid-js";
import { createEffect, createSignal, onMount } from "solid-js";
let map: L.Map | null = null;
export function Arrow() {
const container = <div class="h-[98vh] rounded-lg dark:opacity-60" />;
const [points, setPoints] = createSignal<Array<L.LatLng>>([]);
const [first_point, set_first_point] = createSignal<L.LatLng | null>(null);
const [second_point, set_second_point] = createSignal<L.LatLng | null>(null);
const [points, setPoints] = createSignal<Array<[number, number]>>([]);
onMount(() => {
map = L.map(container as HTMLElement)
@ -19,19 +21,44 @@ export function Arrow() {
// Set up click logic
map.addEventListener("click", (ev) => {
const p1 = ev.latlng;
const p2 = new L.LatLng(
p1.lat + 0.005,
p1.lng,
);
const point = ev.latlng;
const [c1, c2, c3] = compute_triangle_points(p1, p2);
if (first_point() === null) {
// Set first point
set_first_point(point);
return;
}
if (second_point() === null) {
set_second_point(point);
// Draw the arrow. TODO: direction
L.polygon([c1, c2, c3], { color: "red" }).addTo(map!);
// Compute the triangle
const p1 = first_point()!;
const [c1, c2, c3] = compute_triangle_points(p1, point);
// Draw the arrow. TODO: direction
L.polygon([c1, c2, c3], { color: "red" }).addTo(map!);
// Reset
set_first_point(null);
set_second_point(null);
}
});
});
let current_polyline: L.Polyline | null = null;
createEffect(() => {
const dots = points().map(([lat, lng]) => ({ lat, lng }));
if (dots.length === 0) {
current_polyline?.removeFrom(map!);
current_polyline = null;
}
current_polyline = L.polyline(dots, { color: "red" });
current_polyline.addTo(map!);
});
return (
<div class="grid grid-cols-[30rem_auto]">
<div>
@ -41,30 +68,41 @@ export function Arrow() {
</h2>
<p class="px-2">
Haz click en cualquier parte del mapa para crear una flecha.
Ingresá una ruta.
<br />
Haz click en un punto de la ruta (punto inicial)
<br />
Haz click en otro punto de la ruta (punto final)
<br />
Un triangulo se creará en el medio, apuntdando hacia
el punto final
</p>
<div class="px-2 py-4">
Puntos:
Ruta:
<br />
<div class="h-40 overflow-scroll p-2 my-2 rounded border-2 border-c-primary">
<For each={points()}>
{(p) => <p class="font-mono">{p.lat},{p.lng}</p>}
</For>
<textarea
class="inline-block w-full bg-black text-white p-1 my-2 rounded"
name="" id=""
onInput={(e) => setPoints(JSON.parse(e.target.value))}
/>
Puntos:
<div>
Punto 1: {first_point()?.lat ?? "<vacio>"}, {first_point()?.lng ?? "<vacio>"}
<br />
Punto 2: {second_point()?.lat ?? "<vacio>"}, {second_point()?.lng ?? "<vacio>"}
</div>
<button class="bg-c-primary text-white py-2 px-4 rounded mr-2"
onClick={() => {
if (points().length >= 1) {
setPoints((x) => x.slice(0, -1));
}
}}
>
Retroceder
</button>
<button class="bg-c-primary text-white py-2 px-4 rounded mr-2"
onClick={() => {
const confirmation = confirm("¿Estas seguro? Se perderán todos los puntos");
if (confirmation) setPoints([]);
if (confirmation) {
setPoints([]);
set_first_point(null);
set_second_point(null);
}
}}
>
Reiniciar