Skip to content

Source ScaleBar

Source ScaleBar

Cette page est générée automatiquement à partir du dépôt local au moment de la génération de la documentation.

Fichiers inclus

packages/common/src/lib/widgets/scale-bar/scale-bar.declaration.ts

packages/common/src/lib/widgets/scale-bar/scale-bar.declaration.ts
import { widgetFactorySvelte, type WidgetProps } from '$lib/api/managers/widget';
import { type ScaleBarConfig, scaleBarConfigSchema } from './scale-bar.config';
import type { WidgetDeclaration } from '$lib/api/managers/widget/widget-declaration';
export const declaration = {
factory: () => import('./ScaleBar.svelte').then((ScaleBar) => widgetFactorySvelte(ScaleBar)),
schema: () => scaleBarConfigSchema,
} satisfies WidgetDeclaration;
export type ScaleBarProps = WidgetProps<ScaleBarConfig>;

packages/common/src/lib/widgets/scale-bar/scale-bar.config.ts

packages/common/src/lib/widgets/scale-bar/scale-bar.config.ts
import { defineWidgetConfig } from '$lib/api/managers/configuration';
import { inToolbarSchemaFrom } from '$lib/api/managers/configuration/models/widget/widget-in-toolbar.schema';
import { z } from 'zod';
export const scaleBarConfigSchema = defineWidgetConfig({
inToolbar: inToolbarSchemaFrom(false),
active: true,
config: z
.object({
scale: z.boolean().default(true),
bar: z.boolean().default(true),
})
.prefault({}),
});
export type ScaleBarConfig = z.infer<typeof scaleBarConfigSchema>;

packages/common/src/lib/widgets/scale-bar/ScaleBar.svelte

packages/common/src/lib/widgets/scale-bar/ScaleBar.svelte
<script lang="ts">
import { getMapManager } from '$lib/api/map';
import { debounceState, KeyboardEventKey } from '$lib/api/utils';
import { onDestroy } from 'svelte';
import type { ScaleBarProps } from './scale-bar.declaration';
const { fullConfig }: ScaleBarProps = $props();
const mapManager = getMapManager();
const scaleManager = mapManager.tools.scale;
let scale = $state(0);
const unsub = mapManager.tools.events.watch('SCALE', (v) => {
scale = v;
});
const debouncedScale = debounceState(() => scale, 150);
let info = $derived.by(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used for reactivity
debouncedScale.debounced;
return scaleManager.getCurrentScaleInfo();
});
function updateScale(event: KeyboardEvent) {
if (event.key === KeyboardEventKey.Enter) {
zoomToScale();
}
}
function zoomToScale() {
if (info) {
scaleManager.setScale(info.scaleForDevice);
}
}
onDestroy(() => {
unsub();
});
</script>
<div class="gv-bg-black/40 gv-text-white gv-flex gv-items-center gv-h-5 gv-gap-1 gv-px-1 gv-py-0.5">
{#if info}
{#if fullConfig.config.scale}
<span class="gv-text-[10px]/[12px]">
1:<input
onkeydown={updateScale}
bind:value={info.scaleForDevice}
onblur={zoomToScale}
class="gv-w-20 gv-bg-transparent focus:gv-outline-none gv-m-0"
type="number"
data-test-id="ScaleBar-Input"
/>
</span>
{/if}
{#if fullConfig.config.bar}
<span
class="gv-border gv-border-t-0 gv-border-white gv-px-2 gv-pb-0.5 gv-text-[10px]/[10px]"
style={`width: ${Math.round(info.length)}px`}
>
{info.value}
{info.unit}
</span>
{/if}
{/if}
</div>
<style>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type='number'] {
-moz-appearance: textfield;
}
</style>

Aller plus loin