Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed src/assets/logos/envalior.png
Binary file not shown.
1 change: 1 addition & 0 deletions src/assets/logos/envalior.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 12 additions & 32 deletions src/components/Companies.astro
Original file line number Diff line number Diff line change
@@ -1,36 +1,24 @@
---
import { getImage } from 'astro:assets';
import type { SvgComponent } from 'astro/types';

import { companies } from '../data/profile';

// SVG logos are inlined, so their currentColor parts follow the theme. A PNG
// logo is single-colour; it is used as a mask over currentColor instead, which
// renders it the same way.
const logos = await Promise.all(
companies.map(async ({ name, src, height, ink }) => {
const width = Math.round((height * src.width) / src.height);
const style = `--h: ${height}px; --w: ${width}px; ${ink ? `--ink: ${ink};` : ''}`;
if (src.format === 'svg') {
return { name, style, Svg: src as unknown as SvgComponent };
}
const mask = await getImage({ src, height: height * 2, format: 'webp' });
return { name, style: `${style} --mask: url(${mask.src});` };
}),
);
// The logos are inlined SVGs, so their currentColor parts follow the theme and
// they appear with the page, without a request of their own.
const logos = companies.map(({ name, src, height, ink }) => {
const width = Math.round((height * src.width) / src.height);
const style = `--h: ${height}px; --w: ${width}px; ${ink ? `--ink: ${ink};` : ''}`;
return { name, style, Svg: src as unknown as SvgComponent };
});
---

<div class="companies">
<div class="wrap">
<p class="label">Experience with</p>
<ul class="logos">
<p class="label reveal">Experience with</p>
<ul class="logos reveal">
{logos.map(({ name, style, Svg }) => (
<li style={style}>
{Svg ? (
<Svg role="img" aria-label={name} />
) : (
<span class="mask" role="img" aria-label={name} />
)}
<Svg role="img" aria-label={name} />
</li>
))}
</ul>
Expand Down Expand Up @@ -77,18 +65,11 @@ const logos = await Promise.all(
color: var(--text);
}

.logos :global(svg),
.mask {
.logos :global(svg) {
height: var(--h);
width: var(--w);
}

.mask {
display: block;
background: currentColor;
mask: var(--mask) center / contain no-repeat;
}

@media (max-width: 920px) {
.wrap {
grid-template-columns: 1fr;
Expand All @@ -103,8 +84,7 @@ const logos = await Promise.all(
gap: 22px 30px;
}

.logos :global(svg),
.mask {
.logos :global(svg) {
height: calc(var(--h) * 0.75);
width: calc(var(--w) * 0.75);
}
Expand Down
7 changes: 5 additions & 2 deletions src/data/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import psm1 from '../assets/badges/psm1.png';
import cbtw from '../assets/logos/cbtw.svg';
import cronos from '../assets/logos/cronos.svg';
import deloitte from '../assets/logos/deloitte.svg';
import envalior from '../assets/logos/envalior.png';
import envalior from '../assets/logos/envalior.svg';
import imec from '../assets/logos/imec.svg';
import partenamut from '../assets/logos/partenamut.svg';

Expand Down Expand Up @@ -47,7 +47,10 @@ export const person = {
*/
export interface Logo {
name: string;
/** An SVG, inlined; or a single-colour PNG, used as a mask. */
/**
* An SVG, inlined. A logo only available as a single-colour PNG is wrapped
* in one, as a mask over a currentColor rectangle (see envalior.svg).
*/
src: ImageMetadata;
/** Display height in pixels on large screens; logos differ in proportions. */
height: number;
Expand Down
Loading