<div class="demo" style="display: grid; grid-template-columns: 50% 50%; text-align:center;">
<div>
<h2>Text to test</h2>
<div id="test" style="margin-bottom: 2rem;">Mj</div>
<div id="test1" style="margin-bottom: 2rem;">x</div>
</div>
<div>
<h2>Screenshot of text to test</h2>
<div id="screenshot" style="margin-bottom: 2rem;">
</div>
<div id="cropped-screenshot" style="margin-bottom: 2rem;">
</div>
</div>
</div>
<main>
<div class="panel">
<h2>Select a font:</h2>
<label for="fonts">Web Fonts</label>
<select name="fonts" id="fonts">
<option value="Arial">Arial</option>
<option value="Arial Black">'Arial Black'</option>
<option value="Arial Narrow">'Arial Narrow'</option>
<option value="Arial Rounded MT Bold">'Arial Rounded MT Bold'</option>
<option value="Avant Garde">'Avant Garde'</option>
<option value="Calibri">Calibri</option>
<option value="Candara">Candara</option>
<option value="Century Gothic">'Century Gothic'</option>
<option value="Franklin Gothic Medium">'Franklin Gothic Medium'</option>
<option value="Futura">Futura</option>
<option value="Geneva">Geneva</option>
<option value="Gill Sans">'Gill Sans'</option>
<option value="Helvetica Neue">'Helvetica Neue'</option>
<option value="Impact">Impact</option>
<option value="Lucida Grande">'Lucida Grande'</option>
<option value="Optima">Optima</option>
<option value="Segoe UI">'Segoe UI'</option>
<option value="Tahoma">Tahoma</option>
<option value="Trebuchet MS">'Trebuchet MS'</option>
<option value="Verdana">Verdana</option>
<option value="Big Caslon">'Big Caslon'</option>
<option value="Bodoni MT">'Bodoni MT'</option>
<option value="Book Antiqua">'Book Antiqua'</option>
<option value="Calisto MT">'Calisto MT'</option>
<option value="Cambria">Cambria</option>
<option value="Didot">Didot</option>
<option value="Garamond">Garamond</option>
<option value="Georgia">Georgia</option>
<option value="Goudy Old Style">'Goudy Old Style'</option>
<option value="Hoefler Text">'Hoefler Text'</option>
<option value="Lucida Bright">'Lucida Bright'</option>
<option value="Palatino">Palatino</option>
<option value="Perpetua">Perpetua</option>
<option value="Rockwell">Rockwell</option>
<option value="Rockwell Extra Bold">'Rockwell Extra Bold'</option>
<option value="Baskerville">Baskerville</option>
<option value="TimesNewRoman">TimesNewRoman</option>
<option value="Consolas">Consolas</option>
<option value="Courier New">'Courier New'</option>
<option value="Lucida Console">'Lucida Console'</option>
<option value="Lucida Sans Typewriter">'Lucida Sans Typewriter'</option>
<option value="monaco">monaco</option>
<option value="Andale Mono">'Andale Mono'</option>
<option value="Copperplate">Copperplate</option>
<option value="Papyrus">Papyrus</option>
<option value="Brush Script MT">'Brush Script MT'</option>
</select> | <label for="cfont">Custom font</label>
<input type="text" name="cfont" id="cfont"/>
<label for="gfont">Google Fonts</label>
<select name='gfont' id="gfont">
<option>ABeeZee</option>
<option>Abel</option>
<option>Abril Fatface</option>
<option>Aclonica</option>
<option>Acme</option>
<option>Actor</option>
<option>Adamina</option>
<option>Advent Pro</option>
<option>Aguafina Script</option>
<option>Akronim</option>
<option>Aladin</option>
<option>Aldrich</option>
<option>Alef</option>
<option>Alegreya</option>
<option>Alegreya SC</option>
<option>Alegreya Sans</option>
<option>Alegreya Sans SC</option>
<option>Alex Brush</option>
<option>Alfa Slab One</option>
<option>Alice</option>
<option>Alike</option>
<option>Alike Angular</option>
<option>Allan</option>
<option>Allerta</option>
<option>Allerta Stencil</option>
<option>Allura</option>
<option>Almendra</option>
<option>Almendra Display</option>
<option>Almendra SC</option>
<option>Amarante</option>
<option>Amaranth</option>
<option>Amatic SC</option>
<option>Amethysta</option>
<option>Amiri</option>
<option>Anaheim</option>
<option>Andada</option>
<option>Andika</option>
<option>Angkor</option>
<option>Annie Use Your Telescope</option>
<option>Anonymous Pro</option>
<option>Antic</option>
<option>Antic Didone</option>
<option>Antic Slab</option>
<option>Anton</option>
<option>Arapey</option>
<option>Arbutus</option>
<option>Arbutus Slab</option>
<option>Architects Daughter</option>
<option>Archivo Black</option>
<option>Archivo Narrow</option>
<option>Arimo</option>
<option>Arizonia</option>
<option>Armata</option>
<option>Artifika</option>
<option>Arvo</option>
<option>Asap</option>
<option>Asset</option>
<option>Astloch</option>
<option>Asul</option>
<option>Atomic Age</option>
<option>Aubrey</option>
<option>Audiowide</option>
<option>Autour One</option>
<option>Average</option>
<option>Average Sans</option>
<option>Averia Gruesa Libre</option>
<option>Averia Libre</option>
<option>Averia Sans Libre</option>
<option>Averia Serif Libre</option>
<option>Bad Script</option>
<option>Balthazar</option>
<option>Bangers</option>
<option>Basic</option>
<option>Battambang</option>
<option>Baumans</option>
<option>Bayon</option>
<option>Belgrano</option>
<option>Belleza</option>
<option>BenchNine</option>
<option>Bentham</option>
<option>Berkshire Swash</option>
<option>Bevan</option>
<option>Bigelow Rules</option>
<option>Bigshot One</option>
<option>Bilbo</option>
<option>Bilbo Swash Caps</option>
<option>Bitter</option>
<option>Black Ops One</option>
<option>Bokor</option>
<option>Bonbon</option>
<option>Boogaloo</option>
<option>Bowlby One</option>
<option>Bowlby One SC</option>
<option>Brawler</option>
<option>Bree Serif</option>
<option>Bubblegum Sans</option>
<option>Bubbler One</option>
<option>Buda</option>
<option>Buenard</option>
<option>Butcherman</option>
<option>Butterfly Kids</option>
<option>Cabin</option>
<option>Cabin Condensed</option>
<option>Cabin Sketch</option>
<option>Caesar Dressing</option>
<option>Cagliostro</option>
<option>Calligraffitti</option>
<option>Cambay</option>
<option>Cambo</option>
<option>Candal</option>
<option>Cantarell</option>
<option>Cantata One</option>
<option>Cantora One</option>
<option>Capriola</option>
<option>Cardo</option>
<option>Carme</option>
<option>Carrois Gothic</option>
<option>Carrois Gothic SC</option>
<option>Carter One</option>
<option>Caudex</option>
<option>Cedarville Cursive</option>
<option>Ceviche One</option>
<option>Changa One</option>
<option>Chango</option>
<option>Chau Philomene One</option>
<option>Chela One</option>
<option>Chelsea Market</option>
<option>Chenla</option>
<option>Cherry Cream Soda</option>
<option>Cherry Swash</option>
<option>Chewy</option>
<option>Chicle</option>
<option>Chivo</option>
<option>Cinzel</option>
<option>Cinzel Decorative</option>
<option>Clicker Script</option>
<option>Coda</option>
<option>Coda Caption</option>
<option>Codystar</option>
<option>Combo</option>
<option>Comfortaa</option>
<option>Coming Soon</option>
<option>Concert One</option>
<option>Condiment</option>
<option>Content</option>
<option>Contrail One</option>
<option>Convergence</option>
<option>Cookie</option>
<option>Copse</option>
<option>Corben</option>
<option>Courgette</option>
<option>Cousine</option>
<option>Coustard</option>
<option>Covered By Your Grace</option>
<option>Crafty Girls</option>
<option>Creepster</option>
<option>Crete Round</option>
<option>Crimson Text</option>
<option>Croissant One</option>
<option>Crushed</option>
<option>Cuprum</option>
<option>Cutive</option>
<option>Cutive Mono</option>
<option>Damion</option>
<option>Dancing Script</option>
<option>Dangrek</option>
<option>Dawning of a New Day</option>
<option>Days One</option>
<option>Dekko</option>
<option>Delius</option>
<option>Delius Swash Caps</option>
<option>Delius Unicase</option>
<option>Della Respira</option>
<option>Denk One</option>
<option>Devonshire</option>
<option>Dhurjati</option>
<option>Didact Gothic</option>
<option>Diplomata</option>
<option>Diplomata SC</option>
<option>Domine</option>
<option>Donegal One</option>
<option>Doppio One</option>
<option>Dorsa</option>
<option>Dosis</option>
<option>Dr Sugiyama</option>
<option>Droid Sans</option>
<option>Droid Sans Mono</option>
<option>Droid Serif</option>
<option>Duru Sans</option>
<option>Dynalight</option>
<option>EB Garamond</option>
<option>Eagle Lake</option>
<option>Eater</option>
<option>Economica</option>
<option>Ek Mukta</option>
<option>Electrolize</option>
<option>Elsie</option>
<option>Elsie Swash Caps</option>
<option>Emblema One</option>
<option>Emilys Candy</option>
<option>Engagement</option>
<option>Englebert</option>
<option>Enriqueta</option>
<option>Erica One</option>
<option>Esteban</option>
<option>Euphoria Script</option>
<option>Ewert</option>
<option>Exo</option>
<option>Exo 2</option>
<option>Expletus Sans</option>
<option>Fanwood Text</option>
<option>Fascinate</option>
<option>Fascinate Inline</option>
<option>Faster One</option>
<option>Fasthand</option>
<option>Fauna One</option>
<option>Federant</option>
<option>Federo</option>
<option>Felipa</option>
<option>Fenix</option>
<option>Finger Paint</option>
<option>Fira Mono</option>
<option>Fira Sans</option>
<option>Fjalla One</option>
<option>Fjord One</option>
<option>Flamenco</option>
<option>Flavors</option>
<option>Fondamento</option>
<option>Fontdiner Swanky</option>
<option>Forum</option>
<option>Francois One</option>
<option>Freckle Face</option>
<option>Fredericka the Great</option>
<option>Fredoka One</option>
<option>Freehand</option>
<option>Fresca</option>
<option>Frijole</option>
<option>Fruktur</option>
<option>Fugaz One</option>
<option>GFS Didot</option>
<option>GFS Neohellenic</option>
<option>Gabriela</option>
<option>Gafata</option>
<option>Galdeano</option>
<option>Galindo</option>
<option>Gentium Basic</option>
<option>Gentium Book Basic</option>
<option>Geo</option>
<option>Geostar</option>
<option>Geostar Fill</option>
<option>Germania One</option>
<option>Gidugu</option>
<option>Gilda Display</option>
<option>Give You Glory</option>
<option>Glass Antiqua</option>
<option>Glegoo</option>
<option>Gloria Hallelujah</option>
<option>Goblin One</option>
<option>Gochi Hand</option>
<option>Gorditas</option>
<option>Goudy Bookletter 1911</option>
<option>Graduate</option>
<option>Grand Hotel</option>
<option>Gravitas One</option>
<option>Great Vibes</option>
<option>Griffy</option>
<option>Gruppo</option>
<option>Gudea</option>
<option>Gurajada</option>
<option>Habibi</option>
<option>Halant</option>
<option>Hammersmith One</option>
<option>Hanalei</option>
<option>Hanalei Fill</option>
<option>Handlee</option>
<option>Hanuman</option>
<option>Happy Monkey</option>
<option>Headland One</option>
<option>Henny Penny</option>
<option>Herr Von Muellerhoff</option>
<option>Hind</option>
<option>Holtwood One SC</option>
<option>Homemade Apple</option>
<option>Homenaje</option>
<option>IM Fell DW Pica</option>
<option>IM Fell DW Pica SC</option>
<option>IM Fell Double Pica</option>
<option>IM Fell Double Pica SC</option>
<option>IM Fell English</option>
<option>IM Fell English SC</option>
<option>IM Fell French Canon</option>
<option>IM Fell French Canon SC</option>
<option>IM Fell Great Primer</option>
<option>IM Fell Great Primer SC</option>
<option>Iceberg</option>
<option>Iceland</option>
<option>Imprima</option>
<option>Inconsolata</option>
<option>Inder</option>
<option>Indie Flower</option>
<option>Inika</option>
<option>Irish Grover</option>
<option>Istok Web</option>
<option>Italiana</option>
<option>Italianno</option>
<option>Jacques Francois</option>
<option>Jacques Francois Shadow</option>
<option>Jim Nightshade</option>
<option>Jockey One</option>
<option>Jolly Lodger</option>
<option>Josefin Sans</option>
<option>Josefin Slab</option>
<option>Joti One</option>
<option>Judson</option>
<option>Julee</option>
<option>Julius Sans One</option>
<option>Junge</option>
<option>Jura</option>
<option>Just Another Hand</option>
<option>Just Me Again Down Here</option>
<option>Kalam</option>
<option>Kameron</option>
<option>Kantumruy</option>
<option>Karla</option>
<option>Karma</option>
<option>Kaushan Script</option>
<option>Kavoon</option>
<option>Kdam Thmor</option>
<option>Keania One</option>
<option>Kelly Slab</option>
<option>Kenia</option>
<option>Khand</option>
<option>Khmer</option>
<option>Khula</option>
<option>Kite One</option>
<option>Knewave</option>
<option>Kotta One</option>
<option>Koulen</option>
<option>Kranky</option>
<option>Kreon</option>
<option>Kristi</option>
<option>Krona One</option>
<option>La Belle Aurore</option>
<option>Laila</option>
<option>Lakki Reddy</option>
<option>Lancelot</option>
<option>Lateef</option>
<option>Lato</option>
<option>League Script</option>
<option>Leckerli One</option>
<option>Ledger</option>
<option>Lekton</option>
<option>Lemon</option>
<option>Libre Baskerville</option>
<option>Life Savers</option>
<option>Lilita One</option>
<option>Lily Script One</option>
<option>Limelight</option>
<option>Linden Hill</option>
<option>Lobster</option>
<option>Lobster Two</option>
<option>Londrina Outline</option>
<option>Londrina Shadow</option>
<option>Londrina Sketch</option>
<option>Londrina Solid</option>
<option>Lora</option>
<option>Love Ya Like A Sister</option>
<option>Loved by the King</option>
<option>Lovers Quarrel</option>
<option>Luckiest Guy</option>
<option>Lusitana</option>
<option>Lustria</option>
<option>Macondo</option>
<option>Macondo Swash Caps</option>
<option>Magra</option>
<option>Maiden Orange</option>
<option>Mako</option>
<option>Mallanna</option>
<option>Mandali</option>
<option>Marcellus</option>
<option>Marcellus SC</option>
<option>Marck Script</option>
<option>Margarine</option>
<option>Marko One</option>
<option>Marmelad</option>
<option>Martel Sans</option>
<option>Marvel</option>
<option>Mate</option>
<option>Mate SC</option>
<option>Maven Pro</option>
<option>McLaren</option>
<option>Meddon</option>
<option>MedievalSharp</option>
<option>Medula One</option>
<option>Megrim</option>
<option>Meie Script</option>
<option>Merienda</option>
<option>Merienda One</option>
<option>Merriweather</option>
<option>Merriweather Sans</option>
<option>Metal</option>
<option>Metal Mania</option>
<option>Metamorphous</option>
<option>Metrophobic</option>
<option>Michroma</option>
<option>Milonga</option>
<option>Miltonian</option>
<option>Miltonian Tattoo</option>
<option>Miniver</option>
<option>Miss Fajardose</option>
<option>Modak</option>
<option>Modern Antiqua</option>
<option>Molengo</option>
<option>Molle</option>
<option>Monda</option>
<option>Monofett</option>
<option>Monoton</option>
<option>Monsieur La Doulaise</option>
<option>Montaga</option>
<option>Montez</option>
<option>Montserrat</option>
<option>Montserrat Alternates</option>
<option>Montserrat Subrayada</option>
<option>Moul</option>
<option>Moulpali</option>
<option>Mountains of Christmas</option>
<option>Mouse Memoirs</option>
<option>Mr Bedfort</option>
<option>Mr Dafoe</option>
<option>Mr De Haviland</option>
<option>Mrs Saint Delafield</option>
<option>Mrs Sheppards</option>
<option>Muli</option>
<option>Mystery Quest</option>
<option>NTR</option>
<option>Neucha</option>
<option>Neuton</option>
<option>New Rocker</option>
<option>News Cycle</option>
<option>Niconne</option>
<option>Nixie One</option>
<option>Nobile</option>
<option>Nokora</option>
<option>Norican</option>
<option>Nosifer</option>
<option>Nothing You Could Do</option>
<option>Noticia Text</option>
<option>Noto Sans</option>
<option>Noto Serif</option>
<option>Nova Cut</option>
<option>Nova Flat</option>
<option>Nova Mono</option>
<option>Nova Oval</option>
<option>Nova Round</option>
<option>Nova Script</option>
<option>Nova Slim</option>
<option>Nova Square</option>
<option>Numans</option>
<option>Nunito</option>
<option>Odor Mean Chey</option>
<option>Offside</option>
<option>Old Standard TT</option>
<option>Oldenburg</option>
<option>Oleo Script</option>
<option>Oleo Script Swash Caps</option>
<option>Open Sans</option>
<option>Open Sans Condensed</option>
<option>Oranienbaum</option>
<option>Orbitron</option>
<option>Oregano</option>
<option>Orienta</option>
<option>Original Surfer</option>
<option>Oswald</option>
<option>Over the Rainbow</option>
<option>Overlock</option>
<option>Overlock SC</option>
<option>Ovo</option>
<option>Oxygen</option>
<option>Oxygen Mono</option>
<option>PT Mono</option>
<option>PT Sans</option>
<option>PT Sans Caption</option>
<option>PT Sans Narrow</option>
<option>PT Serif</option>
<option>PT Serif Caption</option>
<option>Pacifico</option>
<option>Paprika</option>
<option>Parisienne</option>
<option>Passero One</option>
<option>Passion One</option>
<option>Pathway Gothic One</option>
<option>Patrick Hand</option>
<option>Patrick Hand SC</option>
<option>Patua One</option>
<option>Paytone One</option>
<option>Peddana</option>
<option>Peralta</option>
<option>Permanent Marker</option>
<option>Petit Formal Script</option>
<option>Petrona</option>
<option>Philosopher</option>
<option>Piedra</option>
<option>Pinyon Script</option>
<option>Pirata One</option>
<option>Plaster</option>
<option>Play</option>
<option>Playball</option>
<option>Playfair Display</option>
<option>Playfair Display SC</option>
<option>Podkova</option>
<option>Poiret One</option>
<option>Poller One</option>
<option>Poly</option>
<option>Pompiere</option>
<option>Pontano Sans</option>
<option>Port Lligat Sans</option>
<option>Port Lligat Slab</option>
<option>Prata</option>
<option>Preahvihear</option>
<option>Press Start 2P</option>
<option>Princess Sofia</option>
<option>Prociono</option>
<option>Prosto One</option>
<option>Puritan</option>
<option>Purple Purse</option>
<option>Quando</option>
<option>Quantico</option>
<option>Quattrocento</option>
<option>Quattrocento Sans</option>
<option>Questrial</option>
<option>Quicksand</option>
<option>Quintessential</option>
<option>Qwigley</option>
<option>Racing Sans One</option>
<option>Radley</option>
<option>Rajdhani</option>
<option>Raleway</option>
<option>Raleway Dots</option>
<option>Ramabhadra</option>
<option>Ramaraja</option>
<option>Rambla</option>
<option>Rammetto One</option>
<option>Ranchers</option>
<option>Rancho</option>
<option>Ranga</option>
<option>Rationale</option>
<option>Ravi Prakash</option>
<option>Redressed</option>
<option>Reenie Beanie</option>
<option>Revalia</option>
<option>Ribeye</option>
<option>Ribeye Marrow</option>
<option>Righteous</option>
<option>Risque</option>
<option>Roboto</option>
<option>Roboto Condensed</option>
<option>Roboto Slab</option>
<option>Rochester</option>
<option>Rock Salt</option>
<option>Rokkitt</option>
<option>Romanesco</option>
<option>Ropa Sans</option>
<option>Rosario</option>
<option>Rosarivo</option>
<option>Rouge Script</option>
<option>Rozha One</option>
<option>Rubik Mono One</option>
<option>Rubik One</option>
<option>Ruda</option>
<option>Rufina</option>
<option>Ruge Boogie</option>
<option>Ruluko</option>
<option>Rum Raisin</option>
<option>Ruslan Display</option>
<option>Russo One</option>
<option>Ruthie</option>
<option>Rye</option>
<option>Sacramento</option>
<option>Sail</option>
<option>Salsa</option>
<option>Sanchez</option>
<option>Sancreek</option>
<option>Sansita One</option>
<option>Sarina</option>
<option>Sarpanch</option>
<option>Satisfy</option>
<option>Scada</option>
<option>Scheherazade</option>
<option>Schoolbell</option>
<option>Seaweed Script</option>
<option>Sevillana</option>
<option>Seymour One</option>
<option>Shadows Into Light</option>
<option>Shadows Into Light Two</option>
<option>Shanti</option>
<option>Share</option>
<option>Share Tech</option>
<option>Share Tech Mono</option>
<option>Shojumaru</option>
<option>Short Stack</option>
<option>Siemreap</option>
<option>Sigmar One</option>
<option>Signika</option>
<option>Signika Negative</option>
<option>Simonetta</option>
<option>Sintony</option>
<option>Sirin Stencil</option>
<option>Six Caps</option>
<option>Skranji</option>
<option>Slabo 13px</option>
<option>Slabo 27px</option>
<option>Slackey</option>
<option>Smokum</option>
<option>Smythe</option>
<option>Sniglet</option>
<option>Snippet</option>
<option>Snowburst One</option>
<option>Sofadi One</option>
<option>Sofia</option>
<option>Sonsie One</option>
<option>Sorts Mill Goudy</option>
<option>Source Code Pro</option>
<option>Source Sans Pro</option>
<option>Source Serif Pro</option>
<option>Special Elite</option>
<option>Spicy Rice</option>
<option>Spinnaker</option>
<option>Spirax</option>
<option>Squada One</option>
<option>Sree Krushnadevaraya</option>
<option>Stalemate</option>
<option>Stalinist One</option>
<option>Stardos Stencil</option>
<option>Stint Ultra Condensed</option>
<option>Stint Ultra Expanded</option>
<option>Stoke</option>
<option>Strait</option>
<option>Sue Ellen Francisco</option>
<option>Sunshiney</option>
<option>Supermercado One</option>
<option>Suranna</option>
<option>Suravaram</option>
<option>Suwannaphum</option>
<option>Swanky and Moo Moo</option>
<option>Syncopate</option>
<option>Tangerine</option>
<option>Taprom</option>
<option>Tauri</option>
<option>Teko</option>
<option>Telex</option>
<option>Tenali Ramakrishna</option>
<option>Tenor Sans</option>
<option>Text Me One</option>
<option>The Girl Next Door</option>
<option>Tienne</option>
<option>Timmana</option>
<option>Tinos</option>
<option>Titan One</option>
<option>Titillium Web</option>
<option>Trade Winds</option>
<option>Trocchi</option>
<option>Trochut</option>
<option>Trykker</option>
<option>Tulpen One</option>
<option>Ubuntu</option>
<option>Ubuntu Condensed</option>
<option>Ubuntu Mono</option>
<option>Ultra</option>
<option>Uncial Antiqua</option>
<option>Underdog</option>
<option>Unica One</option>
<option>UnifrakturCook</option>
<option>UnifrakturMaguntia</option>
<option>Unkempt</option>
<option>Unlock</option>
<option>Unna</option>
<option>VT323</option>
<option>Vampiro One</option>
<option>Varela</option>
<option>Varela Round</option>
<option>Vast Shadow</option>
<option>Vesper Libre</option>
<option>Vibur</option>
<option>Vidaloka</option>
<option>Viga</option>
<option>Voces</option>
<option>Volkhov</option>
<option>Vollkorn</option>
<option>Voltaire</option>
<option>Waiting for the Sunrise</option>
<option>Wallpoet</option>
<option>Walter Turncoat</option>
<option>Warnes</option>
<option>Wellfleet</option>
<option>Wendy One</option>
<option>Wire One</option>
<option>Yanone Kaffeesatz</option>
<option>Yellowtail</option>
<option>Yeseva One</option>
<option>Yesteryear</option>
<option>Zeyada</option>
</select>
</div>
</main>
<main style="display:grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr))">
<div class="form-group">
<label for="cap-height">cap-height</label>
<input id="cap-height" type="text"/>
</div>
<div class="form-group">
<label for="x-height">x-height</label>
<input id="x-height" type="text"/>
</div>
<div class="form-group">
<label for="descender-height">descender-height</label>
<input id="descender-height" type="text"/>
</div>
<div class="form-group">
<label for="baseline">baseline</label>
<input id="baseline" type="text"/>
</div>
<div class="form-group">
<label for="baseline2">baseline2</label>
<input id="baseline2" type="text"/>
</div>
</main>
<main>
Inspired by <a href="https://codepen.io/phun-ky/pen/MWWezBb">https://codepen.io/phun-ky/pen/MWWezBb</a> and <a href="https://codepen.io/MisterCurtis/pen/doEzzx">https://codepen.io/MisterCurtis/pen/doEzzx</a>
</main>
<footer id="footer">
<div id="made">
Made with <strong>saturated fat</strong> by <a href="https://phun-ky.net" target="_blank">Alexander Vassbotn Røyne-Helgesen</a>
</div>
<div id="fat">
Buy <strong>me</strong> some <a href="https://www.paypal.me/phunky/20">bacon?</a>
</div>
</footer>
:root{
--fontSize: 200px
}
#test{
line-height: 100%;
font-size: 200px;
width: 300px;
height: 200px;
padding-bottom: 3rem;
font-family: 'If Sans', sans-serif;
background-color: rgb(255, 255, 255);
color: rgb(51, 30, 17);
text-align:center;
margin: 0 auto;
marbin-bottom: 2rem;
flex-grow: 0;
flex-shrink: 0;
}
#test1{
line-height: 100%;
font-size: 200px;
width: 300px;
height: 200px;
padding-bottom: 3rem;
font-family: 'If Sans', sans-serif;
background-color: rgb(255, 255, 255);
color: rgb(51, 30, 17);
text-align:center;
margin: 0 auto;
flex-grow: 0;
flex-shrink: 0;
}
#screenshot{
margin: 0 auto;
}
#cropped-screenshot{
margin: 0 auto
}
.form-group{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 2rem;
}
.form-group input{
-moz-appearance: textfield;
-webkit-appearance: textfield;
appearance: textfield;
border: none;
background-color: transparent;
color: inherit;
text-align: center;
width: 10rem;
font-size: 20pt;
}
label{
font-weight: 500;
margin-bottom: 0.5rem;
}
window.CP.PenTimer.MAX_TIME_IN_LOOP_WO_EXIT = 20000;
/* global html2canvas */
const takeScreenshot = (el, target) =>
html2canvas(el, {
scale: 1
})
.then(canvas => {
target.appendChild(canvas);
});
const getCoordsFromCanvasIndex = (i, canvasWidth) => ({
x: (i / 4) % canvasWidth,
y: Math.floor(i / 4 / canvasWidth)
});
const getFirstAndLastYOfColor = (canvasHolder, avoidColor) => {
const canvas = canvasHolder.querySelector('canvas');
const canvasRect = canvas.getBoundingClientRect();
const ctx = canvas.getContext('2d');
const canvasHeight = ctx.canvas.height;
const canvasWidth = ctx.canvas.width;
console.log(canvasHeight, canvasWidth)
const pixelData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
console.log('pixelData', pixelData.height, pixelData.width)
const pixels = pixelData.data;
const numPixels = pixelData.data.length; //pixelData.width * pixelData.height;
let firstColoredY = false;
let lastColoredY = false;
let firstY = false;
let lastY = false;
let lastIndex = 0;
for (let i = 0; i < numPixels; i += 4) {
const currentColor = getRGBStringFromCanvasIndex(pixels, i);
let {
x,
y
} = getCoordsFromCanvasIndex(i, canvasWidth);
if (firstY === false) {
firstY = y;
} else {
lastY = y;
}
if (currentColor !== avoidColor) {
if (firstColoredY === false) {
firstColoredY = y;
// test by drawing the pixel into the image
drawPixel(canvas, i);
} else {
lastColoredY = y;
lastIndex = i;
}
}
}
drawPixel(canvas, lastIndex);
return {
firstColoredY,
lastColoredY,
firstY,
lastY
};
};
const r = i => i;
const g = i => i + 1;
const b = i => i + 2;
const a = i => i + 3;
const getRGBStringFromCanvasIndex = (pixels, i) => `rgb(${pixels[r(i)]}, ${pixels[g(i)]}, ${pixels[b(i)]})`;
const getRGBfromCanvasIndex = i => ({
r: r(i),
g: g(i),
b: b(i)
});
const setColorOnIndex = (pixelData, i, rgb) => {
const {
r: red,
g: green,
b: blue
} = rgb;
const pixels = pixelData.data;
pixels[r(i)] = red;
pixels[g(i)] = green;
pixels[b(i)] = blue;
return pixels;
};
const drawPixel = (canvas, index) => {
const ctx = canvas.getContext('2d');
const canvasHeight = ctx.canvas.height;
const canvasWidth = ctx.canvas.width;
const pixelData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
const rgb = {
r: 0,
g: 255,
b: 0
};
pixelData.data = setColorOnIndex(pixelData, index, rgb);
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.putImageData(pixelData, 0, 0);
};
const init = () => {
const FONT_SIZE = parseInt(getComputedStyle(document.documentElement)
.getPropertyValue('--fontSize')
.replace('px', '')
.replace("\n", ''), 10);
const COLOR_TO_AVOID = 'rgb(255, 255, 255)';
const TYPOGRAPHY_TEST_AREA_CAP_DESC = document.getElementById('test');
const TYPOGRAPHY_TEST_AREA_X_BASELINE = document.getElementById('test1');
const FIRST_SCREENSHOT_CANVAS_HOLDER = document.getElementById('screenshot');
const SECOND_SCREENSHOT_CANVAS_HOLDER = document.getElementById('cropped-screenshot');
const CAP_HEIGHT_VALUE_ELEMENT = document.getElementById('cap-height');
const BASELINE_VALUE_ELEMENT = document.getElementById('baseline');
const BASELINE2_VALUE_ELEMENT = document.getElementById('baseline2');
const DESCENDER_HEIGHT_VALUE_ELEMENT = document.getElementById('descender-height');
const X_HEIGHT_VALUE_ELEMENT = document.getElementById('x-height');
let START_CAP_HEIGHT_VALUE;
let STOP_CAP_HEIGHT_VALUE;
let STOP_DESCENDER_HEIGHT_VALUE;
let START_DESCENDER_HEIGHT_VALUE;
let START_X_HEIGHT_VALUE;
let STOP_X_HEIGHT_VALUE;
let BASELINE_VALUE;
const firstCanvases = FIRST_SCREENSHOT_CANVAS_HOLDER.querySelectorAll('canvas');
firstCanvases.forEach(canvas => {
canvas.parentNode.removeChild(canvas);
})
const secondCanvases = SECOND_SCREENSHOT_CANVAS_HOLDER.querySelectorAll('canvas');
secondCanvases.forEach(canvas => {
canvas.parentNode.removeChild(canvas);
})
takeScreenshot(TYPOGRAPHY_TEST_AREA_CAP_DESC, FIRST_SCREENSHOT_CANVAS_HOLDER)
.then(() => {
const {
firstColoredY,
lastColoredY,
firstY,
lastY
} = getFirstAndLastYOfColor(FIRST_SCREENSHOT_CANVAS_HOLDER, COLOR_TO_AVOID);
console.log({
firstY,
lastY
})
START_CAP_HEIGHT_VALUE = firstColoredY;
STOP_DESCENDER_HEIGHT_VALUE = lastColoredY;
});
takeScreenshot(TYPOGRAPHY_TEST_AREA_X_BASELINE, SECOND_SCREENSHOT_CANVAS_HOLDER)
.then(() => {
const {
firstColoredY,
lastColoredY
} = getFirstAndLastYOfColor(SECOND_SCREENSHOT_CANVAS_HOLDER, COLOR_TO_AVOID);
START_X_HEIGHT_VALUE = firstColoredY;
START_DESCENDER_HEIGHT_VALUE = lastColoredY;
STOP_X_HEIGHT_VALUE = lastColoredY;
BASELINE_VALUE = lastColoredY;
STOP_CAP_HEIGHT_VALUE = lastColoredY;
DESCENDER_HEIGHT_VALUE_ELEMENT.value = (STOP_DESCENDER_HEIGHT_VALUE - BASELINE_VALUE) / FONT_SIZE;
X_HEIGHT_VALUE_ELEMENT.value = (BASELINE_VALUE - START_X_HEIGHT_VALUE) / FONT_SIZE;
CAP_HEIGHT_VALUE_ELEMENT.value = (BASELINE_VALUE - START_CAP_HEIGHT_VALUE) / FONT_SIZE;
BASELINE_VALUE_ELEMENT.value = BASELINE_VALUE;
BASELINE2_VALUE_ELEMENT.value = BASELINE_VALUE / FONT_SIZE;
console.log({
FONT_SIZE,
START_CAP_HEIGHT_VALUE,
STOP_DESCENDER_HEIGHT_VALUE,
START_X_HEIGHT_VALUE,
START_DESCENDER_HEIGHT_VALUE,
STOP_X_HEIGHT_VALUE,
BASELINE_VALUE,
STOP_CAP_HEIGHT_VALUE
})
});
};
document.getElementById('fonts')
.addEventListener('change', function (e) {
try {
const gfontlink = document.getElementById('gfontlink');
gfontlink.parentNode.removeChild(gfontlink);
} catch (e) {}
document.getElementById('test')
.style.fontFamily = e.target.value;
document.getElementById('test1')
.style.fontFamily = e.target.value;
init();
})
$('#gfont')
.change(function (e) {
$('#gfontlink')
.remove();
$('head')
.append("<link href='https://fonts.googleapis.com/css?family=" + $(this)
.val() + "' rel='stylesheet' type='text/css' id='gfontlink'>");
$('#test')
.css('font-family', $(this)
.val())
$('#test1')
.css('font-family', $(this)
.val())
init();
});
$('#cfont')
.change(function (e) {
$('#gfontlink')
.remove();
if($(this)
.val().length > 4)
$('#test')
.css('font-family', $(this)
.val())
$('#test1')
.css('font-family', $(this)
.val())
init();
});
setTimeout(init, 2000);
View Compiled