starting zone element done

This commit is contained in:
Quentin Roussel
2024-03-28 21:53:43 +01:00
parent 27e5a6615a
commit 1a5405b4e8
4 changed files with 113 additions and 28 deletions

View File

@@ -3,7 +3,7 @@ import ActionDrawer from '@/components/team/actionDrawer';
import { useTeamConnexion } from '@/context/teamConnexionContext'; import { useTeamConnexion } from '@/context/teamConnexionContext';
import useGame from '@/hook/useGame'; import useGame from '@/hook/useGame';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React, { use } from 'react' import React from 'react'
//Load the map without SSR //Load the map without SSR
const LiveMap = dynamic(() => import('@/components/team/map'), { const LiveMap = dynamic(() => import('@/components/team/map'), {

View File

@@ -0,0 +1,70 @@
"use client";
import { useLocation } from "@/hook/useLocation";
import { use, useEffect, useState } from "react";
import "leaflet/dist/leaflet.css";
import { Circle, MapContainer, TileLayer, useMap } from "react-leaflet";
function MapPan(props) {
const map = useMap();
const [initialized, setInitialized] = useState(false);
useEffect(() => {
if (!initialized && props.center) {
map.flyTo(props.center, props.zoom, { animate: false });
setInitialized(true)
}
}, [props.center]);
return null;
}
function MapEventListener({onClick, onMouseMove}) {
const map = useMap();
useEffect(() => {
map.on('click', onClick);
return () => {
map.off('click', onClick);
}
}, [onClick]);
useEffect(() => {
map.on('mousemove', onMouseMove);
return () => {
map.off('mousemove', onMouseMove);
}
});
return null;
}
export function CircularAreaPicker({area, setArea, ...props}) {
const DEFAULT_ZOOM = 17;
const location = useLocation(Infinity);
const [drawing, setDrawing] = useState(false);
const [center, setCenter] = useState(area?.center || null);
const [radius, setRadius] = useState(area?.radius || null);
function handleClick(e) {
if(!drawing) {
setCenter(e.latlng);
setRadius(null);
setDrawing(true);
} else {
setDrawing(false);
setArea({center, radius});
}
}
function handleMouseMove(e) {
if(drawing) {
setRadius(e.latlng.distanceTo(center));
}
}
return (
<MapContainer {...props} className='min-h-full w-full ' center={[0, 0]} zoom={0} scrollWheelZoom={true}>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{center && radius && <Circle center={center} radius={radius} fillColor="blue"/>}
<MapPan center={location} zoom={DEFAULT_ZOOM} />
<MapEventListener onClick={handleClick} onMouseMove={handleMouseMove} />
</MapContainer>)
}

View File

@@ -2,6 +2,11 @@ import React, { useEffect, useState } from 'react'
import TextInput from '../util/textInput' import TextInput from '../util/textInput'
import Button from '../util/button'; import Button from '../util/button';
import useAdmin from '@/hook/useAdmin'; import useAdmin from '@/hook/useAdmin';
import dynamic from 'next/dynamic';
const CircularAreaPicker = dynamic(() => import('./mapPicker').then((mod) => mod.CircularAreaPicker), {
ssr: false
});
export default function TeamEdit({ selectedTeamId, setSelectedTeamId }) { export default function TeamEdit({ selectedTeamId, setSelectedTeamId }) {
const [newTeamName, setNewTeamName] = React.useState(''); const [newTeamName, setNewTeamName] = React.useState('');
@@ -35,6 +40,8 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) {
} }
return (team && return (team &&
<div className='flex flex-col h-full'>
<div className='flex flex-row'> <div className='flex flex-row'>
<div className='w-1/2 flex flex-col space-y-3 mx-2'> <div className='w-1/2 flex flex-col space-y-3 mx-2'>
<h2 className='text-2xl text-center'>Actions</h2> <h2 className='text-2xl text-center'>Actions</h2>
@@ -59,5 +66,10 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) {
</div> </div>
</div> </div>
</div> </div>
<div className='m-5 h-full flex flex-col'>
<h2 className='text-2xl text-center'>Starting area</h2>
<CircularAreaPicker area={team.startingArea} setArea={(startingArea) => setTeam({ ...team, startingArea })} />
</div>
</div>
) )
} }

View File

@@ -9,9 +9,12 @@ export function useLocation(interval) {
const [location, setLocation] = useState(); const [location, setLocation] = useState();
useEffect(() => { useEffect(() => {
function update() { function update() {
console.log('Updating location');
navigator.geolocation.getCurrentPosition((position) => { navigator.geolocation.getCurrentPosition((position) => {
setLocation([position.coords.latitude, position.coords.longitude]); setLocation([position.coords.latitude, position.coords.longitude]);
if(interval != Infinity) {
setTimeout(update, interval); setTimeout(update, interval);
}
}, () => { }, { enableHighAccuracy: true, timeout: Infinity, maximumAge: 0 }); }, () => { }, { enableHighAccuracy: true, timeout: Infinity, maximumAge: 0 });
} }
update(); update();