updated image optimisation, updated readme accrodingly. fixed image issues, fixed navbar on mobile view + more

This commit is contained in:
Henri
2026-04-23 15:48:34 +03:00
parent 08d6e08c4d
commit 63c4960062
154 changed files with 1141 additions and 312 deletions

View File

@@ -5,6 +5,7 @@
} from "$components";
import { onMount, onDestroy } from "svelte";
import { createPageTextStore } from "$lib";
import { getHeroImageFallback, getHeroImageSrcSet, getRootAssetPath } from "$lib/imageHelpers.js";
import yaml from 'js-yaml';
import { MapLibre, Marker } from "svelte-maplibre";
@@ -13,8 +14,9 @@
import { navigate } from "$lib/router/router.js";
// Images
const helpdeskbg = "/assets/helpdesk/helpdesk_bg.jpg";
const helpdesk = "/assets/helpdesk/helpdesk-on-black.png";
const helpdeskbg = getHeroImageFallback("helpdesk-page-images", "helpdesk_bg");
const helpdeskbgWebpSet = getHeroImageSrcSet("helpdesk-page-images", "helpdesk_bg");
const helpdesk = getRootAssetPath("helpdesk-page-images", "helpdesk-on-black.png");
// Coordinates for Akadeemia tee 5, 12616 Tallinn [longitude, latitude]
const center = [24.66887400515207, 59.396427975093935];
@@ -24,13 +26,17 @@
const tehnikaBusStop = [24.67328945396854, 59.39508874042947];
// Google Maps directions URL
const getDirectionsUrl = (lng, lat) => {
const getDirectionsUrl = (lng, lat, loc) => {
if (loc == "bus"){
return `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}&travelmode=transit`;
}
return `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}`;
};
// Navigate to directions using router
const openDirections = (lng, lat) => {
navigate(getDirectionsUrl(lng, lat), { external: true });
const openDirections = (lng, lat, loc) => {
navigate(getDirectionsUrl(lng, lat, loc), { external: true });
};
// Load pricing data
@@ -54,11 +60,14 @@
<div class="flex absolute justify-center items-center flex-row w-full h-[42vh] px-4">
<img src={helpdesk} alt={$text["hero"]?.title || "Helpdesk logo"} class="z-10" />
</div>
<img
class="h-[42vh] object-cover object-left w-full opacity-50 blur-[1.5px]"
src={helpdeskbg}
alt="Helpdesk"
/>
<picture>
<source srcset={helpdeskbgWebpSet} type="image/webp" />
<img
class="h-[42vh] object-cover object-left w-full opacity-50 blur-[1.5px]"
src={helpdeskbg}
alt="Helpdesk"
/>
</picture>
</div>
<!-- Main Content -->
@@ -159,8 +168,8 @@
<div
role="button"
tabindex="0"
onclick={() => openDirections(keemiaBusStop[0], keemiaBusStop[1])}
onkeydown={(e) => (e.key === 'Enter' || e.key === ' ') && openDirections(keemiaBusStop[0], keemiaBusStop[1])}
onclick={() => openDirections(keemiaBusStop[0], keemiaBusStop[1], "bus")}
onkeydown={(e) => (e.key === 'Enter' || e.key === ' ') && openDirections(keemiaBusStop[0], keemiaBusStop[1], "bus")}
class="flex flex-col items-center hover:scale-110 transition-transform cursor-pointer"
title="Get directions to Keemia bus stop"
>
@@ -174,8 +183,8 @@
<div
role="button"
tabindex="0"
onclick={() => openDirections(tehnikaBusStop[0], tehnikaBusStop[1])}
onkeydown={(e) => (e.key === 'Enter' || e.key === ' ') && openDirections(tehnikaBusStop[0], tehnikaBusStop[1])}
onclick={() => openDirections(tehnikaBusStop[0], tehnikaBusStop[1], "bus")}
onkeydown={(e) => (e.key === 'Enter' || e.key === ' ') && openDirections(tehnikaBusStop[0], tehnikaBusStop[1], "bus")}
class="flex flex-col items-center hover:scale-110 transition-transform cursor-pointer"
title="Get directions to Tehnikaülikool bus stop"
>

View File

@@ -2,6 +2,7 @@
import {Section, Stack, Grid, Center, Image, Svg, Button} from "$components";
import { navigate } from "$lib/router/router.js";
import { createPageTextStore, currentLang } from "$lib";
import { getHeroImagePath, getHeroImageSrcSet, getHeroImageFallback, getOptimisedImagePath, getOptimisedImageFallback } from "$lib/imageHelpers.js";
import { onMount, onDestroy } from "svelte";
import yaml from 'js-yaml';
@@ -21,6 +22,19 @@
onDestroy(() => {
text.destroy();
});
const partnerLogoExtByName = {
taltech_logo: "jpg",
eas: "svg",
hextech_logo: "svg",
};
function getPartnerLogoPath(name) {
if (!name) return "";
if (name.includes(".")) return `/assets/partners/${name}`;
const ext = partnerLogoExtByName[name] || "png";
return `/assets/partners/${name}.${ext}`;
}
</script>
<!-- Hero Section -->
@@ -28,7 +42,9 @@
<div class="relative min-h-screen flex items-center">
<div class="absolute inset-0 left-1/2 w-screen -translate-x-1/2" aria-hidden="true">
<Image
src="/assets/home-page-images/hero.jpg"
webpSrc={getHeroImagePath("home-page-images", "hero")}
src={getHeroImageFallback("home-page-images", "hero")}
webpSrcSet={getHeroImageSrcSet("home-page-images", "hero")}
alt={$text["hero"]?.imageAlt || "illustrative hero image"}
objectFit="cover"
class="w-full h-full"
@@ -88,8 +104,8 @@
<Center dir="col" class="w-full max-w-sm justify-start mx-auto">
<div class="w-[min(72vw,240px)] md:w-[min(26vw,280px)] lg:w-[min(23vw,300px)] aspect-square rounded-full overflow-hidden">
<Image
src="/assets/student-images/image_1.jpg"
webpSrc=""
webpSrc={getOptimisedImagePath("home-page-images", "student_temp", "webp")}
src={getOptimisedImageFallback("home-page-images", "student_temp")}
alt={$text["services"]?.student?.imageAlt || "Tudengile Pilt"}
objectFit="cover"
class="w-full h-full rounded-full object-[center_35%]"
@@ -103,8 +119,8 @@
<Center dir="col" class="w-full max-w-sm justify-start mx-auto">
<div class="w-[min(72vw,240px)] md:w-[min(26vw,280px)] lg:w-[min(23vw,300px)] aspect-square rounded-full overflow-hidden">
<Image
src="/assets/helpdesk/helpdesk_bg.jpg"
webpSrc=""
webpSrc={getOptimisedImagePath("home-page-images", "helpdesk", "webp")}
src={getOptimisedImageFallback("home-page-images", "helpdesk")}
alt={$text["services"]?.helpdesk?.imageAlt || "Helpdesk Pilt"}
objectFit="cover"
class="w-full h-full rounded-full object-[center_38%]"
@@ -118,8 +134,8 @@
<Center dir="col" class="w-full max-w-sm justify-start mx-auto md:col-span-2 lg:col-span-1">
<div class="w-[min(72vw,240px)] md:w-[min(26vw,280px)] lg:w-[min(23vw,300px)] aspect-square rounded-full overflow-hidden">
<Image
src="/assets/asi-karikas-2023-images/miina_harma.jpeg"
webpSrc=""
webpSrc={getOptimisedImagePath("home-page-images", "company_temp", "webp")}
src={getOptimisedImageFallback("home-page-images", "company_temp")}
alt={$text["services"]?.company?.imageAlt || "Ettevõttele Pilt"}
objectFit="cover"
class="w-full h-full rounded-full object-[center_25%]"
@@ -185,7 +201,8 @@
<div class="relative overflow-hidden min-h-90 md:h-full md:self-stretch">
<div class="absolute inset-0">
<Image
src="/assets/home-page-images/about_us.png"
webpSrc={getOptimisedImagePath("home-page-images", "about_us", "webp")}
src={getOptimisedImageFallback("home-page-images", "about_us")}
alt={$text["aboutSection"]?.imageAlt || "Lapikud team"}
objectFit="cover"
class="h-full w-full max-w-none!"
@@ -284,7 +301,8 @@
<div class="relative overflow-hidden min-h-90 md:min-h-0 md:h-full md:self-stretch">
<div class="absolute inset-0">
<Image
src="/assets/home-page-images/temp.png"
webpSrc={getOptimisedImagePath("home-page-images", "temp", "webp")}
src={getOptimisedImageFallback("home-page-images", "temp")}
alt={$text["whatWeDo"]?.imageAlt || "Lapikud parandamas riistvara"}
objectFit="cover"
class="h-full w-full max-w-none!"
@@ -349,11 +367,10 @@
title={partner.name}
>
{#if partner.image}
<Image
src={`/assets/partners/${partner.image}`}
<img
src={getPartnerLogoPath(partner.image)}
alt={partner.name}
objectFit="contain"
class="w-auto max-h-[150px] transition-all duration-300"
class="w-auto max-h-[150px] transition-all duration-300 object-contain"
/>
{:else}
<span class="font-semibold text-center">{partner.name}</span>
@@ -362,11 +379,10 @@
{:else}
<div class="flex h-[170px] items-center justify-center p-3 transition-all duration-300">
{#if partner.image}
<Image
src={`/assets/partners/${partner.image}`}
<img
src={getPartnerLogoPath(partner.image)}
alt={partner.name}
objectFit="contain"
class="w-auto max-h-[150px] transition-all duration-300"
class="w-auto max-h-[150px] transition-all duration-300 object-contain"
/>
{:else}
<span class="font-semibold text-center">{partner.name}</span>

View File

@@ -8,6 +8,7 @@
import { onMount, onDestroy } from "svelte";
import yaml from "js-yaml";
import { currentLang, getLangText, createPageTextStore } from "$lib";
import { getOptimisedImagePath, getOptimisedImageFallback } from "$lib/imageHelpers.js";
import Mail from "lucide-svelte/icons/mail";
import Phone from "lucide-svelte/icons/phone";
@@ -92,11 +93,14 @@
{#each currentManagement as member (member.name)}
<div class="flex flex-col sm:flex-row gap-6 items-start">
<div class="w-full sm:w-auto sm:max-w-[200px] aspect-square shrink-0">
<img
src={`/assets/management-images/${member.photo}`}
alt={member.name}
class="w-full h-full object-cover rounded-md"
/>
<picture>
<source srcset={getOptimisedImagePath("management-images", member.photo, "webp")} type="image/webp" />
<img
src={getOptimisedImageFallback("management-images", member.photo)}
alt={member.name}
class="w-full h-full object-cover rounded-md"
/>
</picture>
</div>
<div class="flex flex-col gap-2 grow">
<h3 class="text-2xl font-medium">{member.name}</h3>
@@ -153,7 +157,8 @@
<div class="h-24 w-24 overflow-hidden rounded-[10px] bg-linear-to-br outline-2 outline-transparent outline-offset-2 transition [@media(min-width:769px)]:h-28 [@media(min-width:769px)]:w-28">
{#if member.image}
<Image
src={`/assets/past-management-images/optimised/${member.image}`}
webpSrc={getOptimisedImagePath("past-management-images", member.image, "webp")}
src={getOptimisedImageFallback("past-management-images", member.image)}
alt={member.name}
objectFit="cover"
class="block h-full w-full"

View File

@@ -3,6 +3,7 @@
import { onMount, onDestroy } from "svelte";
import yaml from "js-yaml";
import { currentLang, getLangText, createPageTextStore } from "$lib";
import { getOptimisedImagePath, getOptimisedImageFallback } from "$lib/imageHelpers.js";
import Mail from "lucide-svelte/icons/mail";
import Phone from "lucide-svelte/icons/phone";
@@ -82,16 +83,14 @@
<!-- Mentor Photo -->
{#if mentor.photo}
<div class="shrink-0">
<img
src={`/assets/mentors-images/optimised/${mentor.photo}`}
alt={mentor.name}
class="w-full md:w-48 h-48 object-cover"
on:error={(e) => {
e.target.src =
"/assets/mentors-images/original/" +
mentor.photo;
}}
/>
<picture>
<source srcset={getOptimisedImagePath("mentors-images", mentor.photo, "webp")} type="image/webp" />
<img
src={getOptimisedImageFallback("mentors-images", mentor.photo)}
alt={mentor.name}
class="w-full md:w-48 h-48 object-cover"
/>
</picture>
</div>
{/if}

View File

@@ -3,6 +3,7 @@
import { onMount, onDestroy } from "svelte";
import yaml from "js-yaml";
import { currentLang, getLangText, createPageTextStore } from "$lib";
import { getOptimisedImagePath, getOptimisedImageFallback } from "$lib/imageHelpers.js";
import ExternalLink from "lucide-svelte/icons/external-link";
@@ -33,12 +34,12 @@
function projectImage(project) {
return project?.photo
? `/assets/ourwork-images/optimised/${project.photo}`
? getOptimisedImagePath("ourwork-images", project.photo, "webp")
: "";
}
function handleImageError(event, photo) {
event.currentTarget.src = `/assets/ourwork-images/original/${photo}`;
event.currentTarget.src = getOptimisedImageFallback("ourwork-images", photo);
}
function openCtaEmail() {

View File

@@ -3,6 +3,7 @@
import { onMount, onDestroy } from "svelte";
import yaml from "js-yaml";
import { currentLang, getLangText, createPageTextStore } from "$lib";
import { getRootAssetPath } from "$lib/imageHelpers.js";
let workshops = [];
const text = createPageTextStore("Workshops");
@@ -81,7 +82,7 @@
class={`overflow-hidden ${getImageHeightClass(getGallery(workshop).length, i)}`}
>
<Image
src={`/assets/workshops/${filename}`}
src={getRootAssetPath("workshop-images", filename, "jpg")}
alt={`${getField(workshop, "title")} ${i + 1}`}
objectFit="cover"
class="h-full w-full"