Consolidate and upload changes from recent work
This commit is contained in:
parent
05a69bf274
commit
da2e46aab2
20 changed files with 1844 additions and 1566 deletions
200
src/components/Asset.tsx
Normal file
200
src/components/Asset.tsx
Normal file
|
@ -0,0 +1,200 @@
|
|||
import {
|
||||
faMagnifyingGlassMinus,
|
||||
faMagnifyingGlassPlus,
|
||||
faSlidersSimple,
|
||||
faVolume,
|
||||
faVolumeSlash,
|
||||
faXmark,
|
||||
} from "@fortawesome/pro-regular-svg-icons";
|
||||
import {
|
||||
Match,
|
||||
Setter,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createSignal,
|
||||
} from "solid-js";
|
||||
import { FontAwesomeIcon } from "./FontAwesomeIcon";
|
||||
|
||||
interface Asset {
|
||||
src: string;
|
||||
}
|
||||
|
||||
function AssetHandler() {
|
||||
const [moving, setMoving] = createSignal(false);
|
||||
const [active, setActive] = createSignal("");
|
||||
const [zoomLevel, setZoomLevel] = createSignal(0);
|
||||
const zoomAmount = () => 1 + zoomLevel() * 0.5;
|
||||
const [x, setX] = createSignal(0);
|
||||
const [y, setY] = createSignal(0);
|
||||
|
||||
function FullscreenView() {
|
||||
const [muted, setMuted] = createSignal(true);
|
||||
const [controlls, setControlls] = createSignal(false);
|
||||
const [clientX, setClientX] = createSignal(0);
|
||||
const [clientY, setClientY] = createSignal(0);
|
||||
const [ref, setRef] = createSignal<HTMLElement | null>(null);
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
const { clientX, clientY } = event;
|
||||
setClientX(clientX);
|
||||
setClientY(clientY);
|
||||
};
|
||||
|
||||
createEffect(() => {
|
||||
const thisRef = ref();
|
||||
if (!thisRef) return;
|
||||
const rectA = thisRef.getBoundingClientRect();
|
||||
const origSizeW = rectA.width / zoomAmount();
|
||||
const origSizeH = rectA.height / zoomAmount();
|
||||
const rectW = wrapperRef.getBoundingClientRect();
|
||||
const hori = rectW.width - origSizeW + origSizeW / zoomAmount();
|
||||
const verti = rectW.height - origSizeH + origSizeH / zoomAmount();
|
||||
const xP = (clientX() - hori / 2) / (rectW.width - hori);
|
||||
const yP = (clientY() - verti / 2) / (rectW.height - verti);
|
||||
setX((xP > 0 ? (xP < 1 ? xP : 1) : 0) * origSizeW);
|
||||
setY((yP > 0 ? (yP < 1 ? yP : 1) : 0) * origSizeH);
|
||||
const moving =
|
||||
clientX() > (rectW.width - origSizeW) / 2 &&
|
||||
clientX() < rectW.width - (rectW.width - origSizeW) / 2 &&
|
||||
clientY() > (rectW.height - origSizeH) / 2 &&
|
||||
clientY() < rectW.height - (rectW.height - origSizeH) / 2;
|
||||
setMoving(moving);
|
||||
});
|
||||
|
||||
let wrapperRef: HTMLDivElement;
|
||||
|
||||
createEffect(() => {
|
||||
if (active()) return;
|
||||
setZoomLevel(0);
|
||||
setMuted(true);
|
||||
setControlls(false);
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={wrapperRef!}
|
||||
onMouseMove={handleMouseMove}
|
||||
classList={{ "fullscreen-asset": true, active: !!active() }}
|
||||
>
|
||||
<Asset
|
||||
src={active()}
|
||||
volume={!muted()}
|
||||
controlls={controlls()}
|
||||
setRef={setRef}
|
||||
/>
|
||||
<div class="controlls">
|
||||
<button onClick={() => setActive("")} title="Close">
|
||||
<FontAwesomeIcon icon={faXmark} />
|
||||
</button>
|
||||
<Show when={active().startsWith("/videos")}>
|
||||
<button
|
||||
onClick={() => setMuted((e) => !e)}
|
||||
style={{ "border-style": controlls() ? "dashed" : "" }}
|
||||
title={muted() ? "Unmute" : "Mute"}
|
||||
>
|
||||
<FontAwesomeIcon icon={!muted() ? faVolume : faVolumeSlash} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setControlls((e) => !e)}
|
||||
style={{ "border-style": controlls() ? "inset" : "" }}
|
||||
title="Show controlls"
|
||||
>
|
||||
<FontAwesomeIcon icon={faSlidersSimple} />
|
||||
</button>
|
||||
</Show>
|
||||
<button
|
||||
onClick={() => setZoomLevel((e) => e + 1)}
|
||||
disabled={zoomLevel() === 4}
|
||||
title="Zoom +"
|
||||
>
|
||||
<FontAwesomeIcon icon={faMagnifyingGlassPlus} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setZoomLevel((e) => e - 1)}
|
||||
disabled={zoomLevel() === 0}
|
||||
title="Zoom -"
|
||||
>
|
||||
<FontAwesomeIcon icon={faMagnifyingGlassMinus} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Asset(
|
||||
props: Asset & {
|
||||
class?: string;
|
||||
volume?: boolean;
|
||||
controlls?: boolean;
|
||||
setRef?: Setter<HTMLElement | null>;
|
||||
},
|
||||
) {
|
||||
let imgRef: HTMLImageElement;
|
||||
let videoRef: HTMLVideoElement;
|
||||
|
||||
const shouldZoom = () => active() === props.src && !!zoomLevel();
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Match when={props.src.startsWith("/images")}>
|
||||
<img
|
||||
ref={imgRef!}
|
||||
style={
|
||||
shouldZoom()
|
||||
? {
|
||||
"--zoom": zoomAmount(),
|
||||
"--x": x() + "px",
|
||||
"--y": y() + "px",
|
||||
}
|
||||
: {}
|
||||
}
|
||||
onMouseEnter={() => props.setRef && props.setRef(imgRef)}
|
||||
classList={{
|
||||
[props.class ?? ""]: !!props.class,
|
||||
zoomed: shouldZoom(),
|
||||
move: moving(),
|
||||
}}
|
||||
onClick={() => setActive(props.src)}
|
||||
src={props.src}
|
||||
alt={props.src}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={props.src.startsWith("/videos")}>
|
||||
<video
|
||||
ref={videoRef!}
|
||||
onMouseEnter={() => props.setRef && props.setRef(videoRef)}
|
||||
style={
|
||||
shouldZoom()
|
||||
? {
|
||||
"--zoom": zoomAmount(),
|
||||
"--x": x() + "px",
|
||||
"--y": y() + "px",
|
||||
}
|
||||
: {}
|
||||
}
|
||||
classList={{
|
||||
[props.class ?? ""]: !!props.class,
|
||||
zoomed: shouldZoom(),
|
||||
move: moving(),
|
||||
active: !props.setRef && active() === props.src,
|
||||
}}
|
||||
onClick={() => setActive(props.src)}
|
||||
width="auto"
|
||||
height="auto"
|
||||
autoplay
|
||||
muted={!props.volume}
|
||||
loop
|
||||
controls={props.controlls}
|
||||
>
|
||||
<source src={props.src} type="video/mp4" />
|
||||
</video>
|
||||
</Match>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
return { FullscreenView, Asset };
|
||||
}
|
||||
|
||||
export default AssetHandler;
|
|
@ -4,17 +4,15 @@ import { A } from "solid-start";
|
|||
function DeviceTile(props: { href?: string; name: string; src: string }) {
|
||||
return (
|
||||
<A href={props.href ?? "/soon"}>
|
||||
<div class="raster">
|
||||
<h3>{props.name}</h3>
|
||||
<Show when={props.src.startsWith("/images")}>
|
||||
<img src={props.src} alt={props.name} />
|
||||
</Show>
|
||||
<Show when={props.src.startsWith("/videos")}>
|
||||
<video width="auto" height="auto" autoplay muted loop>
|
||||
<source src={props.src} type="video/mp4" />
|
||||
</video>
|
||||
</Show>
|
||||
</div>
|
||||
<h3>{props.name}</h3>
|
||||
<Show when={props.src.startsWith("/images")}>
|
||||
<img src={props.src} alt={props.name} />
|
||||
</Show>
|
||||
<Show when={props.src.startsWith("/videos")}>
|
||||
<video width="auto" height="auto" autoplay muted loop>
|
||||
<source src={props.src} type="video/mp4" />
|
||||
</video>
|
||||
</Show>
|
||||
</A>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ function R(props: {
|
|||
target={type() === "external" ? "_blank" : ""}
|
||||
rel={type() === "external" ? "noreferrer noopener" : ""}
|
||||
id={props.id}
|
||||
class={props.class}
|
||||
classList={{ reference: true, [props.class ?? ""]: !!props.class }}
|
||||
>
|
||||
<Show when={type() === "id"}>
|
||||
<FontAwesomeIcon class="left" icon={types["id"]} />
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {
|
||||
faBars,
|
||||
faBookOpen,
|
||||
faCircleHalfStroke,
|
||||
faGavel,
|
||||
faGlobe,
|
||||
faXmark,
|
||||
} from "@fortawesome/pro-regular-svg-icons";
|
||||
|
@ -75,7 +77,7 @@ function Navbar() {
|
|||
<A href="/de/overview#historie">Historie</A>
|
||||
</li>
|
||||
<li>
|
||||
<A href="/de/overview#geräte">Geräte Liste</A>
|
||||
<A href="/de/overview#geraete">Geräte Liste</A>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
@ -83,6 +85,10 @@ function Navbar() {
|
|||
<FontAwesomeIcon icon={faBookOpen} /> Hersteller
|
||||
</A>
|
||||
|
||||
<A href="/de/imprint">
|
||||
<FontAwesomeIcon icon={faGavel} /> Impressum
|
||||
</A>
|
||||
|
||||
<button onClick={() => setLightMode((e) => !e)}>
|
||||
{lightMode() ? "Dark Mode " : "Light Mode "}
|
||||
<FontAwesomeIcon icon={faCircleHalfStroke} />
|
||||
|
@ -99,14 +105,9 @@ function Navbar() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="sidenavbar"
|
||||
style={{ visibility: menu() ? "hidden" : "visible" }}
|
||||
>
|
||||
<button onClick={() => navigate(-1)}>Zurück</button>
|
||||
<button onClick={() => navigate("/de/overview")}>Start</button>
|
||||
<button onClick={() => setMenu(true)}>Menu</button>
|
||||
</div>
|
||||
<button class="menu" title="Menu" onClick={() => setMenu(true)}>
|
||||
<FontAwesomeIcon icon={faBars} />
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {
|
||||
faBars,
|
||||
faBookOpen,
|
||||
faCircleHalfStroke,
|
||||
faGavel,
|
||||
faGlobe,
|
||||
faXmark,
|
||||
} from "@fortawesome/pro-regular-svg-icons";
|
||||
|
@ -75,7 +77,7 @@ function Navbar() {
|
|||
<A href="/en/overview#historie">History</A>
|
||||
</li>
|
||||
<li>
|
||||
<A href="/en/overview#geräte">Device list</A>
|
||||
<A href="/en/overview#geraete">Device list</A>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
@ -83,6 +85,10 @@ function Navbar() {
|
|||
<FontAwesomeIcon icon={faBookOpen} /> Manufacturers
|
||||
</A>
|
||||
|
||||
<A href="/de/imprint">
|
||||
<FontAwesomeIcon icon={faGavel} /> Legal Notice (DE)
|
||||
</A>
|
||||
|
||||
<button onClick={() => setLightMode((e) => !e)}>
|
||||
{lightMode() ? "Dark Mode " : "Light Mode "}
|
||||
<FontAwesomeIcon icon={faCircleHalfStroke} />
|
||||
|
@ -99,14 +105,9 @@ function Navbar() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="sidenavbar"
|
||||
style={{ visibility: menu() ? "hidden" : "visible" }}
|
||||
>
|
||||
<button onClick={() => navigate(-1)}>Back</button>
|
||||
<button onClick={() => navigate("/en/overview")}>Start</button>
|
||||
<button onClick={() => setMenu(true)}>Menu</button>
|
||||
</div>
|
||||
<button class="menu" title="Menu" onClick={() => setMenu(true)}>
|
||||
<FontAwesomeIcon icon={faBars} />
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue