Add 16:9 template image
This commit is contained in:
parent
56c9a5fe7c
commit
b6093426e1
@ -8,7 +8,7 @@ _Database schema changes are expected._
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
[](https://vercel.com/new/clone?demo-title=Photo+Blog&demo-description=Store+photos+with+original+camera+data&demo-url=https%3A%2F%2Fphotos.sambecker.com&demo-image=https%3A%2F%2Fphotos.sambecker.com%2Ftemplate-image&project-name=Photo+Blog&repository-name=photo-blog&repository-url=https%3A%2F%2Fgithub.com%2Fsambecker%2Fphoto-blog&from=templates&skippable-integrations=1&env-description=Configure+your+photo+blog+meta&env-link=BLANK&env=NEXT_PUBLIC_SITE_TITLE%2CNEXT_PUBLIC_SITE_DOMAIN&teamCreateStatus=hidden&stores=%5B%7B%22type%22%3A%22postgres%22%7D%2C%7B%22type%22%3A%22blob%22%7D%5D)
|
[](https://vercel.com/new/clone?demo-title=Photo+Blog&demo-description=Store+photos+with+original+camera+data&demo-url=https%3A%2F%2Fphotos.sambecker.com&demo-image=https%3A%2F%2Fphotos.sambecker.com%2Ftemplate-image-tight&project-name=Photo+Blog&repository-name=photo-blog&repository-url=https%3A%2F%2Fgithub.com%2Fsambecker%2Fphoto-blog&from=templates&skippable-integrations=1&env-description=Configure+your+photo+blog+meta&env-link=BLANK&env=NEXT_PUBLIC_SITE_TITLE%2CNEXT_PUBLIC_SITE_DOMAIN&teamCreateStatus=hidden&stores=%5B%7B%22type%22%3A%22postgres%22%7D%2C%7B%22type%22%3A%22blob%22%7D%5D)
|
||||||
|
|
||||||
### 1. Deploy to Vercel
|
### 1. Deploy to Vercel
|
||||||
|
|
||||||
|
|||||||
44
src/app/(isr)/template-image-tight/route.tsx
Normal file
44
src/app/(isr)/template-image-tight/route.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import DeployImageResponse from '@/photo/image-response/DeployImageResponse';
|
||||||
|
import { getPhotos } from '@/services/postgres';
|
||||||
|
import { FONT_FAMILY_IBM_PLEX_MONO, getIBMPlexMonoMedium } from '@/site/font';
|
||||||
|
import { ImageResponse } from '@vercel/og';
|
||||||
|
|
||||||
|
const DEBUG_CACHING: boolean = true;
|
||||||
|
|
||||||
|
export const runtime = 'edge';
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const photos = await getPhotos('priority');
|
||||||
|
const fontData = await getIBMPlexMonoMedium();
|
||||||
|
|
||||||
|
return new ImageResponse(
|
||||||
|
(
|
||||||
|
<DeployImageResponse {...{
|
||||||
|
photos,
|
||||||
|
request,
|
||||||
|
includeHeader: false,
|
||||||
|
outerMargin: 0,
|
||||||
|
width: 1200,
|
||||||
|
height: 1200 * 900 / 1600,
|
||||||
|
verticalOffset: -30,
|
||||||
|
fontFamily: FONT_FAMILY_IBM_PLEX_MONO,
|
||||||
|
}}/>
|
||||||
|
),
|
||||||
|
{
|
||||||
|
width: 1200,
|
||||||
|
height: 1200 * 900 / 1600,
|
||||||
|
fonts: [
|
||||||
|
{
|
||||||
|
name: FONT_FAMILY_IBM_PLEX_MONO,
|
||||||
|
data: fontData,
|
||||||
|
style: 'normal',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers: {
|
||||||
|
'Cache-Control': DEBUG_CACHING
|
||||||
|
? 's-maxage=1'
|
||||||
|
: 's-maxage=3600, stale-while-revalidate',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ export function GET() {
|
|||||||
url.searchParams.set('demo-description', DESCRIPTION);
|
url.searchParams.set('demo-description', DESCRIPTION);
|
||||||
url.searchParams.set('demo-url', 'https://photos.sambecker.com');
|
url.searchParams.set('demo-url', 'https://photos.sambecker.com');
|
||||||
url.searchParams.set('demo-description', DESCRIPTION);
|
url.searchParams.set('demo-description', DESCRIPTION);
|
||||||
url.searchParams.set('demo-image', 'https://photos.sambecker.com/template-image');
|
url.searchParams.set('demo-image', 'https://photos.sambecker.com/template-image-tight');
|
||||||
url.searchParams.set('project-name', TITLE);
|
url.searchParams.set('project-name', TITLE);
|
||||||
url.searchParams.set('repository-name', REPO_NAME);
|
url.searchParams.set('repository-name', REPO_NAME);
|
||||||
url.searchParams.set('repository-url', `https://github.com/sambecker/${REPO_NAME}`);
|
url.searchParams.set('repository-url', `https://github.com/sambecker/${REPO_NAME}`);
|
||||||
|
|||||||
@ -10,7 +10,9 @@ export default function DeployImageResponse({
|
|||||||
height,
|
height,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
outerMargin = 50,
|
outerMargin = 50,
|
||||||
|
includeHeader = true,
|
||||||
darkMode = true,
|
darkMode = true,
|
||||||
|
verticalOffset,
|
||||||
}: {
|
}: {
|
||||||
photos: Photo[]
|
photos: Photo[]
|
||||||
request: Request
|
request: Request
|
||||||
@ -18,7 +20,9 @@ export default function DeployImageResponse({
|
|||||||
height: number
|
height: number
|
||||||
fontFamily: string
|
fontFamily: string
|
||||||
outerMargin?: number
|
outerMargin?: number
|
||||||
|
includeHeader?: boolean
|
||||||
darkMode?: boolean
|
darkMode?: boolean
|
||||||
|
verticalOffset?: number
|
||||||
}) {
|
}) {
|
||||||
const innerWidth = width - (outerMargin * 2);
|
const innerWidth = width - (outerMargin * 2);
|
||||||
|
|
||||||
@ -45,33 +49,34 @@ export default function DeployImageResponse({
|
|||||||
marginBottom: outerMargin,
|
marginBottom: outerMargin,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
}}>
|
}}>
|
||||||
<div style={{
|
{includeHeader &&
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
flexGrow: 1,
|
|
||||||
}}>
|
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
border: '2px solid #333',
|
justifyContent: 'flex-start',
|
||||||
alignItems: 'center',
|
flexGrow: 1,
|
||||||
borderRadius: 8,
|
|
||||||
}}>
|
}}>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
padding: '3px 10px',
|
border: '2px solid #333',
|
||||||
color: '#333',
|
alignItems: 'center',
|
||||||
borderRight: '2px solid #333',
|
borderRadius: 8,
|
||||||
}}>
|
}}>
|
||||||
<IconFullFrame includeTitle={false} width={80} />
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '3px 10px',
|
||||||
|
color: '#333',
|
||||||
|
borderRight: '2px solid #333',
|
||||||
|
}}>
|
||||||
|
<IconFullFrame includeTitle={false} width={80} />
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '3px 10px',
|
||||||
|
}}>
|
||||||
|
<IconGrid includeTitle={false} width={80} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
</div>}
|
||||||
display: 'flex',
|
|
||||||
padding: '3px 10px',
|
|
||||||
}}>
|
|
||||||
<IconGrid includeTitle={false} width={80} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
@ -86,6 +91,7 @@ export default function DeployImageResponse({
|
|||||||
colCount: 4,
|
colCount: 4,
|
||||||
rowCount: 4,
|
rowCount: 4,
|
||||||
width: innerWidth,
|
width: innerWidth,
|
||||||
|
verticalOffset,
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export default function PhotoGridImageResponse({
|
|||||||
colCount,
|
colCount,
|
||||||
rowCount,
|
rowCount,
|
||||||
gap = 12,
|
gap = 12,
|
||||||
|
verticalOffset,
|
||||||
}: {
|
}: {
|
||||||
photos: Photo[]
|
photos: Photo[]
|
||||||
request: Request
|
request: Request
|
||||||
@ -17,6 +18,7 @@ export default function PhotoGridImageResponse({
|
|||||||
colCount: number
|
colCount: number
|
||||||
rowCount: number
|
rowCount: number
|
||||||
gap?: number
|
gap?: number
|
||||||
|
verticalOffset?: number
|
||||||
}) {
|
}) {
|
||||||
const imageWidth = (width - ((colCount - 1) * gap)) / colCount ;
|
const imageWidth = (width - ((colCount - 1) * gap)) / colCount ;
|
||||||
|
|
||||||
@ -24,6 +26,7 @@ export default function PhotoGridImageResponse({
|
|||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
|
...verticalOffset && { transform: `translateY(${verticalOffset}px)` },
|
||||||
}}>
|
}}>
|
||||||
{photos
|
{photos
|
||||||
.slice(0, colCount * rowCount)
|
.slice(0, colCount * rowCount)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user