-
Notifications
You must be signed in to change notification settings - Fork 1
/
jquery-full-house.js
199 lines (154 loc) · 4.06 KB
/
jquery-full-house.js
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
Based on this script by Marcus Ekwall
http://jsfiddle.net/mekwall/fNyHs/
Examples, support and the newest version of this script is here:
https://github.com/kuchumovn/jquery-full-house
Author: Nikolay Kuchumov
github: kuchumovn
email: kuchumovn@gmail.com
*/
(function($)
{
var Algorythm =
{
// you can write your own algorythm
Interface: function(options)
{
// called if the 'x' font size is too big, and the text with this font size doesn't fit the container
this.too_big = function(x) {}
// called if the text with font size 'x' fits the container (e.g. font_size=0 fits any container)
this.fits = function(x) {}
// this.retry(x) function will be set automatically
},
// just for reference
Linear: function(options)
{
var largest_fit = 0
this.too_big = function(x)
{
if (x - 1 === largest_fit)
return largest_fit
return this.retry(x - 1)
}
this.fits = function(x)
{
largest_fit = x
return this.retry(x + 1)
}
},
// the faster algorythm
Binary: function(options)
{
var largest_fit
var minimum_too_big
var step = options.Font_size_increment_step || 10
this.too_big = function(x)
{
minimum_too_big = x
if (largest_fit)
{
if (largest_fit === x - 1)
return largest_fit
return this.retry(largest_fit + (x - largest_fit) / 2)
}
else
{
if (x === 1)
return 1
return this.retry(x - step)
}
}
this.fits = function(x)
{
largest_fit = x
if (minimum_too_big)
{
if (minimum_too_big === x + 1)
return x
return this.retry(x + (minimum_too_big - x) / 2)
}
else
{
return this.retry(x + step)
}
}
}
}
function get_initial_font_size(container)
{
if (container.css('fontSize'))
{
var check = container.css('fontSize').match(/[\d]+px/)
if (check.length)
return parseInt(check[0])
}
return 1
}
function find_max_font_size(container, options)
{
var initial_font_size = get_initial_font_size(container)
container.css('fontSize', 0)
var html = container.html()
container.empty()
var overflow = container.css('overflow')
container.css('overflow', 'hidden')
var sandbox = $('<span/>').html(html).appendTo(container)
var available_height = container.outerHeight()
var available_width = container.outerWidth()
function try_font_size(font_size)
{
container.css({ fontSize: font_size + 'px' })
}
function is_too_big(font_size)
{
font_size = Math.ceil(font_size)
if (font_size < 1)
font_size = 1
try_font_size(font_size)
var current_height = container[0].scrollHeight
var current_width = container[0].scrollWidth
var height_proportion = current_height / available_height
var width_proportion = current_width / available_width
return height_proportion > 1 || width_proportion > 1
}
function recursive_search(algorythm, start_with)
{
var find_max_font_size_starting_with = function(font_size)
{
font_size = Math.ceil(font_size)
if (is_too_big(font_size))
return algorythm.too_big(font_size)
else
return algorythm.fits(font_size)
}
algorythm.retry = find_max_font_size_starting_with
return find_max_font_size_starting_with(start_with)
}
options.algorythm = options.algorythm || 'Binary'
var algorythm = new Algorythm[options.algorythm](options)
function find_font_size()
{
if (options.max_font_size && !is_too_big(options.max_font_size))
return options.max_font_size
if (options.min_font_size && is_too_big(options.min_font_size))
return options.min_font_size
return recursive_search(algorythm, initial_font_size)
}
var font_size = find_font_size()
container.css('overflow', overflow)
container.empty().html(html)
return font_size
}
$.fn.fill_with_text = function(options)
{
options = options || {}
return $(this).each(function()
{
var container = $(this)
container.css({ fontSize: find_max_font_size(container, options) + 'px' })
if (options.collapse)
container.css('height', 'auto')
})
}
})
(jQuery);