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 L from "leaflet";
import { createSignal, For, onMount } from "solid-js"; import { createEffect, createSignal, onMount } from "solid-js";
let map: L.Map | null = null; let map: L.Map | null = null;
export function Arrow() { export function Arrow() {
const container = <div class="h-[98vh] rounded-lg dark:opacity-60" />; 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(() => { onMount(() => {
map = L.map(container as HTMLElement) map = L.map(container as HTMLElement)
@ -19,19 +21,44 @@ export function Arrow() {
// Set up click logic // Set up click logic
map.addEventListener("click", (ev) => { map.addEventListener("click", (ev) => {
const p1 = ev.latlng; const point = ev.latlng;
const p2 = new L.LatLng(
p1.lat + 0.005,
p1.lng,
);
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);
// Compute the triangle
const p1 = first_point()!;
const [c1, c2, c3] = compute_triangle_points(p1, point);
// Draw the arrow. TODO: direction // Draw the arrow. TODO: direction
L.polygon([c1, c2, c3], { color: "red" }).addTo(map!); 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 ( return (
<div class="grid grid-cols-[30rem_auto]"> <div class="grid grid-cols-[30rem_auto]">
<div> <div>
@ -41,30 +68,41 @@ export function Arrow() {
</h2> </h2>
<p class="px-2"> <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> </p>
<div class="px-2 py-4"> <div class="px-2 py-4">
Puntos: Ruta:
<br /> <br />
<div class="h-40 overflow-scroll p-2 my-2 rounded border-2 border-c-primary"> <textarea
<For each={points()}> class="inline-block w-full bg-black text-white p-1 my-2 rounded"
{(p) => <p class="font-mono">{p.lat},{p.lng}</p>} name="" id=""
</For> 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> </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" <button class="bg-c-primary text-white py-2 px-4 rounded mr-2"
onClick={() => { onClick={() => {
const confirmation = confirm("¿Estas seguro? Se perderán todos los puntos"); 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 Reiniciar