Skip to content

Instantly share code, notes, and snippets.

@Namaskar-1F64F
Created August 8, 2023 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Namaskar-1F64F/f499c85c286eaae6b2e6a7854539c140 to your computer and use it in GitHub Desktop.
Save Namaskar-1F64F/f499c85c286eaae6b2e6a7854539c140 to your computer and use it in GitHub Desktop.
dAppling OG Image Generation
import { StatusType } from '@aws-sdk/client-codebuild'
import { ImageResponse } from '@vercel/og'
import { NextRequest } from 'next/server'
export const config = {
runtime: 'edge',
}
type GradientGenerator = {
generate: (seed: string) => string
}
const colors = ['c051e9', '578ce6', '8cacf5', 'd8fb9f']
// Simple PRNG using Mulberry32 algorithm
function mulberry32(seed: number) {
return function () {
let temp = (seed += 0x6d2b79f5)
temp = Math.imul(temp ^ (temp >>> 15), temp | 1)
temp ^= temp + Math.imul(temp ^ (temp >>> 7), temp | 61)
return ((temp ^ (temp >>> 14)) >>> 0) / 4294967296
}
}
const GradientGenerator: GradientGenerator = {
generate(seed: string) {
// Convert seed string to seed number
let seedNumber = 0
for (let i = 0; i < seed.length; i++) {
seedNumber += seed.charCodeAt(i)
}
const rng = mulberry32(seedNumber)
const gradients = []
const numGradients = Math.floor(rng() * 9) + 2
for (let i = 0; i < numGradients; i++) {
const x = Math.floor(rng() * 201) - 50
const y = Math.floor(rng() * 201) - 50
const start = Math.floor(rng() * 101)
const end = start + Math.floor(rng() * (101 - start))
const color = colors[Math.floor(rng() * colors.length)]
gradients.push(
`radial-gradient(at ${x}% ${y}%, #${color} ${start}%, transparent ${end}%)`
)
}
return gradients.join()
},
}
export default async function handler(request: NextRequest) {
const { searchParams } = new URL(request.url)
const hasId = searchParams.has('id')
const id = hasId
? searchParams.get('id')?.slice(0, 100)
: "What a great day to be alive, what what day isn't?"
const hasType = searchParams.has('type')
const type = hasType ? searchParams.get('type')?.slice(0, 100) : ''
const hasStatus = searchParams.has('status')
const status = hasStatus
? searchParams.get('status')?.slice(0, 100)
: 'we deploy dApps'
const hasRepo = searchParams.has('repo')
const repo = hasRepo ? searchParams.get('repo')?.slice(0, 100) : ''
const hasOwner = searchParams.has('owner')
const owner = hasOwner ? searchParams.get('owner')?.slice(0, 100) : ''
const hasSignature = searchParams.has('signature')
const signature = hasSignature
? searchParams.get('signature')?.slice(0, 100)
: ''
const fontData = await fetch(
new URL('public/fonts/BrandingSF-Medium.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
return new ImageResponse(
(
<span
style={{
fontSize: 90,
fontFamily: 'BrandingSF',
color: 'white',
background: '#1a1a1a',
width: '100%',
height: '100%',
textAlign: 'center',
justifyContent: 'center',
alignItems: 'center',
backgroundPosition:
'0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px,0px 0px',
backgroundImage: GradientGenerator.generate(id || ''),
}}
>
<span
style={{
boxShadow:
' 5px 5px rgba(222, 149, 248, 0.4), 10px 10px rgba(222, 149, 248, 0.3), 15px 15px rgba(222, 149, 248, 0.2), 20px 20px rgba(222, 149, 248, 0.1), 25px 25px rgba(222, 149, 248, 0.05)',
transform: 'translateX(-10px) translateY(-10px)',
width: '75%',
height: '75%',
borderRadius: '15px',
backgroundColor: '#1a1a1a',
}}
>
<span
style={{
border: '3px solid #494949',
height: '100%',
width: '100%',
borderRadius: '15px',
position: 'absolute',
}}
></span>
<HeaderTrinkets />
<hr
style={{
position: 'absolute',
height: '3px',
width: '100%',
backgroundColor: '#494949',
}}
/>
{type && status && repo && owner ? (
<DetailsSection
type={type}
status={status}
repo={repo}
owner={owner}
signature={signature}
/>
) : (
<div
style={{
display: 'flex',
flexDirection: 'column',
margin: '0 auto',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Wordmark scale={1.5} />
{type && <span style={{ fontSize: '42px' }}>{type}</span>}
</div>
)}
</span>
</span>
),
{
width: 1200,
fonts: [
{
name: 'BrandingSF',
data: fontData,
style: 'normal',
},
],
height: 630,
}
)
}
const HeaderTrinkets = () => {
return (
<>
<span
style={{
height: '16px',
left: '16px',
top: '16px',
width: '16px',
backgroundColor: '#DE95F8',
borderRadius: '15px',
position: 'absolute',
}}
></span>
<span
style={{
height: '16px',
left: '40px',
top: '16px',
width: '16px',
backgroundColor: '#578ce6',
borderRadius: '15px',
position: 'absolute',
}}
></span>
<span
style={{
left: '370px',
fontSize: '22px',
top: '10px',
borderRadius: '15px',
position: 'absolute',
}}
>
we deploy dApps
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
height="24px"
style={{
transform: 'rotate(180deg)',
left: '800px',
top: '12px',
position: 'absolute',
}}
>
<path
fill="white"
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
height="24px"
style={{
left: '843px',
top: '12px',
position: 'absolute',
}}
>
<path
fill="#464646"
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
/>
</svg>
<span
style={{
height: '16px',
left: '63px',
top: '16px',
width: '16px',
backgroundColor: '#b3f14f',
borderRadius: '15px',
position: 'absolute',
}}
></span>
</>
)
}
const DetailsSection = ({
type,
status,
repo,
owner,
signature,
}: {
type: string
status: string
repo: string
owner: string
signature?: string
}) => {
return (
<>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
padding: '16px',
paddingLeft: '32px',
height: '100%',
}}
>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
flex: '1',
}}
></div>
<div
style={{
display: 'flex',
textAlign: 'center',
width: '100%',
flex: '1',
}}
>
<div
style={{
marginTop: '-100px',
justifyContent: 'space-between',
display: 'flex',
flexDirection: 'column',
gap: '24px',
}}
>
<span style={{ fontSize: '64px' }}>{repo}</span>
<div style={{ display: 'flex', gap: '12px' }}>
<svg
style={{
marginTop: '3px',
width: '72px',
height: '72px',
filter: 'sepia(0) saturate(0) brightness(0) invert(1)',
}}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
>
<path d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0 1 38.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z" />
</svg>
<span style={{ textOverflow: 'ellipsis', fontSize: '52px' }}>
{owner}
</span>
</div>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
textAlign: 'center',
width: '100%',
flex: '1',
marginLeft: '14px',
fontSize: '50px',
}}
>
{status === StatusType.SUCCEEDED && (
<div
style={{
display: 'flex',
gap: '16px',
justifyContent: 'space-between',
width: '100%',
}}
>
<div style={{ display: 'flex', gap: '8px' }}>
<svg
xmlns="http://www.w3.org/2000/svg"
style={{
width: '50px',
height: '50px',
marginTop: '10px',
}}
viewBox="0 0 1024 1024"
>
<path
fill="#b3f14f"
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z"
/>
</svg>
deployed
</div>
{signature && (
<div
style={{
display: 'flex',
flex: 1,
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
style={{
width: '50px',
height: '50px',
marginTop: '10px',
}}
>
<path
fill="#b3f14f"
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
/>
</svg>
<span
style={{
fontSize: '50px',
textOverflow: 'ellipsis',
}}
>
verified
</span>
</div>
)}
</div>
)}
{status === StatusType.FAILED && (
<div
style={{
display: 'flex',
gap: '12px',
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
style={{
width: '50px',
height: '50px',
marginTop: '10px',
}}
viewBox="0 0 1024 1024"
>
<path
fill="#F5212D"
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM512 533c-85.5 0-155.6 67.3-160 151.6a8 8 0 0 0 8 8.4h48.1c4.2 0 7.8-3.2 8.1-7.4C420 636.1 461.5 597 512 597s92.1 39.1 95.8 88.6c.3 4.2 3.9 7.4 8.1 7.4H664a8 8 0 0 0 8-8.4C667.6 600.3 597.5 533 512 533z"
/>
</svg>
not deployed
</div>
)}
</div>
</div>
</div>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'flex-end',
width: '100%',
flex: '1',
marginBottom: '16px',
}}
>
<span style={{ fontSize: '40px', marginLeft: '8px' }}>{type}</span>
<Wordmark />
</div>
</div>
</>
)
}
const Wordmark = ({ scale = 1 }) => {
return (
<svg
width={scale * 334}
height={scale * 75}
viewBox="0 0 668 151"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={{ marginRight: '16px' }}
>
<path
d="M230.098 22.5836C234.132 22.5836 237.447 22.8593 240.1 23.3556V106.686C236.563 108.451 232.197 109.94 227.113 111.153C222.029 112.367 216.835 112.918 211.64 112.918C200.091 112.918 191.028 110.05 184.507 104.204C177.986 98.4138 174.726 90.1966 174.726 79.5528C174.726 72.8797 176.329 66.9236 179.479 61.7395C182.628 56.5555 186.883 52.5848 192.189 49.8824C197.494 47.1801 203.462 45.8566 209.983 45.8566C213.906 45.8566 217.277 46.2426 220.261 47.0147V23.3556C222.914 22.8593 226.174 22.5836 230.098 22.5836ZM210.922 96.0424C213.961 96.0424 217.056 95.6563 220.261 94.8291V64.5522C217.885 63.3389 214.845 62.7322 211.254 62.7322C206.501 62.7322 202.522 64.2213 199.428 67.2545C196.333 70.2877 194.731 74.3136 194.731 79.3322C194.731 84.3507 196.223 88.3766 199.207 91.465C202.191 94.5534 206.114 96.0424 210.922 96.0424Z"
fill="#B3F14F"
/>
<path
d="M295.049 25.7774L325.68 109.017C321.136 110.051 317.02 110.541 313.278 110.541C311.033 110.541 308.681 110.323 306.222 109.888L300.341 93.2289H269.658L263.724 109.888C261.212 110.214 258.325 110.378 255.011 110.378C250.841 110.378 247.42 109.888 244.854 108.962L275.698 25.723C278.264 25.233 281.578 24.9608 285.641 24.9608C289.383 24.9608 292.537 25.233 295.049 25.723V25.7774ZM275.591 77.0601H294.354L287.459 57.6794L284.893 49.5678L282.594 57.6794L275.645 77.0601H275.591Z"
fill="#B3F14F"
/>
<path
d="M359.495 45.1672C364.592 45.1672 369.19 45.8734 373.456 47.2315C377.666 48.5896 381.378 50.5996 384.536 53.2615C387.694 55.9234 390.187 59.3458 391.96 63.5831C393.733 67.8203 394.619 72.6009 394.619 78.0333C394.619 84.8238 393.013 90.8538 389.855 96.0146C386.641 101.175 382.486 105.087 377.279 107.749C372.071 110.41 366.309 111.714 359.938 111.714C356.004 111.714 352.403 111.334 349.19 110.519V133.553C345.866 134.041 342.542 134.313 339.162 134.313C335.783 134.313 332.57 134.041 329.246 133.553V54.9455C337.611 48.4809 347.694 45.2215 359.55 45.2215L359.495 45.1672ZM358.331 94.6565C363.262 94.7651 367.251 93.3527 370.187 90.4735C373.124 87.5943 374.619 83.5743 374.619 78.4135C374.619 73.2527 373.124 69.5587 370.132 66.7339C367.14 63.9633 363.096 62.5509 358.11 62.5509C355.007 62.5509 352.016 63.0941 349.19 64.2349V93.0267C351.628 94.1132 354.675 94.6021 358.387 94.6021L358.331 94.6565Z"
fill="#B3F14F"
/>
<path
d="M432.089 45.1672C437 45.1672 441.431 45.8734 445.542 47.2315C449.6 48.5896 453.176 50.5996 456.22 53.2615C459.263 55.9234 461.665 59.3458 463.373 63.5831C465.082 67.8203 465.936 72.6009 465.936 78.0333C465.936 84.8238 464.388 90.8538 461.345 96.0146C458.248 101.175 454.244 105.087 449.226 107.749C444.207 110.41 438.655 111.714 432.516 111.714C428.725 111.714 425.255 111.334 422.159 110.519V133.553C418.955 134.041 415.752 134.313 412.496 134.313C409.239 134.313 406.143 134.041 402.939 133.553V54.9455C411.001 48.4809 420.717 45.2215 432.142 45.2215L432.089 45.1672ZM430.968 94.6565C435.719 94.7651 439.563 93.3527 442.392 90.4735C445.222 87.5943 446.663 83.5743 446.663 78.4135C446.663 73.2527 445.222 69.5587 442.339 66.7339C439.456 63.9633 435.559 62.5509 430.754 62.5509C427.764 62.5509 424.881 63.0941 422.159 64.2349V93.0267C424.508 94.1132 427.444 94.6021 431.021 94.6021L430.968 94.6565Z"
fill="#B3F14F"
/>
<path
d="M485.043 110.541C481.487 110.541 477.931 110.268 474.256 109.776V23.3484C476.864 22.8567 480.301 22.5836 484.628 22.5836C488.954 22.5836 492.688 22.8567 495.651 23.3484V109.776C492.392 110.268 488.895 110.541 485.043 110.541Z"
fill="#B3F14F"
/>
<path
d="M525.55 36.4489C523.312 38.7761 520.659 39.9126 517.588 39.9126C514.518 39.9126 511.864 38.7761 509.679 36.4489C507.441 34.1217 506.349 31.4156 506.349 28.2224C506.349 25.0293 507.441 22.3232 509.627 20.0501C511.812 17.7771 514.466 16.6405 517.588 16.6405C520.711 16.6405 523.312 17.7771 525.55 20.0501C527.787 22.3232 528.932 25.0293 528.932 28.2224C528.932 31.4156 527.787 34.1758 525.55 36.4489ZM517.484 110.541C514.466 110.541 511.396 110.27 508.222 109.783V47.9767C510.616 47.4896 513.686 47.219 517.484 47.219C521.283 47.219 524.301 47.4896 526.903 47.9767V109.783C523.885 110.27 520.763 110.541 517.484 110.541Z"
fill="#B3F14F"
/>
<path
d="M566.516 45.1672C576.14 45.1672 583.398 47.5702 588.237 52.4309C593.075 57.2916 595.495 63.7361 595.495 71.8737V109.776C592.339 110.268 589.131 110.541 585.975 110.541C582.82 110.541 579.664 110.268 576.508 109.776V75.0414C576.508 67.013 572.669 62.9715 565.096 62.9715C561.361 62.9715 557.995 63.8454 554.998 65.593V109.776C551.842 110.268 548.686 110.541 545.478 110.541C542.27 110.541 539.22 110.268 536.064 109.776V55.5986C538.957 52.9224 543.059 50.5194 548.371 48.3894C553.683 46.2595 559.731 45.2218 566.463 45.2218L566.516 45.1672Z"
fill="#B3F14F"
/>
<path
d="M639.065 45.1672C644.775 45.1672 650.156 45.9897 655.207 47.6897C660.258 49.3896 664.541 51.5831 668 54.325V106.201C668 111.246 667.176 115.797 665.529 119.691C663.882 123.639 661.576 126.82 658.611 129.287C655.646 131.755 652.187 133.565 648.234 134.826C644.281 136.087 639.888 136.69 635.111 136.69C628.029 136.69 621.934 135.594 616.663 133.4C611.447 131.207 607.274 128.355 604.089 124.9C604.474 122.268 605.627 119.8 607.549 117.497C609.47 115.194 611.886 113.549 614.796 112.507C619.847 118.21 626.217 121.062 633.958 121.062C638.845 121.062 642.469 120.075 644.775 118.046C647.081 116.017 648.234 113.275 648.234 109.71V107.462C644.94 108.449 641.371 108.943 637.582 108.943C631.323 108.943 625.668 107.791 620.616 105.543C615.565 103.295 611.502 99.7849 608.427 95.0689C605.352 90.353 603.815 84.7596 603.815 78.2888C603.815 71.4341 605.407 65.5117 608.647 60.4119C611.886 55.312 616.114 51.5283 621.385 48.9509C626.656 46.4284 632.531 45.1672 639.01 45.1672H639.065ZM639.449 93.1496C642.579 93.1496 645.543 92.6013 648.289 91.5594V63.5924C645.159 62.4409 642.194 61.8377 639.449 61.8377C634.947 61.8377 631.213 63.2634 628.248 66.115C625.283 68.9665 623.801 72.7502 623.801 77.5759C623.801 82.4016 625.283 86.1305 628.193 88.9272C631.103 91.7239 634.892 93.1496 639.504 93.1496H639.449Z"
fill="#B3F14F"
/>
<path
d="M129.674 33.5366L73.6106 1.54929C69.9998 -0.516429 65.502 -0.516429 61.8912 1.54929L5.82803 33.5366C2.21719 35.6023 0 39.4207 0 43.5522V107.527C0 111.658 2.21719 115.477 5.82803 117.542L35.8551 134.694L35.9818 134.381C38.7057 128.747 38.6424 122.237 35.8551 116.603L15.7737 105.148V45.8683L67.7192 16.2597L119.665 45.8683V105.148L75.6377 130.25V109.217C75.6377 109.217 75.8278 109.217 75.9545 109.217C88.7508 109.217 100.344 100.453 103.194 87.5582C103.321 86.8696 102.751 86.0558 102.054 85.868C94.7689 84.3031 87.2938 85.6177 81.0857 89.5613C79.0585 90.8758 77.2848 92.5034 75.6377 94.1935V46.3691H69.6197C64.2351 46.3691 59.8007 50.6883 59.8007 56.0717V72.7852C58.1536 70.7821 56.3799 68.9041 54.1627 67.3392C48.0813 63.0826 40.7329 61.455 33.3211 62.6444C32.6243 62.7696 32.0542 63.646 32.1809 64.2719C33.4478 71.5332 37.4388 77.8556 43.5202 82.1122C48.2713 85.4299 53.846 87.1826 59.5473 87.1826C59.6106 87.1826 59.674 87.1826 59.8007 87.1826V145.81C59.8007 147.297 60.5989 148.669 61.8912 149.404V149.404C65.502 151.47 69.9998 151.47 73.6106 149.404L75.7011 148.215L129.674 117.417C133.285 115.351 135.502 111.533 135.502 107.402V43.5522C135.502 39.4207 133.285 35.6023 129.674 33.5366Z"
fill="#B3F14F"
/>
</svg>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment