-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathjquery.rm.js
More file actions
160 lines (135 loc) · 5 KB
/
jquery.rm.js
File metadata and controls
160 lines (135 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* Responsive Measure
* http://github.com/jbrewer/Responsive-Measure
*
* August 2012
*
* @version 0.1
* @author Josh Brewer http://jbrewer.me
* @author Mark Christian http://markchristian.org/
* @license MIT
*
* Responsive Measure is a simple script that allows you to pass in a selector (ideally the
* container where your primary content will go) and based on that, finds the ideal font
* size to give you the best measure and then affect your overall design.
* Ideally, it is a resolution independent font-scale based on the ideal font size needed
* to render your ideal measure.
*
*/
(function($) {
'use strict';
function calculateIdealLineLength() {
// Set to Bringhurst's recommendation for an ideal measure
return 66;
}
function fontSizeForIdealLineLength($element, sampleText, maximumFontSize) {
// Add a new element to the DOM with the same width as the element we're trying to size
var $container = $('<div/>').appendTo(document.documentElement);
$container.css({
position: 'absolute',
left: '-9999em',
width: $element.width() + 'px',
visibility: 'hidden'
});
// Put an element in that container with the sample text in it
var $ruler = $('<span/>').appendTo($container);
// Starting with font-size 0, measure the text and bump the size until it wraps onto two lines
var fontSize = 0, heightWithOneLetter, heightWithSampleText;
while (fontSize < maximumFontSize) {
fontSize++;
$ruler.css('font-size', fontSize + 'px');
$ruler.text('M');
heightWithOneLetter = $ruler.height();
$ruler.text(sampleText);
heightWithSampleText = $ruler.height();
if (heightWithSampleText > heightWithOneLetter) {
break;
}
}
// Clean up
$container.remove();
return fontSize - 1;
}
function getSampleText(baseText, idealLineLength) {
// Make sure our sample text is the right length
var sampleText = baseText;
while(sampleText.length < idealLineLength) {
sampleText += " " + baseText;
}
return sampleText.substring(0, idealLineLength).trim();
}
function fontRatiosForFontSize(baseSize, ratio, scaleIncrements, minimumFontSize) {
var scale = [], multiplier, fontSize;
for(var i = -scaleIncrements; i < scaleIncrements; i++) {
if(i < 0) {
multiplier = Math.pow(1/ratio, -i);
} else if(i == 0) {
multiplier = 1;
} else {
multiplier = Math.pow(ratio, i);
}
scale.push(baseSize * multiplier);
}
return scale;
}
function responsiveMeasure(opts) {
var defaultOptions = {
idealLineLength: calculateIdealLineLength,
maximumFontSize: 300,
ratio: 4/3,
scaleIncrements: 5,
sampleText: "Four score and seven years ago, our forefathers were actually five *"
}
opts = $.extend(defaultOptions, opts || {})
if(this.length == 0) {
// We don't match any elements
return;
} else if(this.length != 1) {
// Too many elements
throw new Error("responsiveMeasure must be applied with a selector that matches only one element.");
return;
}
var $element = this;
var idealLineLength = typeof(opts.idealLineLength) == 'function' ? opts.idealLineLength.call(this, $element) : parseInt(opts.idealLineLength, 10);
if (idealLineLength == 0) {
throw new Error("responsiveMeasure was given an ideal line length of 0; this doesn't make any sense. Doing nothing.");
return;
}
var sampleText = getSampleText(opts.sampleText, idealLineLength);
var idealFontSize = fontSizeForIdealLineLength($element, sampleText, opts.maximumFontSize);
if(typeof opts.minimumFontSize != 'undefined') {
idealFontSize = Math.max(idealFontSize, opts.minimumFontSize)
}
var fontRatios = fontRatiosForFontSize(idealFontSize, opts.ratio, opts.scaleIncrements, opts.minimumFontSize);
var $docElement = $(document.documentElement);
$docElement.css('font-size', idealFontSize + 'px');
$docElement.trigger('responsiveMeasureUpdated', {
idealFontSize: idealFontSize,
fontRatios: fontRatios
});
};
$.fn.responsiveMeasure = function(opts) {
// Calculate now
responsiveMeasure.call(this, opts);
// Update when page is resized
var lastUpdateTime = new Date;
var minimumUpdateDelay = 100;
var nextUpdateTimer = null;
$(window).on('resize', function() {
if (new Date - lastUpdateTime < minimumUpdateDelay) {
// It's been less than minimumUpdateDelay milleseconds since the last time we updated;
// wait a while so we don't overwhelm the browser.
if (!nextUpdateTimer) {
nextUpdateTimer = setTimeout(function() {
nextUpdateTimer = null;
responsiveMeasure.call(this, opts);
}.bind(this), minimumUpdateDelay);
}
} else {
// It's been more than minimumUpdatedelay milleseconds; update now
responsiveMeasure.call(this, opts);
}
lastUpdateTime = new Date;
}.bind(this));
}
})(jQuery);