brb in an hr
This commit is contained in:
@@ -1,2 +1,59 @@
|
||||
# this-must-be-the-place--mural--colorblock-fx
|
||||
|
||||
|
||||
A canvas-based sign-painted block letter effect — white face, red mid-layer, black depth — inspired by the ["This Must Be The Place"](https://www.thebanner.com/community/local-news/this-must-be-the-place-mural-painted-espo-DMKP5D3IJNCWZEDL6NW6JOGKCE/) mural.
|
||||
|
||||

|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
No build step. Open either file directly in a browser.
|
||||
|
||||
|
||||
## How the effect works
|
||||
|
||||
Three canvas draw passes, back to front:
|
||||
|
||||
```
|
||||
1. Deep layer — drawn at offset (i, i) for i = depth…1 → black
|
||||
2. Mid layer — drawn at offset (i, i) for i = depth×0.55…1 → red
|
||||
3. Face layer — drawn at (0, 0) → white
|
||||
```
|
||||
|
||||
This simulates physically mounted block letters casting a red then black shadow, the same technique used in hand-painted signs and murals.
|
||||
|
||||
## Embedding in your own page
|
||||
|
||||
Copy `embed.html` or paste the snippet below. The only dependency is the [Bebas Neue](https://fonts.google.com/specimen/Bebas+Neue) Google Font (falls back to Impact).
|
||||
|
||||
```html
|
||||
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet">
|
||||
|
||||
<div style="background:#1a1a1a;padding:1rem;border-radius:8px;">
|
||||
<canvas id="sign"></canvas>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
blockLetterFX(document.getElementById('sign'), 'YOUR TEXT HERE');
|
||||
</script>
|
||||
|
||||
<script src="block-letter-fx.js"></script>
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```js
|
||||
blockLetterFX(canvas, text, {
|
||||
faceColor: '#f0f0f0', // letter face
|
||||
midColor: '#cc2200', // red mid-layer
|
||||
deepColor: '#111111', // black depth
|
||||
depthPct: 0.09, // extrusion as fraction of font size (0–0.25)
|
||||
spacing: 2, // letter-spacing in px
|
||||
padding: 28, // horizontal padding in px
|
||||
})
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
(function (root, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = factory();
|
||||
else root.blockLetterFX = factory();
|
||||
})(typeof self !== 'undefined' ? self : this, function () {
|
||||
|
||||
var DEFAULT_OPTS = {
|
||||
faceColor: '#f0f0f0',
|
||||
midColor: '#cc2200',
|
||||
deepColor: '#111111',
|
||||
depthPct: 0.09,
|
||||
spacing: 2,
|
||||
padding: 28,
|
||||
};
|
||||
|
||||
function draw(canvas, text, opts) {
|
||||
opts = Object.assign({}, DEFAULT_OPTS, opts || {});
|
||||
text = (text || '').trim() || 'BLOCK LETTER FX';
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
var DPR = window.devicePixelRatio || 1;
|
||||
var LETTER_SPACING = opts.spacing;
|
||||
var maxW = canvas.parentElement
|
||||
? canvas.parentElement.clientWidth - opts.padding * 2
|
||||
: 600;
|
||||
|
||||
var fontSize = Math.round(maxW * 0.11);
|
||||
ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
|
||||
var textW = ctx.measureText(text).width + LETTER_SPACING * text.length;
|
||||
while (textW > maxW && fontSize > 8) {
|
||||
fontSize--;
|
||||
ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
|
||||
textW = ctx.measureText(text).width + LETTER_SPACING * text.length;
|
||||
}
|
||||
|
||||
var depth = Math.round(fontSize * opts.depthPct);
|
||||
var padY = Math.round(fontSize * 0.2);
|
||||
var cssW = textW + opts.padding * 2;
|
||||
var cssH = fontSize + padY * 2 + depth;
|
||||
|
||||
canvas.width = Math.round(cssW * DPR);
|
||||
canvas.height = Math.round(cssH * DPR);
|
||||
canvas.style.width = cssW + 'px';
|
||||
canvas.style.height = cssH + 'px';
|
||||
|
||||
ctx.scale(DPR, DPR);
|
||||
ctx.clearRect(0, 0, cssW, cssH);
|
||||
ctx.font = 'normal ' + fontSize + 'px "Bebas Neue", Impact, sans-serif';
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.letterSpacing = LETTER_SPACING + 'px';
|
||||
|
||||
var x = opts.padding;
|
||||
var y = padY;
|
||||
|
||||
for (var i = depth; i >= 1; i--) {
|
||||
ctx.fillStyle = opts.deepColor;
|
||||
ctx.fillText(text, x + i, y + i);
|
||||
}
|
||||
for (var i = Math.round(depth * 0.55); i >= 1; i--) {
|
||||
ctx.fillStyle = opts.midColor;
|
||||
ctx.fillText(text, x + i, y + i);
|
||||
}
|
||||
ctx.fillStyle = opts.faceColor;
|
||||
ctx.fillText(text, x, y);
|
||||
}
|
||||
|
||||
function blockLetterFX(canvas, text, opts) {
|
||||
function render() { draw(canvas, text, opts); }
|
||||
if (document.fonts && document.fonts.load) {
|
||||
document.fonts.load('1em "Bebas Neue"').then(render);
|
||||
} else {
|
||||
setTimeout(render, 400);
|
||||
}
|
||||
window.addEventListener('resize', render);
|
||||
return { redraw: render };
|
||||
}
|
||||
|
||||
return blockLetterFX;
|
||||
});
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Reference in New Issue
Block a user