add banner card generator layout

This commit is contained in:
James Fenn
2023-04-04 18:01:07 -04:00
parent 570815ea5e
commit eb882747f7
6 changed files with 174 additions and 19 deletions

View File

@@ -0,0 +1,104 @@
export default `
.codeScreenBg {
perspective: 200px;
perspective-origin: center;
}
.codeScreenBg {
background: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCABIAIADASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAECAwQFBv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHhWUyNsqZRozlhDTXvDldLnCzW01KcbCmF9ImmSIotuy2G3veW9DFnC73mxUaM1XW5WTqATTGIG0iWvER2OWoggpNMQwBAwAJXGeWpmRa4mUtgQbiA0DAd4FgAAKIEEBCICiB//8QAIxAAAQQBBAIDAQAAAAAAAAAAAQACAxESECEwMSAyBBMiI//aAAgBAQABBQIbK9ogpRsw4optlRsNy+jk/rRyPg12zjaeaR9Gdtbala5SDUJ6LdtR2U0onaHuJv5LLMyDb0j9p+28AdivjzD63yU2U26/56ONnzvSGXFfbm1x/XM11c+JWJ5KKDfAhYqvOkBw0sVjp//EABQRAQAAAAAAAAAAAAAAAAAAAFD/2gAIAQMBAT8BI//EABQRAQAAAAAAAAAAAAAAAAAAAFD/2gAIAQIBAT8BI//EABsQAAMAAwEBAAAAAAAAAAAAAAABIRARIDBg/9oACAEBAAY/AsTEzCi4XSRpEzti96QvF8abS+Y//8QAHxAAAwACAgMBAQAAAAAAAAAAAAERITEQQSBRYTBx/9oACAEBAAE/IWC7RjVT+sQ6XuFc9cs31ntiNwbcLJazs2b2dHYsHZoy2ZZfPRCaIX7iGoZzgXitG4nklwQSmy2W24fC0jCkE5p+I2TIdbRTr2IXSlSsCpPCQgfxxmtImDrPkQ8jdSd8D2Yg2HRn9D2JxpmQL43hZDdKUmqkN25xdFm/ajMEbf4rjriNnwIdeM807oStkS65Sx+o2XKXgrFr8WrI4Q//2gAMAwEAAgADAAAAELF3261HEKNNDcYDWOBNCizLMDBPOYaJPPIXfHfYXP/EABQRAQAAAAAAAAAAAAAAAAAAAFD/2gAIAQMBAT8QI//EABkRAQACAwAAAAAAAAAAAAAAAAEAESAwQP/aAAgBAgEBPxDWwzSBXJ//xAAeEAEAAwEBAAMBAQAAAAAAAAABABEhMUEQUWFxgf/aAAgBAQABPxBVDED24YAfYyo4Vw9juZZ/JELbL2D6mBShKHOuv3GodNltJsiUZSpo9fs6H3KhChxss1ucJ1nsVy8nbiuBOJl0z1BayVAKHr1ZRwAL/s5eWwPZWWR4djk0u7KVMAz9jqksb3Iz9RGEuFpEos5HSyDaDOZdRcnnsESg3m+T0oTFTarZYzl9RL4obCNxQk17P9gDFr3ZQKyZYADyHRZKilpeX8FXZH7IKWx0n3LICBabuMc0mn7iGReseW6sijAKNXexalcOkfslgnXZyH8g7MMuIWuWLZX14mU5SzEZi3TRBTjHWDVkLj2XPIYQdiCuxorbi1LghuBKZFVftj1jjk9tgk9jRCPZ18ZFCwRQX8Ytahl/cI6/k/Jgh+x35DdyBbkcqN7TDkHws6Z/scbU6gxT6grjLJWwiEREEFLYQZfww/Y5EGeRP22IDrCs/9k='), radial-gradient(ellipse 200% 100%, #EEE, #FFF);
background-blend-mode: screen;
background-size: cover;
z-index: -4;
}
.codeScreenBg.blur {
--gradient: linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,1));
-webkit-mask-image: var(--gradient);
mask-image: var(--gradient);
filter: blur(5px);
}
.codeScreen, .rect {
--z: 0px;
transform: rotateX(var(--rotX)) rotateY(21deg) rotateZ(336deg) translate(25%, -20%) translateZ(var(--z));
transform-origin: center;
}
.codeScreen {
height: 1000px;
overflow: hidden;
background-color: #FFF;
position: absolute;
top: 0;
left: 20%;
right: 0;
box-shadow: 0 0 180px 0 #0002;
border-radius: 20px;
border-left: 10px solid #CCC;
}
.rect {
width: 180px;
height: 180px;
background-color: #8885;
backdrop-filter: blur(2px);
border: 4px solid #FFF;
box-shadow: -80px -10px 30px #0005;
--x: 0px;
--y: 0px;
--z: 80px;
position: absolute;
top: calc(50% + var(--y));
left: calc(50% + var(--x));
}
.rect img {
margin: 20px;
width: calc(100% - 40px);
filter: grayscale(1);
}
.tags {
position: absolute;
top: 25%;
left: 5%;
font-size: 10rem;
font-family: monospace;
text-transform: uppercase;
font-weight: bolder;
}
.tags span {
display: block;
color: rgba(0, 0, 0, 0.15);
}
pre {
background: none !important;
border: none !important;
color: #000 !important;
}
pre code span {
text-shadow: currentColor 1px 0 10px;
}
.absoluteFill {
height: 100%;
width: 100%;
position: absolute;
box-sizing: border-box;
top: 0;
left: 0;
}
.codeScreenOverlay {
background: linear-gradient(340deg, rgba(0,0,0,.5), rgba(0,0,0,0)), url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600"><filter id="noiseFilter"><feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(%23noiseFilter)"/></svg>');
background-blend-mode: screen;
filter: contrast(800%) brightness(200%) saturate(0%);
opacity: 0.1;
z-index: -2;
}
`;

View File

@@ -0,0 +1,60 @@
import * as React from 'preact';
import { readFileAsBase64 } from '../utils';
import * as fs from 'fs';
import { ComponentProps } from '../base';
import style from './banner.css';
import classnames from 'classnames';
const unicornFile = readFileAsBase64("src/assets/unicorn_utterances_sticker_512.png");
function BannerCodeScreen({
post,
postHtml,
blur,
}: {
post: ComponentProps['post'],
postHtml: string,
blur?: boolean,
}) {
const rotX = (post.description.length % 30) - 10;
return <>
<div class={classnames("absoluteFill", "codeScreenBg", blur && "blur")} style={`--rotX: ${rotX}deg;`}>
<div class="codeScreen">
<pre dangerouslySetInnerHTML={{ __html: postHtml }} />
<div class="tags">
{
post.tags.map((tag) => (
<span key={tag}>{tag}</span>
))
}
</div>
</div>
<div class="rect" style="--z: 60px; --x: -80px; --y: -150px;">
<img src={unicornFile} />
</div>
</div>
</>;
}
function Banner({
post,
postHtml,
}: ComponentProps) {
return <>
<BannerCodeScreen post={post} postHtml={postHtml} />
<BannerCodeScreen post={post} postHtml={postHtml} blur />
<div
className="absoluteFill codeScreenOverlay"
style={{
zIndex: -1,
}}
/>
</>;
}
export default {
name: "banner",
css: style,
Component: Banner,
};

View File

@@ -1,10 +1,6 @@
export default `
@import url("https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
html, body {
margin: 0;
padding: 0;
}
* {
font-family: "Work Sans";
color: var(--white);
@@ -145,3 +141,4 @@ html, body {
.secondHalfTitle {
color: #f5acc9;
}
`;

View File

@@ -1,11 +1,7 @@
import * as React from 'preact';
import { readFileAsBase64 } from '../utils';
import { dirname, resolve } from 'path';
import * as fs from 'fs';
import { ComponentProps } from '../base';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
import style from './twitter-preview.css';
export function splitSentence(str: string): [string, string] {
const splitStr = str.split(" ");
@@ -42,9 +38,7 @@ export function splitSentence(str: string): [string, string] {
return [str, ""];
}
const unicornUtterancesHead = readFileAsBase64(
resolve("src/assets/unicorn_head_1024.png")
);
const unicornUtterancesHead = readFileAsBase64("src/assets/unicorn_head_1024.png");
interface TwitterCodeScreenProps {
title: string;
@@ -131,9 +125,6 @@ const TwitterLargeCard = ({
export default {
name: "twitter-preview",
css: fs.readFileSync(
resolve(__dirname, "./twitter-preview.css"),
"utf8"
),
css: style,
Component: TwitterLargeCard,
};

View File

@@ -12,10 +12,11 @@ import remarkToRehype from "remark-rehype";
import { findAllAfter } from "unist-util-find-all-after";
import rehypeStringify from "rehype-stringify";
import banner from "./layouts/banner";
import twitterPreview from "./layouts/twitter-preview";
import { Layout } from "./base";
export const layouts: Layout[] = [twitterPreview];
export const layouts: Layout[] = [banner, twitterPreview];
// https://github.com/shikijs/twoslash/issues/147
const remarkTwoslash =
@@ -103,6 +104,8 @@ export const renderPostPreviewToString = async (
</style>
<style>
html, body {
margin: 0;
padding: 0;
width: ${heightWidth.width}px;
height: ${heightWidth.height}px;
position: relative;

2
public/.gitignore vendored
View File

@@ -3,5 +3,5 @@ content/**
.ignored_*
unicorn-profile-pic-map.ts
searchIndex.js
*.twitter-preview.png
generated/
*.epub