← Previous Next →

Scrawl-canvas v8 - Snippets test 006

Editable header text colorizer and animation effect snippets

Color fonts are a real thing. However...

... Support for OpenType SVG fonts in browsers is in active development, with all the caveats that apply to such functionality - see the caniuse site for current details.

This demo does not use color font technology, nor does it attempt to replicate color font functionality. Instead it demonstrates a proof-of-concept application of color design and animation to any text on the web page, typically in HTML header elements, through the use of Scrawl-canvas snippet modules.

Scrawl-canvas font snippets

The snippets in this demo allow developers to apply color, distortion and animation effects to HTML header text blocks. Each header element can personalize the snippet effect applied to it using CSS custom properties, meaning each snippet can create a range of different effects.

Heads up! This technique uses Scrawl-canvas snippet modules, which are experimental. Depending on the header size, and the complexity of the pattern design and animation effect, the technique may lead to heavy computation which can result in excessive power use and slower screen refresh rates.

Note that this demo includes many header examples. The more headers that the snippets get applied to, the longer the initial computation takes, which can lead to a delay to the effects appearing on the page - resulting in an unfortunate FOUT (flash of unstyled text).

Use snippets sparingly!

DOM text and canvas text: These snippets work by matching the font characteristics of the DOM headers and recreating the text in a <canvas> element added inside the header element (progressive enhancement). For accessibility and user experience purposes the DOM text is not removed: users should be able to copy/paste the header text as normal. Users who disable Javascript in their devices should still be able to see the normal, CSS styled header text.

Accessibility controls and checks include:

Details on how to apply these Scrawl-canvas snippets to DOM elements can be found at the end of this page. The following CSS is common to all the examples:

CSS: body { color: black; background-color: transparent; @media (prefers-color-scheme: dark) { color: white; background-color: black; } } main { width: 100%; max-width: 60em; margin: 0 auto; text-align: left; } .demo-header { font-size: 2rem; line-height: 1.15; border: 0; margin: 0; -webkit-hyphens: none; -ms-hyphens: none; hyphens: none; min-height: 1em; caret-color: black; background-color: transparent; font-weight: normal; @media (prefers-color-scheme: dark) { caret-color: white; } @media (min-width: 30em) { font-size: 3rem; } @media (min-width: 40em) { font-size: 4rem; } @media (min-width: 50em) { font-size: 5rem; } }

To note: Javascript is not running in this browser environment. Our apologies, but this demo has not yet been updated to support progressive enhancement.

risograph-text-gradient-snippet

This effect is inspired by Risograph printing which uses a limited color palette, stippling colors to create a gradient effect.

The snippet can be customised using the following --data-??? CSS custom properties:

... And for prefers-color-scheme: dark users:

This snippet reacts to the user preference prefers-contrast: more with the following properties:

Risograph effect - default values CSS: .header-font-sans { font-family: sans-serif; --data-line-adjustment: 2; & u { --SC-include-underline: true; --SC-underline-offset: 0.84; --SC-underline-width: 3; --SC-underline-gap: 4; @media (min-width: 30em) { --SC-underline-offset: 0.85; --SC-underline-width: 4.5; --SC-underline-gap: 5; } @media (min-width: 40em) { --SC-underline-offset: 0.85; --SC-underline-width: 6; --SC-underline-gap: 8; } @media (min-width: 50em) { --SC-underline-offset: 0.86; --SC-underline-width: 8; --SC-underline-gap: 10; } } } HTML: <h4 id="header-test-1" class="demo-header header-font-sans risograph-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua


To note: this is a proof-of-concept demo test - do not use this sort of code in production!

Normally we don't need to care about EnhancedLabel text matching up exactly with HTML text - even in Scrawl-canvas (highly experimental!) snippet code. But in this Demo we're deliberately adding snippets to contenteditable DOM elements, to see if we can match EL text to DOM text. Clicking in each header will reveal the DOM text as a translucent gray over the EL text, so we can compare their relative positioning.

For the most part, horizontal alignment (along the line) appears to be excellent across Chrome/Safari (and Firefox - though that browser doesn't seem to like contenteditable elements with child canvas elements very much). Vertical alignment of the lines of text, however, appears very problematic: experimentation indicates that browsers position lines depending on individual font characteristics and CSS line-height values for the header element.

This demo attempts to fix this by including a CSS custom property - --data-line-adjustment - which we can add to the CSS font declaration to adjust the EL's vertical alignment to match (as closely as possible) the DOM header's text. (Even with this fix, Firefox appears to stamp the canvas text higher than the other browsers, which has a knock-on effect on each snippet's graphical effect.) But this is not a good fix for anything beyond experimentation and/or personal projects.

Risograph effect - variant 1 CSS: .header-font-serif { font-family: serif; --data-line-adjustment: 0; & u { --SC-include-underline: true; --SC-underline-offset: 0.84; --SC-underline-width: 3; --SC-underline-gap: 4; @media (min-width: 30em) { --SC-underline-offset: 0.85; --SC-underline-width: 4.5; --SC-underline-gap: 5; } @media (min-width: 40em) { --SC-underline-offset: 0.85; --SC-underline-width: 6; --SC-underline-gap: 8; } @media (min-width: 50em) { --SC-underline-offset: 0.86; --SC-underline-width: 8; --SC-underline-gap: 10; } } } .risograph-v1 { --data-random-radius: 0.15; --data-outline-width: 0.08; --data-top-color: red; --data-bottom-color: black; --data-outline-color: gold; --data-dark-top-color: red; --data-dark-bottom-color: white; --data-dark-outline-color: gold; } HTML: <h4 id="header-test-2" class="demo-header header-font-serif risograph-header risograph-v1" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

worley-text-gradient-snippet

Worley noise is a form of procedural texture which can be generated and used to simulate textures which look (a bit) like stone, water or biological cells.

The snippet can be customised using the following --data-??? CSS custom properties:

... And for prefers-color-scheme: dark users:

This snippet reacts to the user preference prefers-contrast: more with the following properties:

Scrawl-canvas supports several types of noise generation, including Worley noise - see Demo canvas-052.

Worley effect - default CSS: .header-font-cursive { font-family: cursive; --data-line-adjustment: -22; & u { --SC-include-underline: true; --SC-underline-offset: 0.75; --SC-underline-width: 3; --SC-underline-gap: 4; @media (min-width: 30em) { --SC-underline-width: 4.5; --SC-underline-gap: 5; } @media (min-width: 40em) { --SC-underline-width: 6; --SC-underline-gap: 8; } @media (min-width: 50em) { --SC-underline-width: 8; --SC-underline-gap: 10; } } } HTML: <h4 id="header-test-3" class="demo-header header-font-cursive worley-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua


To note: this doesn't work so well with the default cursive font in any of the major browsers, with the text being offset downwards thus cutting off the bottom of the last line of the text.

Worley effect - variant 1 CSS: .justify-center-test { text-align: center; } .worley-v1 { --data-highlight-color: red; --data-shadow-color: slategray; --data-dark-highlight-color: red; --data-dark-shadow-color: lightslategray; --data-shadow-offset-x: 2; --data-shadow-offset-y: 2; --data-shadow-blur: 1; --data-noise-scale: 40; --data-noise-sum-function: none; } HTML: <h4 id="header-test-4" class="demo-header header-font-sans justify-center-test worley-header worley-v1" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Scrawl-canvas EnhancedLabel entity text can be justified within its template's dimensions; these text snippets will pick up and apply the header block text-align property.

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

Worley effect - variant 2 CSS: .header-font-bungee { font-family: Bungee; --data-line-adjustment: 9; @media (min-width: 30em) { font-size: 2.7rem; } @media (min-width: 40em) { font-size: 3.4rem; } @media (min-width: 50em) { font-size: 4.1rem; } & u { --SC-include-underline: true; --SC-underline-offset: 0.94; --SC-underline-width: 3; --SC-underline-gap: 4; @media (min-width: 30em) { --SC-underline-width: 4.5; --SC-underline-gap: 5; } @media (min-width: 40em) { --SC-underline-width: 6; --SC-underline-gap: 8; } @media (min-width: 50em) { --SC-underline-width: 8; --SC-underline-gap: 10; } } } .justify-right-test { text-align: right; } .worley-v2 { --data-base-color: white; --data-dark-base-color: white; --data-highlight-color: #0760f7; --data-dark-highlight-color: #74c0f2; --data-noise-sum-function: none; --data-noise-output: YminusX; --data-noise-scale: 45; --data-contrast-color: darkred; --data-dark-contrast-color: pink; } HTML: <h4 id="header-test-5" class="demo-header header-font-bungee justify-right-test worley-header worley-v2" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua


To note: some fonts insist on pushing parts of their italicised text at the start/end of a line beyond the box. Annoying, but beyond the scope of this Demo to fix.

animated-highlight-gradient-text-snippet

A simple gradient effect using two colors, spaced along the gradient to make a series of bars. The gradient animates downwards in a repeating pattern.

The snippet can be customised using the following --data-??? CSS custom properties:

... And for prefers-color-scheme: dark users:

This snippet reacts to the user preference prefers-contrast: more with the following properties:

Animated highlight gradient effect - default CSS: .letter-space-px-test { letter-spacing: 4px; } HTML: <h4 id="header-test-6" class="demo-header header-font-sans letter-space-px-test highlight-gradient-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Scrawl-canvas EnhancedLabel entitys include letter spacing functionality; these text snippets will use any CSS letter-spacing property value applied to the header element.

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

Animated highlight gradient effect - variant 1 CSS: .letter-space-em-test { letter-spacing: 0.2em; } .highlight-gradient-v1 { --data-main-color: black; --data-dark-main-color: #faf1d4; --data-highlight-color: orange; --data-dark-highlight-color: #e6a315; --data-gradient-easing: easeInOut; } HTML: <h4 id="header-test-7" class="demo-header header-font-serif letter-space-em-test highlight-gradient-v1 highlight-gradient-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Scrawl-canvas supports eased linear gradients.

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

Animated highlight gradient effect - variant 2 CSS: .highlight-gradient-v2 { --data-main-color: lch(29.2345% 44.2 27); --data-dark-main-color: #5eadd1; --data-highlight-color: lab(52.2345% 40.1645 59.9971); --data-dark-highlight-color: #c5d6fc; --data-contrast-color: darkred; --data-dark-contrast-color: pink; --data-gradient-skew-x: -1; --data-gradient-easing: easeOutIn; } HTML: <h4 id="header-test-8" class="demo-header header-font-bungee highlight-gradient-header highlight-gradient-v2" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Scrawl-canvas supports the use of LAB|LCH and the new OKLAB|OKLCH color strings.

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

bubbles-text-snippet

An animation effect that shows bubbles appearing, rising and expanding inside the text.

The snippet can be customised using the following --data-??? CSS custom properties:

... And for prefers-color-scheme: dark users:

This snippet reacts to the user preference prefers-contrast: more with the following data- attributes:

Bubbles text effect - default values CSS: .header-font-carter-one { font-family: 'Carter One'; --data-line-adjustment: -18; & u { --SC-include-underline: true; --SC-underline-offset: 0.78; --SC-underline-width: 3; --SC-underline-gap: 4; @media (min-width: 30em) { --SC-underline-width: 4; --SC-underline-gap: 6; } @media (min-width: 40em) { --SC-underline-width: 5; --SC-underline-gap: 8; } @media (min-width: 50em) { --SC-underline-width: 6; --SC-underline-gap: 10; } } } HTML: <h4 id="header-test-9" class="demo-header header-font-carter-one bubbles-text-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

Bubbles text effect - variant 1 CSS: .bubbles-text-v1 { --data-text-color: white; --data-outline-color: black; --data-bubble-color: green; --data-bubble-outline-color: gold; --data-dark-text-color: black; --data-dark-outline-color: white; --data-dark-bubble-color: lightgreen; --data-dark-bubble-outline-color: gold; --data-bubble-density: 150; --data-contrast-color: darkred; --data-dark-contrast-color: pink; } HTML: <h4 id="header-test-10" class="demo-header header-font-carter-one bubbles-text-header bubbles-text-v1" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

swirling-stripes-text-snippet

A striped 2-color gradient effect. Animation occurs when the user hovers their browser cursor over the header, which leads to a swirl filter being applied to the text.

The snippet can be customised using the following --data-??? CSS custom properties:

... And for prefers-color-scheme: dark users:

This snippet makes no attempt to react to the prefers-contrast user preference.

Swirling stripes effect - default (animated) HTML: <h4 id="header-test-11" class="demo-header header-font-sans swirling-stripes-header" contenteditable="plaintext-only" > Lorem ipsum dolor <i>sit amet</i> <b>consectetur</b> <u>adipiscing elit</u> magna aliqua </h4>

Lorem ipsum dolor sit amet consectetur adipiscing elit magna aliqua

Applying a Scrawl-canvas snippet to HTML header elements

HTML elements

CSS markup

It turns out that underlining text is really difficult. Scrawl-canvas EnhancedLabel entitys have functionality to apply underline, overline and background highlight text decoration to their text units ... but to get to that stage, we need to add some Scrawl-canvas-unique custom properties to the CSS code to get the underline to appear as we want it in the EL's displayed text:

Using snippets: We apply Scrawl-canvas snippets to HTML elements using Javascript:

JS: import * as scrawl from 'path/to/scrawl-canvas/library'; import myFontEffect from './path/to/required-SC-header-snippet.js'; const headers = document.querySelectorAll('.arbitrary-name'); headers.forEach(el => myFontEffect(scrawl, el));

Testing the responsiveness of the snippets: all the examples have been set up with media queries to change font size in line with browser's viewport width.

Test purpose

Touch test: should work as expected

Annotated code