Skip to content

Instantly share code, notes, and snippets.

@snuffyDev
Created March 28, 2023 14:06
Show Gist options
  • Select an option

  • Save snuffyDev/505b9670946cc29e89bdc2a341d16dc0 to your computer and use it in GitHub Desktop.

Select an option

Save snuffyDev/505b9670946cc29e89bdc2a341d16dc0 to your computer and use it in GitHub Desktop.
<svelte:options accessors={true} />
<script context="module" lang="ts">
export const DIRECTION_MAP: Record<string, number> = {
front: 180,
left: 90,
back: 0,
right: 270
};
import type { Position } from '$lib/types/position';
import { objectEntries } from '$lib/utils/object';
import { isValidTexture } from '$lib/utils/validation';
import { getContext, onMount } from 'svelte';
import { ctxKey, type TextureContext } from '../../routes/key';
import type { MapItem, Texture } from '../utils/map';
function getPositionFrom({ x, z }: { x: number; z: number }) {
return {
x: (x * -15000) / 150,
z: (z * -15000) / 150
};
}
</script>
<script lang="ts">
export let offset = 0;
export let section = 0;
export let height = 100;
export let item: MapItem;
const position = getPositionFrom({ x: offset, z: section });
let isVisible = true;
/** Position for the component instance */
export const getPosition = () => position;
/** Returns the localPosition ()`offset` and `section`) of the component within the level */
export const getLocalPosition = (): Omit<Position, 'y'> => ({ x: offset, z: section });
/** Returns the visibility state */
export const getVisibility = () => isVisible;
/** Sets the visibility state */
export const setVisibility = (visible: boolean) => (isVisible = visible);
/** Returns an array of each wall face */
export const sides: ([direction: string, texture: Texture] | null)[] = Object.entries(
item?.surfaces ?? {}
).map(([k, v]) => (v !== ' ' ? [k, v] : null));
/** Returns an array of DOM elements for each wall face */
export const boundSides: HTMLDivElement[] = [];
const { textures }: TextureContext = getContext(ctxKey);
const getZPosition = (direction: 'front' | 'left' | 'right' | 'back') => {
switch (direction) {
case 'front':
return -position.z - 50;
case 'back':
return -position.z + 50;
case 'left':
case 'right':
return -position.z - 50;
}
};
</script>
<div class="surface">
{#each objectEntries(item?.surfaces) as [direction, texture], i}
{#if direction && texture && typeof texture === 'string'}
{@const positionZ = getZPosition(direction)}
{@const validatedTexture = isValidTexture(texture) ? $textures[texture]?.original : ''}
{@const img = ` --img: url(${validatedTexture});`}
<div
class="wall {direction}"
bind:this={boundSides[i]}
data-x={-position.x}
data-z={positionZ}
data-rotation={DIRECTION_MAP[direction]}
style="--height: {height}px; {img} transform: translate3d({-position.x}px, -50%, {positionZ}px) rotateY({DIRECTION_MAP[
direction
]}deg);"
/>
{/if}
{/each}
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment