Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
large-type
<!DOCTYPE html>
<html>
<head>
<title>Large Type</title>
<link rel="stylesheet/less" type="text/css" href="style.less">
<script type="text/javascript" src="lib/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="lib/less.min.js"></script>
</head>
<body>
<div class="out"><span contenteditable autofocus>*hello*</span></div>
<div class="sidebar">
<h1>Font</h1>
<ul class="fonts">
<li><input type="radio" name="font" data-font="Times New Roman" checked/></li>
<li><input type="radio" name="font" data-font="Arial"/></li>
<li><input type="radio" name="font" data-font="Courier"/></li>
</ul>
</div>
</body>
<script type="text/javascript" src="script.js"></script>
</html>
$(document).ready(function() {
/**
* Minimum font size, in CSS pixels.
*/
const MIN_SIZE = 10;
var target = {
el: $(".out"),
text: undefined,
h: undefined,
w: undefined,
},
shadow = {
el: target.el
.clone()
.addClass("shadow")
.appendTo("body"),
},
size;
target.text = target.el.children("span");
shadow.text = shadow.el.children("span");
setTarget();
size = parseInt(target.el.css("font-size"));
$(".out").on("keyup", function(event) {
setText($(this).text());
});
$(window).on("resize", function() {
setTarget();
});
$("input[name=font]").on("change", function(event) {
var font = $(this).data("font");
shadow.text.css("font-family", font);
target.text.css("font-family", font);
setText($(".out > span").text());
});
function setText(value) {
if (value === "") {
size = MIN_SIZE;
finished();
return;
}
shadow.text.text(value);
// If there are newlines, don't wrap except on newlines.
// Otherwise, wrap normally.
setWrapping(value.indexOf("\n") >= 0 ?
"pre" :
"pre-wrap");
// ±1 offset is to prevent bouncing between sizes
var minSize = isBounded() ? size - 1 : MIN_SIZE,
maxSize = isBounded() ? target.h : size + 1;
while (maxSize - minSize > 1) {
size = Math.floor((minSize + maxSize)/2);
setSize();
if (isBounded()) {
minSize = size;
} else {
maxSize = size;
}
}
finished();
}
function setWrapping(wrapping) {
shadow.text.css("white-space", wrapping);
target.text.css("white-space", wrapping);
}
function setSize() {
shadow.text.css("font-size", size);
}
function finished() {
target.text.css("font-size",size);
}
function isBounded() {
return shadow.text.outerWidth() < target.w &&
shadow.text.outerHeight() < target.h;
}
function setTarget() {
target.h = target.el.innerHeight();
target.w = target.el.innerWidth();
}
});
.out {
position: absolute;
text-align: center;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 1em;
margin: 0;
overflow: hidden;
& > span {
font-family: serif;
font-size: 100px;
white-space: pre-wrap;
}
&:not(.shadow) > span {
transition-property: font-size;
transition-duration: 100ms;
transition-timing-function: ease-in-out;
}
&.shadow {
visibility: hidden;
}
}
.sidebar {
@border: 1px;
@padding: 1em;
position: absolute;
top: 0;
right: ~"calc( -25% - " @border ~" - " 2 * @padding ~")";
bottom: 0;
width: 25%;
padding: 1em;
margin: 0;
background-color: whitesmoke;
border-left: 1px solid grey;
font-family: "Helvetica Neue", sans-serif;
transition: right 250ms ease, box-shadow 100ms linear;
& > ul {
margin: 0;
padding: 0;
list-style-type: none;
& > li {
height: 2em;
line-height: 2em;
margin: 0 -1em;
padding: 0 1em;
}
}
& > h1 {
height: 2em;
line-height: 2em;
margin: 0;
padding: 0;
font-size: medium;
}
&:hover {
right: 0;
box-shadow: 0 0 0.2em fade(black, 50%);
}
&:before {
@color: grey;
@height: 4em;
position: absolute;
font-size: 200%;
color: @color;
content: "«";
top: ~"calc( 50% - " (@height + 2 * @padding/4) / 2 ~" - " 2 * @border ~")";
left: -1em;
padding: @padding/4;
line-height: @height;
border: @border solid @color;
border-right: 0;
border-radius: @padding/4;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
background-color: whitesmoke;
}
@media print {
display: none;
}
}
.sidebar .fonts {
input {
display: block;
position: relative;
font-family: attr(data-font); // Doesn't work in Safari
width: ~"calc( 100% + 2em )";
height: 100%;
line-height: 2em;
margin: 0 -1em;
padding: 0 1em;
cursor: pointer;
font-size: initial;
// Make it look like not a radio element
-webkit-appearance: none;
&:after {
content: attr(data-font);
font-family: attr(data-font);
}
@shadow: 0 0 0.25em fade(black, 10%);
&:hover, &:checked {
background-color: lighten(whitesmoke,10%);
box-shadow: @shadow;
}
&:checked {
box-shadow: @shadow inset;
cursor: initial;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment