forked from cadey/xesite
102 lines
4.5 KiB
Markdown
102 lines
4.5 KiB
Markdown
|
---
|
||
|
title: "Site Update: Hero Images"
|
||
|
date: 2022-06-08
|
||
|
---
|
||
|
|
||
|
For a while I've been wondering how I can add dramatic flair to my website with
|
||
|
so-called "hero images". These images are tools that let you describe the mood a
|
||
|
website wants to evoke. I've been unsure how to best implement these on my
|
||
|
website for a while, but with the advent of MidJourney and other image
|
||
|
generation APIs/algorithms I think I have found a way to create these without
|
||
|
too much effort on my part and the results are pretty fantastic:
|
||
|
|
||
|
<xeblog-hero file="secret-to-life" prompt="the secret to life, the universe and everything, concept art"></xeblog-hero>
|
||
|
|
||
|
I have generated a bunch of other images that I'm going to use for my other
|
||
|
posts. I'll give out a desktop wallpaper sized version of each of these images
|
||
|
on my [Patreon](https://patreon.com/cadey).
|
||
|
|
||
|
Under the hood this is powered by
|
||
|
[lol_html](https://github.com/cloudflare/lol-html) and
|
||
|
[Maud](https://maud.lambda.xyz/). The magic is mostly contained in a function
|
||
|
that generates a `<figure>` HTML element (which I just learned exists today). I
|
||
|
use a function that looks like this for generating the `<xeblog-hero>` snippets:
|
||
|
|
||
|
```rust
|
||
|
pub fn xeblog_hero(file: String, prompt: Option<String>) -> Markup {
|
||
|
html! {
|
||
|
figure.hero style="margin:0" {
|
||
|
picture style="margin:0" {
|
||
|
source type="image/avif" srcset={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) ".avif"};
|
||
|
source type="image/webp" srcset={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) ".webp"};
|
||
|
img style="padding:0" alt={"hero image " (file)} src={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) "-smol.png"};
|
||
|
}
|
||
|
figcaption { "Image generated by MidJourney" @if let Some(prompt) = prompt { " -- " (prompt) } }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
I have it wired up with lol_html like this:
|
||
|
|
||
|
```rust
|
||
|
lol_html::element!("xeblog-hero", |el| {
|
||
|
let file = el.get_attribute("file").expect("wanted xeblog-hero to contain file");
|
||
|
el.replace(&crate::tmpl::xeblog_hero(file, el.get_attribute("prompt")).0, ContentType::Html);
|
||
|
Ok(())
|
||
|
})
|
||
|
```
|
||
|
|
||
|
The result is that I can declare hero images with HTML fragments like this:
|
||
|
|
||
|
```html
|
||
|
<xeblog-hero file="miku-dark-souls" prompt="hatsune miku, elden ring, dark souls, concept art, crowbar"></xeblog-hero>
|
||
|
```
|
||
|
|
||
|
And I get this:
|
||
|
|
||
|
<xeblog-hero file="miku-dark-souls" prompt="hatsune miku, elden ring, dark souls, concept art, crowbar"></xeblog-hero>
|
||
|
|
||
|
<xeblog-conv name="Mara" mood="hacker">This is powered by the
|
||
|
[`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
|
||
|
tag, which is a new discovery to us. This is probably one of the most useful
|
||
|
tags we never knew about and removed the need to write a bunch of annoying CSS
|
||
|
and HTML.</xeblog-conv>
|
||
|
|
||
|
The webp and AVIF versions of the hero images have a higher resolution version
|
||
|
so that it looks nicer on retina screens. However, the png versions of these are
|
||
|
locked to a resolution of 800x356 pixels because I was unable to crush them
|
||
|
below a size of half a megabyte at full resolution. Realistically, this should
|
||
|
only affect older browsers on slower hardware, so I don't expect this to have
|
||
|
too much impact on most users.
|
||
|
|
||
|
<xeblog-conv name="Cadey" mood="coffee">If you don't want to see these hero
|
||
|
images, you can remove them with a userstyle like this:
|
||
|
```css
|
||
|
figure.hero {
|
||
|
display: none;
|
||
|
}
|
||
|
```
|
||
|
</xeblog-conv>
|
||
|
|
||
|
I'm likely going to convert over most of my website templates to use Maud. I'm
|
||
|
very happy with it and I think it is incredibly useful to express your HTML in
|
||
|
Rust instead of something that has to be compiled to Rust. In practice it
|
||
|
reminds me of the Nim library [emerald](http://flyx.github.io/emerald/), which
|
||
|
lets you write HTML using Nim functions similar to how you use Maud.
|
||
|
|
||
|
Here's a few more examples of hero images I have generated:
|
||
|
|
||
|
<xeblog-hero file="the-forbidden-shape" prompt="the forbidden shape"></xeblog-hero>
|
||
|
|
||
|
<xeblog-hero file="great-wave-cyberpunk" prompt="the great wave off of kanagawa, cyberpunk, hanzi inscription"></xeblog-hero>
|
||
|
|
||
|
Normally I will only have one image per post and it will usually be after the
|
||
|
introduction paragraph. The prompt will usually be related to the article topic,
|
||
|
but sometimes I will take artistic liberty. If you have suggestions for prompts,
|
||
|
please [contact me](/contact) with those ideas.
|
||
|
|
||
|
I hope these updates on how I've been messing with my site are interesting. I'm
|
||
|
trying to capture the spirit of how I'm implementing these changes as well as
|
||
|
details of how everything fits together.
|