Add tooltip for box selection feature in map component
- Introduced a tooltip that guides users to draw a box for camera searches, displayed conditionally based on local storage state. - Implemented tooltip positioning logic and dismiss functionality. - Updated the Svelte component to enhance user interaction and experience.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount, onDestroy, tick } from 'svelte';
|
||||
import Map from 'ol/Map.js';
|
||||
import type MapBrowserEvent from 'ol/MapBrowserEvent.js';
|
||||
import { Style, Stroke, Fill } from 'ol/style.js';
|
||||
@@ -88,6 +88,9 @@
|
||||
let locationSearchDebounceTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let selectionBoxCenterPixel: [number, number] | null = null;
|
||||
let footerCollapsed = false;
|
||||
let showBoxTooltip = false;
|
||||
let boxSelectButton: HTMLButtonElement;
|
||||
let boxTooltipPosition: { left: number; top: number } | null = null;
|
||||
|
||||
let cameraSource: VectorSource;
|
||||
let clusterSource: Cluster;
|
||||
@@ -203,6 +206,15 @@
|
||||
|
||||
restoreStateFromUrl();
|
||||
|
||||
const hasSeenTooltip = localStorage.getItem('surveilled-box-tooltip-seen');
|
||||
if (!hasSeenTooltip) {
|
||||
setTimeout(async () => {
|
||||
showBoxTooltip = true;
|
||||
await tick();
|
||||
updateTooltipPosition();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(position) => {
|
||||
@@ -424,12 +436,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateTooltipPosition() {
|
||||
if (!boxSelectButton) return;
|
||||
const toolbar = boxSelectButton.closest('.toolbar');
|
||||
if (!toolbar) return;
|
||||
const toolbarContainer = toolbar.parentElement;
|
||||
if (!toolbarContainer) return;
|
||||
const buttonRect = boxSelectButton.getBoundingClientRect();
|
||||
const containerRect = toolbarContainer.getBoundingClientRect();
|
||||
boxTooltipPosition = {
|
||||
left: buttonRect.left - containerRect.left + buttonRect.width / 2,
|
||||
top: buttonRect.bottom - containerRect.top + 8,
|
||||
};
|
||||
}
|
||||
|
||||
function dismissBoxTooltip() {
|
||||
showBoxTooltip = false;
|
||||
localStorage.setItem('surveilled-box-tooltip-seen', 'true');
|
||||
}
|
||||
|
||||
function toggleBoxSelectMode() {
|
||||
if (isBoxSelectMode) {
|
||||
disableBoxSelectMode();
|
||||
} else {
|
||||
enableBoxSelectMode();
|
||||
}
|
||||
dismissBoxTooltip();
|
||||
}
|
||||
|
||||
function enableBoxSelectMode() {
|
||||
@@ -515,9 +547,6 @@
|
||||
width: 2.5,
|
||||
lineDash: [5, 3],
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(239, 68, 68, 0.18)',
|
||||
}),
|
||||
})
|
||||
);
|
||||
source.clear();
|
||||
@@ -947,6 +976,7 @@
|
||||
class="toolbar bg-bg-secondary/80 backdrop-blur-sm border border-border-color rounded-lg px-2 py-1.5 flex items-center gap-1 shadow-lg"
|
||||
>
|
||||
<button
|
||||
bind:this={boxSelectButton}
|
||||
class="toolbar-btn {isBoxSelectMode ? 'active' : ''}"
|
||||
title="Select Area (B)"
|
||||
on:click={toggleBoxSelectMode}
|
||||
@@ -983,6 +1013,30 @@
|
||||
<option value="satellite">Satellite</option>
|
||||
</select>
|
||||
</div>
|
||||
{#if showBoxTooltip && boxTooltipPosition}
|
||||
<div
|
||||
class="absolute z-[1300] pointer-events-none"
|
||||
style="left: {boxTooltipPosition.left}px; top: {boxTooltipPosition.top}px; transform: translateX(-50%);"
|
||||
>
|
||||
<div
|
||||
class="bg-bg-secondary border border-border-color rounded-lg px-3 py-2 shadow-lg text-sm text-text-primary relative"
|
||||
>
|
||||
<div
|
||||
class="absolute -top-2 left-1/2 -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-b-4 border-l-transparent border-r-transparent border-b-border-color"
|
||||
></div>
|
||||
<div
|
||||
class="absolute -top-[7px] left-1/2 -translate-x-1/2 w-0 h-0 border-l-[7px] border-r-[7px] border-b-[7px] border-l-transparent border-r-transparent border-b-bg-secondary"
|
||||
></div>
|
||||
<div class="relative z-10">Click here to draw a box and search for cameras</div>
|
||||
<button
|
||||
class="absolute top-1 right-1 text-text-secondary hover:text-text-primary pointer-events-auto"
|
||||
on:click={dismissBoxTooltip}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<button
|
||||
class="sm:hidden fixed bottom-4 left-4 z-[1100] bg-bg-secondary border border-border-color rounded-full px-3 py-2 text-xs font-semibold text-text-primary shadow-lg"
|
||||
|
||||
Reference in New Issue
Block a user