Skip to content

Commit aa28df5

Browse files
committed
Add Sprites template with custom fonts and backgrounds
Introduces a new 'sprites' image template featuring a dark background, halftone pattern, and noise overlay. Adds PolySans and Fricolage Grotesque fonts, supporting CSS and font-face rules. Updates controllers and components to support the new template, and includes required font and image assets.
1 parent 2238f82 commit aa28df5

File tree

8 files changed

+134
-1
lines changed

8 files changed

+134
-1
lines changed

lib/og_image_web/components/layouts.ex

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ defmodule OgImageWeb.Layouts do
3838
src: url(<%= font_to_base64_url("InterVariable-Italic.woff2") %>) format("woff2");
3939
}
4040
41+
@font-face {
42+
font-family: 'PolySans';
43+
font-style: normal;
44+
font-weight: 500;
45+
font-display: swap;
46+
src: url(<%= font_to_base64_url("polysans-median.woff2") %>) format("woff2");
47+
}
48+
49+
@font-face {
50+
font-family: 'Fricolage Grotesque';
51+
font-style: normal;
52+
font-weight: 100 900;
53+
font-display: swap;
54+
src: url(<%= font_to_base64_url("fricolage-grotesque.var.woff2") %>) format("woff2");
55+
}
56+
4157
:root {
4258
font-family: InterVariable, sans-serif;
4359
font-feature-settings: 'liga' 1, 'calt' 1; /* fix for Chrome */
@@ -72,6 +88,30 @@ defmodule OgImageWeb.Layouts do
7288
background-repeat: no-repeat;
7389
<%!-- margin-bottom: 100px; --%>
7490
}
91+
92+
.bg-sprites {
93+
background-color: #000000;
94+
}
95+
96+
.bg-sprites-pattern {
97+
background-image: url(<%= image_to_base64_url("bmxy.png") %>);
98+
background-size: cover;
99+
background-position: center;
100+
}
101+
102+
.bg-sprites-noise {
103+
background-image: url(<%= image_to_base64_url("noise.svg") %>);
104+
background-repeat: repeat;
105+
background-size: 150px 150px;
106+
}
107+
108+
.font-sprites-heading {
109+
font-family: 'PolySans', ui-sans-serif, system-ui, sans-serif;
110+
}
111+
112+
.font-sprites-body {
113+
font-family: 'Fricolage Grotesque', ui-sans-serif, system-ui, sans-serif;
114+
}
75115
</style>
76116
"""
77117
end

lib/og_image_web/controllers/image_controller.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ defmodule OgImageWeb.ImageController do
2828
|> render_image(:light)
2929
end
3030

31+
def show(conn, %{"template" => "sprites", "text" => text}) do
32+
conn
33+
|> assign(:text, prepare_html(text))
34+
|> render_image(:sprites)
35+
end
36+
3137
# -- Add more templates here --
3238

3339
def show(conn, _params) do

lib/og_image_web/controllers/image_html.ex

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,87 @@ defmodule OgImageWeb.ImageHTML do
215215

216216
def clip_text(text, _), do: text # Fallback for non-binary values
217217

218+
@doc """
219+
A logo and text for Sprites on a dark background with halftone pattern.
220+
"""
221+
def sprites(assigns) do
222+
~H"""
223+
<body class="bg-sprites flex h-screen relative overflow-hidden">
224+
<!-- Green halftone pattern layer - diagonal mask from top-right -->
225+
<div class="absolute inset-0 bg-green-600" style="
226+
-webkit-mask-image: linear-gradient(15deg, rgba(0,0,0,0) 45%, rgba(0,0,0,1) 80%);
227+
mask-image: linear-gradient(15deg, rgba(0,0,0,0) 45%, rgba(0,0,0,1) 80%);
228+
">
229+
<div class="absolute inset-0 bg-sprites-pattern"></div>
230+
</div>
231+
232+
<!-- Subtle bottom glow -->
233+
<div class="absolute inset-0 bg-green-600 opacity-10" style="
234+
-webkit-mask-image: linear-gradient(15deg, rgba(0,0,0,1), rgba(0,0,0,0) 50%);
235+
mask-image: linear-gradient(15deg, rgba(0,0,0,1), rgba(0,0,0,0) 50%);
236+
">
237+
<div class="absolute inset-0 bg-sprites-pattern"></div>
238+
</div>
239+
240+
<!-- Noise texture overlay -->
241+
<div class="absolute inset-0 bg-sprites-noise mix-blend-overlay opacity-30 pointer-events-none"></div>
242+
243+
<!-- Main content area -->
244+
<div class="flex-1 flex items-center px-20 relative z-10">
245+
<!-- Text section -->
246+
<div class="flex-1">
247+
<!-- Logo -->
248+
<div class="mb-8 flex items-center gap-4">
249+
<svg class="relative top-px w-auto h-12" viewBox="0 0 724 582" fill-rule="evenodd">
250+
<g>
251+
<path d="M205.594 197.898h322.661v108.263H205.594z" fill="#16a34a" />
252+
<path
253+
d="M578.582 508.799h-72.323v72.686h72.323v-72.686zm-361.614 0h-72.323v72.686h72.323v-72.686zm361.614-290.742h72.323v145.371h-72.323v72.686h-74.229 1.906v72.685H216.968v-72.685h-72.323v-72.686H72.323V218.057h72.322v-73.163h72.323V72.686h72.323v72.685h144.645V72.686h72.323v72.685h72.323v72.686zM72.323 508.799V363.428H0v145.371h72.323zm650.904 0V363.428h-72.322v145.371h72.322zM289.423 290.742h-.132.132zm-72.455-72.685h72.323v72.685h-72.323v-72.685zm216.968 0h72.323v72.685h-72.323v-72.685zM578.582 0h-72.323v72.686h72.323V0zM216.968 0h-72.323v72.686h72.323V0z"
254+
fill="#16a34a"
255+
/>
256+
<path
257+
d="M144.645 363.428V218.057h72.323v-72.686h289.291v72.686h72.323v72.685l-.001.001v72.685h-72.322v72.686h-72.323V508.8H289.291v-72.686h-72.323v-72.686h-72.323zm144.646-72.686h-72.323v-72.685h72.323v72.685zm216.968 0h-72.323v-72.685h72.323v72.685z"
258+
fill="#22c55e"
259+
/>
260+
</g>
261+
</svg>
262+
<span class="font-sprites-heading text-white text-3xl font-medium tracking-[-0.01em]">Sprites</span>
263+
</div>
264+
<%
265+
# Extract string from {:safe, text} tuple if needed
266+
raw_text = case @text do
267+
{:safe, text} -> text
268+
text when is_binary(text) -> text
269+
_ -> to_string(@text)
270+
end
271+
clipped_text = OgImageWeb.ImageHTML.clip_text(raw_text, 20)
272+
text_size_class = OgImageWeb.ImageHTML.get_sprites_text_size(clipped_text)
273+
%>
274+
<h1 class={"font-sprites-heading text-green-500 leading-[1.15] tracking-[-0.02em] break-words max-w-4xl #{text_size_class}"} style="font-weight: 500;">
275+
<%= clipped_text %>
276+
</h1>
277+
</div>
278+
</div>
279+
</body>
280+
"""
281+
end
282+
283+
# Helper function to determine text size for sprites template
284+
def get_sprites_text_size(text) when is_binary(text) do
285+
length = String.length(text)
286+
287+
cond do
288+
length <= 20 -> "text-[4.5rem]"
289+
length <= 35 -> "text-[3.8rem]"
290+
length <= 50 -> "text-[3.2rem]"
291+
length <= 75 -> "text-[2.6rem]"
292+
length <= 100 -> "text-[2.2rem]"
293+
true -> "text-[1.8rem]"
294+
end
295+
end
296+
297+
def get_sprites_text_size(_), do: "text-[4.5rem]"
298+
218299
@doc """
219300
A fallback image.
220301
"""

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"floki": {:hex, :floki, "0.36.1", "712b7f2ba19a4d5a47dfe3e74d81876c95bbcbee44fe551f0af3d2a388abb3da", [:mix], [], "hexpm", "21ba57abb8204bcc70c439b423fc0dd9f0286de67dc82773a14b0200ada0995f"},
1414
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
1515
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
16-
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
16+
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
1717
"honeybadger": {:hex, :honeybadger, "0.21.0", "a81f1db7807c3a250f3c4e81c1baa76b59c27974dafe0ff61b69232346e05060", [:mix], [{:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:hackney, "~> 1.1", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.0.0 and < 2.0.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, ">= 1.0.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "444d7161e105ac2ee70e28c280cb3ad43d42f1d3d9670f2db21efffe9fbe6b0c"},
1818
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
1919
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.3", "67b3d9fa8691b727317e0cc96b9b3093be00ee45419ffb221cdeee88e75d1360", [:mix], [{:mochiweb, "~> 2.15 or ~> 3.1", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "87748d3c4afe949c7c6eb7150c958c2bcba43fc5b2a02686af30e636b74bccb7"},
143 KB
Binary file not shown.

priv/fonts/polysans-median.woff2

18.7 KB
Binary file not shown.

priv/static/images/bmxy.png

72.5 KB
Loading

priv/static/images/noise.svg

Lines changed: 6 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)