finished embedding

This commit is contained in:
vcoppe
2024-07-12 18:08:27 +02:00
parent 5419088eaf
commit 24a5daaf9a
13 changed files with 194 additions and 62 deletions

View File

@@ -14,7 +14,9 @@
import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public';
export let accessToken = PUBLIC_MAPBOX_TOKEN;
export let geolocate = true;
export let geocoder = true;
export let hash = true;
mapboxgl.accessToken = accessToken;
@@ -35,7 +37,7 @@
container: 'map',
style: { version: 8, sources: {}, layers: [] },
projection: { name: 'mercator' },
hash: true,
hash: hash,
language: get(locale),
attributionControl: false,
logoPosition: 'bottom-right',
@@ -66,16 +68,18 @@
);
}
newMap.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
fitBoundsOptions,
trackUserLocation: true,
showUserHeading: true
})
);
if (geolocate) {
newMap.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
fitBoundsOptions,
trackUserLocation: true,
showUserHeading: true
})
);
}
newMap.addControl(scaleControl);

View File

@@ -74,6 +74,11 @@
@apply hover:underline;
}
:global(.markdown li > a) {
@apply text-blue-500;
@apply hover:underline;
}
:global(.markdown kbd) {
@apply p-1;
@apply rounded-md;

View File

@@ -9,3 +9,10 @@
>
<slot />
</div>
<style lang="postcss">
div :global(a) {
@apply text-blue-500;
@apply hover:underline;
}
</style>

View File

@@ -18,14 +18,25 @@
$embedding = true;
const { currentBasemap, distanceUnits, velocityUnits, temperatureUnits, fileOrder } = settings;
const {
currentBasemap,
distanceUnits,
velocityUnits,
temperatureUnits,
fileOrder,
distanceMarkers,
directionMarkers
} = settings;
export let options: EmbeddingOptions;
export let hash: string;
let prevUnits = {
distance: '',
velocity: '',
temperature: ''
let prevSettings = {
distanceMarkers: false,
directionMarkers: false,
distanceUnits: 'metric',
velocityUnits: 'speed',
temperatureUnits: 'celsius'
};
function applyOptions() {
@@ -97,29 +108,39 @@
return $selection;
});
map.subscribe(($map) => {
if ($map) {
$map.fitBounds(
[
bounds.southWest.lon,
bounds.southWest.lat,
bounds.northEast.lon,
bounds.northEast.lat
],
{
padding: 80,
linear: true,
easing: () => 1
}
);
}
});
if (hash.length === 0) {
map.subscribe(($map) => {
if ($map) {
$map.fitBounds(
[
bounds.southWest.lon,
bounds.southWest.lat,
bounds.northEast.lon,
bounds.northEast.lat
],
{
padding: 80,
linear: true,
easing: () => 1
}
);
}
});
}
});
if (options.basemap !== $currentBasemap && allowedEmbeddingBasemaps.includes(options.basemap)) {
$currentBasemap = options.basemap;
}
if (options.distanceMarkers !== $distanceMarkers) {
$distanceMarkers = options.distanceMarkers;
}
if (options.directionMarkers !== $directionMarkers) {
$directionMarkers = options.directionMarkers;
}
if (options.distanceUnits !== $distanceUnits) {
$distanceUnits = options.distanceUnits;
}
@@ -134,9 +155,11 @@
}
onMount(() => {
prevUnits.distance = $distanceUnits;
prevUnits.velocity = $velocityUnits;
prevUnits.temperature = $temperatureUnits;
prevSettings.distanceMarkers = $distanceMarkers;
prevSettings.directionMarkers = $directionMarkers;
prevSettings.distanceUnits = $distanceUnits;
prevSettings.velocityUnits = $velocityUnits;
prevSettings.temperatureUnits = $temperatureUnits;
});
$: if (options) {
@@ -144,16 +167,24 @@
}
onDestroy(() => {
if ($distanceUnits !== prevUnits.distance) {
$distanceUnits = prevUnits.distance;
if ($distanceMarkers !== prevSettings.distanceMarkers) {
$distanceMarkers = prevSettings.distanceMarkers;
}
if ($velocityUnits !== prevUnits.velocity) {
$velocityUnits = prevUnits.velocity;
if ($directionMarkers !== prevSettings.directionMarkers) {
$directionMarkers = prevSettings.directionMarkers;
}
if ($temperatureUnits !== prevUnits.temperature) {
$temperatureUnits = prevUnits.temperature;
if ($distanceUnits !== prevSettings.distanceUnits) {
$distanceUnits = prevSettings.distanceUnits;
}
if ($velocityUnits !== prevSettings.velocityUnits) {
$velocityUnits = prevSettings.velocityUnits;
}
if ($temperatureUnits !== prevSettings.temperatureUnits) {
$temperatureUnits = prevSettings.temperatureUnits;
}
$fileOrder = $fileOrder.filter((id) => !id.includes('embed'));
@@ -166,6 +197,8 @@
class="h-full {$fileObservers.size > 1 ? 'horizontal' : ''}"
accessToken={options.token}
geocoder={false}
geolocate={false}
hash={false}
/>
<OpenIn bind:files={options.files} />
<LayerControl />

View File

@@ -1,3 +1,5 @@
import { basemaps } from "$lib/assets/layers";
export type EmbeddingOptions = {
token: string;
files: string[];
@@ -13,6 +15,8 @@ export type EmbeddingOptions = {
temp: boolean,
power: boolean,
},
distanceMarkers: boolean,
directionMarkers: boolean,
distanceUnits: 'metric' | 'imperial',
velocityUnits: 'speed' | 'pace',
temperatureUnits: 'celsius' | 'fahrenheit',
@@ -33,6 +37,8 @@ export const defaultEmbeddingOptions = {
temp: false,
power: false,
},
distanceMarkers: false,
directionMarkers: false,
distanceUnits: 'metric',
velocityUnits: 'speed',
temperatureUnits: 'celsius',
@@ -57,7 +63,4 @@ export function getCleanedEmbeddingOptions(options: any, defaultOptions: any = d
return cleanedOptions;
}
export const allowedEmbeddingBasemaps = [
'mapboxOutdoors',
'mapboxSatellite',
];
export const allowedEmbeddingBasemaps = Object.keys(basemaps).filter(basemap => !['ordnanceSurvey'].includes(basemap));

View File

@@ -5,7 +5,16 @@
import * as Select from '$lib/components/ui/select';
import { Checkbox } from '$lib/components/ui/checkbox';
import * as RadioGroup from '$lib/components/ui/radio-group';
import { Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
import {
Zap,
HeartPulse,
Orbit,
Thermometer,
SquareActivity,
Coins,
Milestone,
Video
} from 'lucide-svelte';
import { _ } from 'svelte-i18n';
import {
allowedEmbeddingBasemaps,
@@ -35,11 +44,11 @@
let manualCamera = false;
let zoom = 0;
let lat = 0;
let lon = 0;
let bearing = 0;
let pitch = 0;
let zoom = '0';
let lat = '0';
let lon = '0';
let bearing = '0';
let pitch = '0';
$: hash = manualCamera ? `#${zoom}/${lat}/${lon}/${bearing}/${pitch}` : '';
@@ -58,6 +67,21 @@
$: if (options.elevation.height || options.elevation.show) {
resizeMap();
}
function updateCamera() {
if ($map) {
let center = $map.getCenter();
lat = center.lat.toFixed(4);
lon = center.lng.toFixed(4);
zoom = $map.getZoom().toFixed(2);
bearing = $map.getBearing().toFixed(1);
pitch = $map.getPitch().toFixed(0);
}
}
$: if ($map) {
$map.on('moveend', updateCamera);
}
</script>
<Card.Root>
@@ -164,6 +188,20 @@
</div>
</div>
{/if}
<div class="flex flex-row items-center gap-2">
<Checkbox id="distance-markers" bind:checked={options.distanceMarkers} />
<Label for="distance-markers" class="flex flex-row items-center gap-1">
<Coins size="16" />
{$_('menu.distance_markers')}
</Label>
</div>
<div class="flex flex-row items-center gap-2">
<Checkbox id="direction-markers" bind:checked={options.directionMarkers} />
<Label for="direction-markers" class="flex flex-row items-center gap-1">
<Milestone size="16" />
{$_('menu.direction_markers')}
</Label>
</div>
<div class="flex flex-row flex-wrap justify-between gap-3">
<Label class="flex flex-col items-start gap-2">
{$_('menu.distance_units')}
@@ -205,18 +243,52 @@
</RadioGroup.Root>
</Label>
</div>
<div class="flex flex-col gap-3 p-3 border rounded-md">
<div class="flex flex-row items-center gap-2">
<Checkbox id="manual-camera" bind:checked={manualCamera} />
<Label for="manual-camera" class="flex flex-row items-center gap-1">
<Video size="16" />
{$_('embedding.manual_camera')}
</Label>
</div>
<p class="text-sm text-muted-foreground">
{$_('embedding.manual_camera_description')}
</p>
<div class="flex flex-row flex-wrap items-center gap-6">
<Label class="flex flex-col gap-1">
<span>{$_('embedding.latitude')}</span>
<span>{lat}</span>
</Label>
<Label class="flex flex-col gap-1">
<span>{$_('embedding.longitude')}</span>
<span>{lon}</span>
</Label>
<Label class="flex flex-col gap-1">
<span>{$_('embedding.zoom')}</span>
<span>{zoom}</span>
</Label>
<Label class="flex flex-col gap-1">
<span>{$_('embedding.bearing')}</span>
<span>{bearing}</span>
</Label>
<Label class="flex flex-col gap-1">
<span>{$_('embedding.pitch')}</span>
<span>{pitch}</span>
</Label>
</div>
</div>
<Label>
{$_('embedding.preview')}
</Label>
<div class="relative h-[600px]">
<Embedding bind:options={iframeOptions} />
<Embedding bind:options={iframeOptions} bind:hash />
</div>
<Label>
{$_('embedding.code')}
</Label>
<pre class="bg-primary text-primary-foreground p-3 rounded-md whitespace-normal break-all">
<code class="language-html">
{`<iframe src="https://gpx.studio${base}/embed?options=${encodeURIComponent(JSON.stringify(getCleanedEmbeddingOptions(options)))}${hash}" width="100%" height="600px" frameborder="0" />`}
{`<iframe src="https://gpx.studio${base}/embed?options=${encodeURIComponent(JSON.stringify(getCleanedEmbeddingOptions(options)))}${hash}" width="100%" height="600px" frameborder="0" style="outline: none;"/>`}
</code>
</pre>
</fieldset>

View File

@@ -10,7 +10,7 @@
<Button
variant="ghost"
class="absolute top-0 flex-wrap h-fit bg-background font-semibold rounded-md py-1 px-2 gap-1.5 xs:text-base mt-2.5 ml-2.5 mr-12"
href="{getURLForLanguage($locale, '/embed')}?files={encodeURIComponent(JSON.stringify(files))}"
href="{getURLForLanguage($locale, '/app')}?files={encodeURIComponent(JSON.stringify(files))}"
target="_blank"
>
{$_('menu.open_in')}