From 7cb6ca1ffd56971e829756b60f4d53f54334ab22 Mon Sep 17 00:00:00 2001 From: Carson Clarke-Magrab Date: Thu, 13 Jun 2024 14:37:51 -0400 Subject: [PATCH] Add latest blog component --- content/Graphics/01.god-rays.md | 20 -------- content/blogs/graphics/god-rays.md | 27 ++++++++++ content/index.md | 3 -- quartz.layout.ts | 1 + quartz/components/Breadcrumbs.tsx | 6 ++- quartz/components/ExplorerNode.tsx | 6 ++- quartz/components/RecentBlog.tsx | 64 ++++++++++++++++++++++++ quartz/components/index.ts | 4 +- quartz/components/styles/recentblog.scss | 34 +++++++++++++ quartz/styles/custom.scss | 21 +++++--- 10 files changed, 154 insertions(+), 32 deletions(-) delete mode 100644 content/Graphics/01.god-rays.md create mode 100644 content/blogs/graphics/god-rays.md create mode 100644 quartz/components/RecentBlog.tsx create mode 100644 quartz/components/styles/recentblog.scss diff --git a/content/Graphics/01.god-rays.md b/content/Graphics/01.god-rays.md deleted file mode 100644 index cb5e85322..000000000 --- a/content/Graphics/01.god-rays.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -draft: false -title: Screen Space God Rays -tags: - - graphics ---- - -While thinking about graphical improvements to [[01.far-reaches|The Far Reaches]], I landed on the decision to invest some time into environmental weather effects like rain, snow, clouds, etc. I was deeply inspired by [t3ssel8r's video](https://www.youtube.com/watch?v=fSNdZ82I-eQ) on god rays (and much of his other stuff) and decided to take a crack at it myself. Before we begin let's break this down to understand what we're talking about here starting with *god rays*. - -## God Rays - -You've seen these before likely both in real life and in video games. - -> [!caption|center] -> ![[crepuscular_rays_real.png]] -"God Rays" - -The scientific term for this phenomenon is called **crepuscular rays** and the term in the graphics programming world is **volumetric light scattering**. These effects are caused by clouds or other objects and give the impression of "shafts" of light emitting from the sun. Essentially the shadows from the clouds create shadowed and un-shadowed regions of the atmosphere where light is being scattered and the contrast between these regions gives the effect of "shafts" of light emerging from the sun. - -## Implementation diff --git a/content/blogs/graphics/god-rays.md b/content/blogs/graphics/god-rays.md new file mode 100644 index 000000000..e5138f06f --- /dev/null +++ b/content/blogs/graphics/god-rays.md @@ -0,0 +1,27 @@ +--- +draft: false +title: God Rays +tags: + - graphics +created: 2024-06-12 +date: 2024-06-13 +aliases: + - God Rays +description: In this post we go over what are god rays and a couple different high-level approaches to them followed by my personal implementation. +--- + +While thinking about graphical improvements to [[01.far-reaches|The Far Reaches]], I landed on the decision to invest some time into environmental weather effects like rain, snow, clouds, etc. I was deeply inspired by [t3ssel8r's video](https://www.youtube.com/watch?v=fSNdZ82I-eQ) on god rays (and much of his other stuff) and decided to take a crack at it myself. Before we begin let's break this down to understand what we're talking about here starting with *god rays*. + +## God Rays + +You've seen these before likely both in real life and in video games. + +> [!caption|center] +> ![[crepuscular_rays_real.png]] +"God Rays" + +The scientific term for this phenomenon is called **crepuscular rays**. *Crepuscular* meaning "of or related to twilight" referring to the fact that this effect usually occurs during twilight. In the graphics world the term is **volumetric light scattering**, referring to how the light "scatters" in the atmosphere. + +These effects are caused by clouds or other objects and give the impression of "shafts" of light emitting from the sun. Essentially the shadows from the clouds create shadowed and un-shadowed regions of the atmosphere where light is being scattered and the contrast between these regions gives the effect of "shafts" of light emerging from the sun. + +## Implementation diff --git a/content/index.md b/content/index.md index 9292f067b..d39622813 100644 --- a/content/index.md +++ b/content/index.md @@ -2,9 +2,6 @@ title: Carson's Blog --- -> [!info] Latest Blog -> [[01.god-rays|Screen Space God Rays]] - A long time ago in a year known to many by 2003, I played my first "real" video game: **Pokémon Sapphire**. After encountering it in a Walmart in the great state of Maine, I quickly became enamored with the vaguely whale-shaped creature on the box art for the game. And so I began my scheming to acquire the game for myself. In about ~0.03 seconds I had formulated my plan. It was simple. Brilliant even. All I need do was ask my grandmother who was with me at that fated Walmart for it. The trick? My parents weren't with us to say no. diff --git a/quartz.layout.ts b/quartz.layout.ts index 02301d8f9..4003395e1 100644 --- a/quartz.layout.ts +++ b/quartz.layout.ts @@ -20,6 +20,7 @@ export const defaultContentPageLayout: PageLayout = { Component.ArticleTitle(), Component.ContentMeta(), Component.TagList(), + Component.RecentBlog(), Component.Comments(), ], left: [ diff --git a/quartz/components/Breadcrumbs.tsx b/quartz/components/Breadcrumbs.tsx index 9ccfb9a6a..fbfb7595f 100644 --- a/quartz/components/Breadcrumbs.tsx +++ b/quartz/components/Breadcrumbs.tsx @@ -42,11 +42,15 @@ const defaultOptions: BreadcrumbOptions = { function formatCrumb(displayName: string, baseSlug: FullSlug, currentSlug: SimpleSlug): CrumbData { return { - displayName: displayName.replaceAll("-", " "), + displayName: capitalize(displayName.replaceAll("-", " ")), path: resolveRelative(baseSlug, currentSlug), } } +function capitalize(title: string) { + return title.charAt(0).toUpperCase() + title.slice(1); +} + export default ((opts?: Partial) => { // Merge options with defaults const options: BreadcrumbOptions = { ...defaultOptions, ...opts } diff --git a/quartz/components/ExplorerNode.tsx b/quartz/components/ExplorerNode.tsx index 2968a03e9..40aee6cc2 100644 --- a/quartz/components/ExplorerNode.tsx +++ b/quartz/components/ExplorerNode.tsx @@ -51,11 +51,15 @@ export class FileNode { constructor(slugSegment: string, displayName?: string, file?: QuartzPluginData, depth?: number) { this.children = [] this.name = slugSegment - this.displayName = displayName ?? file?.frontmatter?.title ?? slugSegment + this.displayName = this.capitalize(displayName ?? file?.frontmatter?.title ?? slugSegment) this.file = file ? clone(file) : null this.depth = depth ?? 0 } + private capitalize(title: string) { + return title.charAt(0).toUpperCase() + title.slice(1); + } + private insert(fileData: DataWrapper) { if (fileData.path.length === 0) { return diff --git a/quartz/components/RecentBlog.tsx b/quartz/components/RecentBlog.tsx new file mode 100644 index 000000000..7f439fe4a --- /dev/null +++ b/quartz/components/RecentBlog.tsx @@ -0,0 +1,64 @@ +import style from "./styles/recentblog.scss" +import { i18n } from "../i18n" +import { resolveRelative } from "../util/path" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" + +export default (() => { + + const RecentBlog: QuartzComponent = ({ + allFiles, + fileData, + cfg + }: QuartzComponentProps) => { + + const page = allFiles.reduce((prev, curr) => { + console.log(fileData.filePath) + if (!curr.filePath?.startsWith("content/blogs/")) { + return prev + } else if (!prev.filePath?.startsWith("content/blogs/")) { + return curr + } + + const prevDate = prev.dates?.created ?? new Date(1970, 1, 1) + const currDate = curr.dates?.created ?? new Date(1970, 1, 1) + if (currDate > prevDate) { + return curr + } + return prev + }, allFiles[0]) + + const title = page.frontmatter?.title ?? i18n(cfg.locale).propertyDefaults.title + const parseDate = (date: Date) => { + return date.toLocaleDateString('en-US') //`${date.getFullYear()}/${date.getMonth()}/${date.getDay()}` + } + + + return fileData.filePath?.startsWith("content/index") ? ( +
+
+
+
+

Latest Blog

+
+
+ +
+ +
+
+ + {title} + + {parseDate(page.dates?.published!)} +
+ +

{page.description}

+
+
+
+ ) : <> + } + + RecentBlog.css = style + return RecentBlog +}) satisfies QuartzComponentConstructor \ No newline at end of file diff --git a/quartz/components/index.ts b/quartz/components/index.ts index bb7a512ad..43ad33b79 100644 --- a/quartz/components/index.ts +++ b/quartz/components/index.ts @@ -21,6 +21,7 @@ import RecentNotes from "./RecentNotes" import Breadcrumbs from "./Breadcrumbs" import Comments from "./Comments" +import RecentBlog from "./RecentBlog" export { ArticleTitle, @@ -45,5 +46,6 @@ export { NotFound, Breadcrumbs, - Comments + Comments, + RecentBlog } diff --git a/quartz/components/styles/recentblog.scss b/quartz/components/styles/recentblog.scss new file mode 100644 index 000000000..9c91b886f --- /dev/null +++ b/quartz/components/styles/recentblog.scss @@ -0,0 +1,34 @@ +.preview { + display: flex; + flex-direction: row; + padding: 16px 16px; + + border-style: solid; + border-color: #00bfa544; + border-width: 1px; + border-radius: 5px; + background: #00bfa510; + + & > .preview-image { + margin: 0px 0px; + } + + & > .preview-content { + margin: 0px 10px; + + & > .preview-title { + display: flex; + justify-content: space-between; + margin-top: 6px; + + & > a { + font-size: 20; + } + } + + & > p { + margin: 0px 0px; + margin-top: 4px; + } + } +} \ No newline at end of file diff --git a/quartz/styles/custom.scss b/quartz/styles/custom.scss index 08e651970..f4f85e258 100644 --- a/quartz/styles/custom.scss +++ b/quartz/styles/custom.scss @@ -33,6 +33,15 @@ img:active:not(.Logo) { background:var(--background-primary); } +/*----Blog Callouts----*/ + +.callout[data-callout="blog"] { + --color: #00bfa5; + --border: rgba(0, 0, 0, 0); + --bg: rgba(0, 0, 0, 0); + --callout-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLW5ld3NwYXBlciI+PHBhdGggZD0iTTQgMjJoMTZhMiAyIDAgMCAwIDItMlY0YTIgMiAwIDAgMC0yLTJIOGEyIDIgMCAwIDAtMiAydjE2YTIgMiAwIDAgMS0yIDJabTAgMGEyIDIgMCAwIDEtMi0ydi05YzAtMS4xLjktMiAyLTJoMiIvPjxwYXRoIGQ9Ik0xOCAxNGgtOCIvPjxwYXRoIGQ9Ik0xNSAxOGgtNSIvPjxwYXRoIGQ9Ik0xMCA2aDh2NGgtOFY2WiIvPjwvc3ZnPg=="); +} + /*----Faux Grid Callouts----*/ /*---float left---*/ @@ -42,10 +51,9 @@ img:active:not(.Logo) { --bg: rgba(0, 0, 0, 0); --callout-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLW5ld3NwYXBlciI+PHBhdGggZD0iTTQgMjJoMTZhMiAyIDAgMCAwIDItMlY0YTIgMiAwIDAgMC0yLTJIOGEyIDIgMCAwIDAtMiAydjE2YTIgMiAwIDAgMS0yIDJabTAgMGEyIDIgMCAwIDEtMi0ydi05YzAtMS4xLjktMiAyLTJoMiIvPjxwYXRoIGQ9Ik0xOCAxNGgtOCIvPjxwYXRoIGQ9Ik0xNSAxOGgtNSIvPjxwYXRoIGQ9Ik0xMCA2aDh2NGgtOFY2WiIvPjwvc3ZnPg=="); float: left; - width: 45%; - margin: auto; + width: 48%; + margin: auto 1%; clear: left; - margin-left: 20px; } /* mobile breakpoint */ @@ -53,6 +61,7 @@ img:active:not(.Logo) { .callout[data-callout="gridfloatleft"] { width: 100%; float: none; + margin: 20px auto; } } @@ -64,10 +73,9 @@ img:active:not(.Logo) { --bg: rgba(0, 0, 0, 0); --callout-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLW5ld3NwYXBlciI+PHBhdGggZD0iTTQgMjJoMTZhMiAyIDAgMCAwIDItMlY0YTIgMiAwIDAgMC0yLTJIOGEyIDIgMCAwIDAtMiAydjE2YTIgMiAwIDAgMS0yIDJabTAgMGEyIDIgMCAwIDEtMi0ydi05YzAtMS4xLjktMiAyLTJoMiIvPjxwYXRoIGQ9Ik0xOCAxNGgtOCIvPjxwYXRoIGQ9Ik0xNSAxOGgtNSIvPjxwYXRoIGQ9Ik0xMCA2aDh2NGgtOFY2WiIvPjwvc3ZnPg=="); float: right; - width: 45%; - margin: auto; + width: 48%; + margin: auto 1%; clear: right; - margin-right: 20px; } /* mobile breakpoint */ @@ -75,6 +83,7 @@ img:active:not(.Logo) { .callout[data-callout="gridfloatright"] { width: 100%; float: none; + margin: 20px auto; } }