Draw triangles based on user input
This commit is contained in:
parent
f16f1360e3
commit
81ca9d1bd6
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user