Files for my website bwc9876.dev
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Better project cards

Ben C 995737ce d65209e2

+18 -40
+18 -40
src/components/projects/ProjectCard.astro
··· 1 1 --- 2 + import { getImage } from "astro:assets"; 2 3 import { Image } from "astro:assets"; 3 - import backdrop from "@assets/backdrop.webp"; 4 4 import type { CollectionEntry } from "astro:content"; 5 5 6 6 export interface Props { 7 7 project: CollectionEntry<"projects">; 8 8 } 9 9 10 - const stringToNumber = (str: string, seed = 3) => { 11 - let h1 = 0xdeadbeef ^ seed, 12 - h2 = 0x41c6ce57 ^ seed; 13 - for (let i = 0, ch; i < str.length; i++) { 14 - ch = str.charCodeAt(i); 15 - h1 = Math.imul(h1 ^ ch, 2654435761); 16 - h2 = Math.imul(h2 ^ ch, 1597334677); 17 - } 18 - h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909); 19 - h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909); 20 - return 4294967296 * (2097151 & h2) + (h1 >>> 0); 21 - }; 10 + const { project } = Astro.props; 22 11 23 - const getHueFromText = (text: string): string => `hue-rotate(${stringToNumber(text) % 360}deg)`; 24 - 25 - const { project } = Astro.props; 12 + const bgImage = await getImage({ 13 + format: "webp", 14 + src: project.data.image, 15 + width: 16, 16 + height: 16, 17 + quality: 0 18 + }); 26 19 --- 27 20 28 21 <a href={`/projects/${project.id}/`}> 29 22 <article> 30 - <div> 23 + <div style={{ "background-image": `url("${bgImage.src}")` }}> 31 24 <Image 32 25 class="thumbnail" 33 26 transition:name={`project-img-${project.id}`} 34 27 src={project.data.image} 35 28 densities={[1, 1.5, 2]} 36 - width="400" 37 - alt="" 38 - /> 39 - <Image 40 - style={{ filter: getHueFromText(project.id) }} 41 - class="backdrop" 42 - aria-hidden="true" 29 + width={400} 43 30 role="presentation" 44 - src={backdrop} 45 - alt="Backdrop" 31 + alt="" 46 32 /> 47 33 </div> 48 34 <div> ··· 86 72 } 87 73 88 74 a:hover { 89 - transform: translateY(calc(var(--1) * -1)); 75 + transform: translateY(calc(5px * -1)); 90 76 } 91 77 92 78 a:hover img { 93 - transform: scale(1.06); 79 + transform: scale(1.02); 94 80 } 95 81 96 82 span { ··· 105 91 display: flex; 106 92 flex-direction: column; 107 93 align-items: center; 94 + background-repeat: no-repeat; 95 + background-size: 125%; 96 + background-position: center; 108 97 } 109 98 110 99 div { ··· 125 114 height: auto; 126 115 transition: transform ease-in-out 0.4s; 127 116 height: var(--14); 128 - } 129 - 130 - img.thumbnail { 131 - z-index: 2; 132 - } 133 - 134 - img.backdrop { 135 - position: absolute; 136 - transform: scale(1.1); 137 - inset: 0; 138 - object-fit: cover; 139 - filter: blur(6px); 117 + backdrop-filter: blur(100px); 140 118 } 141 119 </style>