Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
typography/examine.html
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
324 lines (286 sloc)
12.3 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html class="no-js" lang=""> | |
<head> | |
<meta charset="utf-8"> | |
<title>Letterform crop</title> | |
<link rel="preload" href="https://use.typekit.net/djb2ljb.css" as="style" crossorigin> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="manifest" href="site.webmanifest"> | |
<link rel="apple-touch-icon" href="icon.png"> | |
<link rel="stylesheet" href="css/normalize.css"> | |
<link rel="stylesheet" href="css/main.css"> | |
<meta name="theme-color" content="#fafafa"> | |
<link rel="stylesheet" href="https://use.typekit.net/djb2ljb.css"> | |
<script src="https://kit.fontawesome.com/5e541f73d9.js" crossorigin="anonymous"></script> | |
<style> | |
main { | |
max-width: 115rem; | |
} | |
.wrapper { | |
display: grid; | |
grid-template-areas: "instructions canvas" "controls canvas"; | |
grid-gap: 20px; | |
} | |
.canvas-container { | |
grid-area: canvas; | |
} | |
canvas, | |
#gallery img { | |
border: 3px solid #ccc; | |
width: 100%; | |
} | |
.controls { | |
grid-area: controls; | |
padding: 10px; | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
} | |
.controls button, | |
.controls select { | |
margin-bottom: 1rem; | |
} | |
.controls label { | |
display: block; | |
} | |
.info { | |
grid-area: instructions; | |
padding: 10px; | |
background-color: seashell; | |
} | |
#gallery { | |
display: grid; | |
grid-template-columns: 1fr 1fr 1fr 1fr; | |
grid-gap: 1em; | |
margin-top: 2rem; | |
} | |
#gallery a { | |
display: block; | |
transition: all 0.3s ease-in; | |
} | |
#gallery a:hover { | |
box-shadow: 0 20px 20px rgba(0, 0, 0, 0.1); | |
transform: translateY(-10px); | |
} | |
#save { | |
background-color: var(--tomato); | |
-webkit-appearance: none; | |
border: 0; | |
color: white; | |
padding: 1rem; | |
} | |
#clear { | |
margin-left: auto; | |
} | |
</style> | |
</head> | |
<body> | |
<main> | |
<span class="sr-only">Warning! This app is visually heavy as allows a user to scale a letter and examine the details of form and counterform.</span> | |
<a href="#accessibility-settings" class="sr-only">Jump to accessibility settings</a> | |
<nav class="lesson" aria-pressed="false"> | |
<div class="nav--meta"> | |
<i class="fas fa-bars"></i> | |
<h1>Examine a Letterform</h1> | |
</div> | |
<a href="index.html" id="return" style="margin-bottom: 20px">« Return to lessons</a> | |
</nav> | |
<h1>Examine a letterform</h1> | |
<div class="wrapper"> | |
<section class="info"> | |
<p><strong>Type</strong> any character to change the letterform.</p> | |
<p><strong>Click and drag</strong> in the canvas to position a letter.</p> | |
<p><strong>Scale and crop</strong> the letter until it becomes abstracted to better see details of the form and counterform.</p> | |
<p>Image states can be saved. <strong>Click</strong> any saved state to download it. The gallery will save in the browser if you refresh.</p> | |
</section> | |
<section class="controls"> | |
<div> | |
<label for="fontsize">Font size:</label> | |
<input type="range" id="fontsize" name="fontsize" value="800" min="400" max="1500"> | |
</div> | |
<div> | |
<label for="fontfamily">Font Family:</label> | |
<select id="fontfamily" name="fontfamily"> | |
<optgroup label="Serif"> | |
<option value="baskerville-urw">Baskerville</option> | |
<option value="bodoni-urw">Bodoni</option> | |
<option value="adobe-caslon-pro">Caslon</option> | |
<option value="garamond-premier-pro">Garamond</option> | |
<option value="times" selected>Times</option> | |
<option value="hoefler text">Hoefler Text</option> | |
<option value="mrs-eaves">Mrs. Eaves</option> | |
</optgroup> | |
<optgroup label="Sans Serif"> | |
<option value="futura-pt">Futura</option> | |
<option value="gill-sans-nova">Gill Sans</option> | |
<option value="gill-sans-nova-condensed">Gill Sans Condensed</option> | |
<option value="gill-sans-nova-inline">Gill Sans Inline</option> | |
<option value="helvetica">Helvetica</option> | |
<option value="monaco">Monaco</option> | |
<option value="optima">Optima</option> | |
</optgroup> | |
</select> | |
</div> | |
<div style="grid-column: 1 / span 2;"> | |
<button id="center">Center text</button> <button id="lock">Lock text</button> | |
<button id="reset">Reset everything</button> | |
</div> | |
<div style="grid-column: 1 / span 2; margin-top: 2rem; display: flex;"><button id="save">Save state</button> <button id="clear" class="hidden">Clear gallery</button></div> | |
</section> | |
<canvas id="cropMe" height="400" width="400"></canvas> | |
</div> | |
<!-- the below forces these fonts to load into the browser --> | |
<div class="font_preload" style="opacity: 0"> | |
<span style="font-family: garamond-premier-pro, serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: adobe-caslon-pro, serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: mrs-eaves, serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: gill-sans-nova, sans-serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: futura-pt, sans-serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: bodoni-urw, serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: baskerville-urw, serif;font-weight: 400;font-style: normal;"></span> | |
<span style="font-family: gill-sans-nova-condensed, sans-serif;font-weight: 500;font-style: normal;"></span> | |
<span style="font-family: gill-sans-nova-inline, sans-serif;font-weight: 700;font-style: normal;"></span> | |
</div> | |
<div id="gallery"> | |
</div> | |
</main> | |
<aside class="accessibility" id="accessibility-settings"> | |
<div class="open-toggle" aria-label="Accessibility panel open button" role="button" aria-pressed="false" tabindex="0"><i class="fas fa-universal-access"></i></div> | |
<h1>Accessibility settings</h1> | |
<label for="font-style">Font style:</label> | |
<select name="font-style" id="font-style" autocomplete="off" style="margin-bottom: 1rem;"> | |
<option value="">Default</option> | |
<option value="opendyslexic">OpenDyslexic</option> | |
<option value="lato">Lato</option> | |
<option value="verdana">Verdana</option> | |
</select> | |
<label for="high-contrast">High contrast:</label> | |
<input type="checkbox" name="high-contrast" id="high-contrast" autocomplete="off"> | |
</aside> | |
<script src="js/vendor/fabric.js"></script> | |
<script src="js/vendor/localforage.js"></script> | |
<script src="js/nav.js"></script> | |
<script> | |
// Variable for the canvas | |
const canvas = new fabric.Canvas('cropMe'); | |
// Variable for the text | |
let text = new fabric.Textbox('a', { | |
fill: '#333', | |
fontSize: 800, | |
editable: false, | |
top: -200, | |
left: 0 | |
}); | |
// create the image array for use later in the gallery | |
let imgSet = []; | |
// Add the text to the canvas | |
canvas.add(text).setActiveObject(text); | |
// Remove controls from the object | |
canvas.item(0).hasControls = canvas.item(0).hasBorders = false; | |
// Grab the font size control and add the event | |
document.getElementById('fontsize').addEventListener('mousemove', function () { | |
text.set({ | |
fontSize: this.value | |
}); | |
canvas.renderAll(); | |
}) | |
// Grab the font family element and add the event | |
document.getElementById('fontfamily').onchange = function () { | |
text.set({ | |
fontFamily: this.value | |
}); | |
canvas.renderAll(); | |
}; | |
// Center element | |
document.getElementById('center').addEventListener('click', function () { | |
text.center(); | |
}) | |
// Reset | |
document.getElementById('reset').addEventListener('click', function () { | |
text.set({ | |
fontSize: 800, | |
text: 'a' | |
}); | |
text.center(); | |
}) | |
// Lock event listener & function | |
let lockBtn = document.getElementById('lock'); | |
let lock = false; | |
lockBtn.addEventListener('click', function () { | |
if (lock === false) { | |
lockBtn.innerHTML = 'Unlock text'; | |
lock = !lock; | |
} else { | |
lockBtn.innerHTML = 'Lock text'; | |
lock = !lock; | |
} | |
}); | |
// Only allow one letter at a time | |
document.body.addEventListener('keyup', event => { | |
// First, check to make sure if the lock is on. If it is, don't proceed. | |
if (lock === true) { | |
return; | |
} | |
if (event.key.length === 1) { | |
let lastChar = event.key.charAt(); | |
text.set({ | |
text: lastChar | |
}); | |
canvas.renderAll(); | |
} | |
}); | |
function renderGallery() { | |
// Render the array on the page | |
document.getElementById('gallery').innerHTML = ''; | |
for (i = 0; i < imgSet.length; i++) { | |
document.getElementById('gallery').innerHTML += '<a href="' + imgSet[i] + '" download="' + i + '.png"><img src="' + imgSet[i] + '" alt=""></a>'; | |
} | |
} | |
// Set the 'clear gallery' button to visible | |
function showClearGalleryButton() { | |
document.getElementById('clear').classList.remove('hidden'); | |
} | |
// Save canvas as base64 data | |
document.getElementById('save').addEventListener('click', function () { | |
imgSet.unshift(canvas.toDataURL()); //set image into the array | |
renderGallery(); | |
showClearGalleryButton(); | |
//Send the array to localStorage | |
localforage | |
.setItem("savedCrops", JSON.stringify(imgSet)) | |
.then((value) => { | |
console.log(value); | |
}) | |
.catch((error) => { | |
console.error(error); | |
}); | |
}); | |
// Clear gallery button | |
document.getElementById('clear').addEventListener('click', function () { | |
document.getElementById('gallery').innerHTML = ''; //remove all images | |
document.getElementById('clear').classList.add('hidden'); // hide the 'clear' button | |
imgSet = []; // clear the array | |
localforage.clear(); //clear localForage | |
}) | |
// Run local forage retrieval | |
function savedCrops() { | |
localforage | |
.getItem("savedCrops") | |
.then((value) => { | |
console.log('localForage ran'); | |
if (value !== null) { | |
imgSet = JSON.parse(value); | |
showClearGalleryButton(); | |
} | |
renderGallery(); | |
}) | |
.catch((error) => { | |
console.error(error); | |
}); | |
} | |
window.addEventListener('load', savedCrops); | |
</script> | |
<script src="js/vendor/modernizr-3.11.2.min.js"></script> | |
<script src="js/main.js"></script> | |
</body> | |
</html> |