Commit 3fc1b18
Changed files (5)
src
components
utils
widgets
types
src/components/utils/ImageWrapper.astro
@@ -0,0 +1,59 @@
+---
+import { url } from '@utils/url-utils';
+import type { ImageMetadata } from 'astro';
+import { Image } from 'astro:assets';
+import path from 'path';
+interface Props {
+ id?: string;
+ src: string;
+ class?: string;
+ alt?: string;
+ position?: string;
+ basePath?: string;
+}
+
+const { id, src, alt, position = 'center', basePath = '/' } = Astro.props;
+const className = Astro.props.class;
+
+const isLocal = !(
+ src.startsWith('/') ||
+ src.startsWith('http') ||
+ src.startsWith('https') ||
+ src.startsWith('data:')
+);
+const isPublic = src.startsWith('/');
+
+let img;
+if (isLocal) {
+ const files = import.meta.glob<ImageMetadata>('../../**', {
+ import: 'default',
+ });
+ let normalizedPath = path.normalize(path.join('../../', basePath, src)).replace(/\\/g, '/');
+ const file = files[normalizedPath];
+ if (!file) {
+ console.error(
+ `\n[ERROR] Image file not found: ${normalizedPath.replace('../../', 'src/')}`
+ );
+ }
+ img = await file();
+}
+
+const imageClass = 'w-full h-full object-cover';
+const imageStyle = `object-position: ${position}`;
+---
+
+<div id={id} class:list={[className, 'relative overflow-hidden']}>
+ <div class="pointer-events-none absolute inset-0 bg-opacity-50 transition dark:bg-black/10">
+ </div>
+ {isLocal && img && <Image src={img} alt={alt || ''} class={imageClass} style={imageStyle} />}
+ {
+ !isLocal && (
+ <img
+ src={isPublic ? url(src) : src}
+ alt={alt || ''}
+ class={imageClass}
+ style={imageStyle}
+ />
+ )
+ }
+</div>
src/components/widgets/PostCardCover.astro
@@ -1,6 +1,6 @@
---
+import ImageWrapper from '@components/utils/ImageWrapper.astro';
import { Icon } from 'astro-icon/components';
-import { Image } from 'astro:assets';
interface Props {
url: string;
@@ -15,7 +15,7 @@ const { url, title, cover } = Astro.props;
<div>
<Icon name="material-symbols:chevron-right-rounded" />
</div>
- <Image src={cover} alt={title} inferSize={true} />
+ <ImageWrapper src={cover} alt={title} />
</a>
<style>
src/components/widgets/ProfileCard.astro
@@ -1,17 +1,6 @@
---
import { profileConfig } from '@/config';
-import avatarImg from '@assets/img/avatar.jpg';
-import { Image } from 'astro:assets';
-
-const avaterAttr = profileConfig.avatar
- ? {
- src: profileConfig.avatar,
- alt: profileConfig.name,
- inferSize: true,
- width: 800,
- height: 800,
- }
- : { src: avatarImg, alt: profileConfig.name };
+import ImageWrapper from '@components/utils/ImageWrapper.astro';
---
<div
@@ -21,7 +10,11 @@ const avaterAttr = profileConfig.avatar
>
<div class="m-3 w-fit min-w-20">
<a href="/about/">
- <Image class="theme-border h-20 w-20 rounded-full border-4" {...avaterAttr} />
+ <ImageWrapper
+ class="theme-border h-20 w-20 rounded-full border-4"
+ src={profileConfig.avatar}
+ alt={profileConfig.name}
+ />
</a>
</div>
<div class="mx-3 mb-5 flex w-full flex-col">
src/types/config.ts
@@ -10,7 +10,7 @@ export type SiteConfig = {
};
export type ProfileConfig = {
- avatar?: string;
+ avatar: string;
name: string;
bio?: string;
links: {
src/config.ts
@@ -17,7 +17,7 @@ export const siteConfig: SiteConfig = {
};
export const profileConfig: ProfileConfig = {
- // avatar: 'https://example.com/avatar.png', // must be a absolute URL, if not set, will use src/asset/img/avatar.jpg
+ avatar: 'assets/img/avatar.jpg',
name: 'John Doe',
bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
links: [],