git.iko.soy/typeable/elm-ui
on master help sign in
Font Adjustment experiment
37e1f06Matthew Griffith
experiments/font-adjustment/FontAdjustment.elm+227−49
@@ -23,14 +23,15 @@ import Html.Attributes
23
23
24
24
25type alias FontAdjustment =
25type alias FontAdjustment =
26+ { lineHeight : Float
26− { capital : Adjustment
27+ , capital : Line
27− , lowercase : Adjustment
28+ , lowercase : Line
28− , baseline : Adjustment
29+ , baseline : Line
29− , descender : Adjustment
30+ , descender : Line
30 }
31 }
31
32
32
33
33−type alias Adjustment =
34+type alias Line =
34 Float
35 Float
35
36
36
37
@@ -42,20 +43,30 @@ edges =
42 { top = 0, right = 0, bottom = 0, left = 0 }
43 { top = 0, right = 0, bottom = 0, left = 0 }
43
44
44
45
46+default =
47+ { capital = 1.15
48+ , lowercase = 0.96
49+ , baseline = 0.465
50+ , descender = 0.245
51+ , lineHeight = 1.5
52+ }
53+
54+
45init =
55init =
46 { adjustment =
56 { adjustment =
47− { capital = 0.07
57+ default
48− , lowercase = 0.57
58+ , converted =
49− , baseline = 0.265
59+ convertAdjustment default
50− , descender = 0.755
51− }
52 }
60 }
53
61
54
62
55update msg model =
63update msg model =
56 case msg of
64 case msg of
57 UpdateAdjustment adj ->
65 UpdateAdjustment adj ->
66+ { model
58− { model | adjustment = adj }
67+ | adjustment = adj
68+ , converted = convertAdjustment adj
69+ }
59
70
60
71
61main =
72main =
@@ -71,15 +82,26 @@ view model =
71 [ Background.color (rgba 1 1 1 1)
82 [ Background.color (rgba 1 1 1 1)
72 , Font.color (rgba 0 0 0 1)
83 , Font.color (rgba 0 0 0 1)
73 , Font.family
84 , Font.family
74− [ Font.external
85+ [ -- Font.external
75− { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
86+ -- { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
76− , name = "EB Garamond"
87+ -- , name = "EB Garamond"
88+ -- }
89+ Font.external
90+ { url = "https://fonts.googleapis.com/css?family=Catamaran"
91+ , name = "Catamaran"
77 }
92 }
78 , Font.sansSerif
93 , Font.sansSerif
79 ]
94 ]
80 ]
95 ]
81 <|
96 <|
97+ column [ width fill, height fill, spacing 128 ]
82− adjustor 240 model.adjustment
98+ [ adjustor 120 model.adjustment
99+ , adjusted 120 model.converted
100+ ]
101+
102+
103+style name val =
104+ htmlAttribute (Html.Attributes.style name val)
83
105
84
106
85fontSize pixels lineHeight up =
107fontSize pixels lineHeight up =
@@ -103,9 +125,159 @@ charcoal =
103 rgb 0.7 0.7 0.7
125 rgb 0.7 0.7 0.7
104
126
105
127
128+adjustor size adjustment =
129+ let
130+ labels =
131+ [ viewAdjustment "Type Height" adjustment.capital size 180 adjustment.lineHeight (\capital -> { adjustment | capital = capital })
132+ , viewAdjustment "Lowercase Height" adjustment.lowercase size 60 adjustment.lineHeight (\lowercase -> { adjustment | lowercase = lowercase })
133+ , viewAdjustment "Baseline" adjustment.baseline size 120 adjustment.lineHeight (\baseline -> { adjustment | baseline = baseline })
134+ , viewAdjustment "Descender" adjustment.descender size 0 adjustment.lineHeight (\descender -> { adjustment | descender = descender })
135+ ]
136+ in
137+ el
138+ ([ centerX
139+ , centerY
140+ , Background.color (rgb 0 0.8 0.9)
141+ , style "line-height" (String.fromFloat adjustment.lineHeight)
142+ , onRight
143+ (el
144+ [ centerY
145+ , width (px 40)
146+
147+ -- , height (px (round (toFloat size * (1 / 1.5))))
148+ , height (px size)
149+ , Background.color (rgb 0.9 0.8 0)
150+ ]
151+ none
152+ )
153+ , Font.size size
154+ ]
155+ ++ labels
156+ )
157+ (text "Typography")
158+
159+
160+adjusted size adjustment =
161+ row
162+ [ centerX
163+ , centerY
164+ , spacing 32
165+ , Font.size 120
166+ ]
167+ [ el
168+ [ Background.color (rgb 0 0.8 0.9)
169+ , style "line-height" "normal"
170+ , above (el [ Font.size 12 ] (text "line-height: normal"))
171+ ]
172+ (text "Typography")
173+ , el
174+ [ Background.color (rgb 0 0.8 0.9)
175+ , style "line-height" "1"
176+ , above (el [ Font.size 12 ] (text "line-height: 1"))
177+ ]
178+ (text "Typography")
179+ , corrected adjustment.full "corrected"
180+ , corrected adjustment.capital "corrected capital"
181+ , paragraph [ Font.size 25, spacing 5, width (px 200) ]
182+ [ el [ Font.size 55, alignLeft ] (text "L")
183+ , text "orem Ipsum is simply dummy text of the printing and typesetting industry."
184+ ]
185+ ]
186+
187+
188+corrected converted label =
189+ el
190+ [ Background.color (rgb 0 0.8 0.9)
191+ , style "display" "block"
192+ , above (el [ Font.size 12, moveUp 6 ] (text label))
193+ , style "line-height" (String.fromFloat converted.height)
194+ , below
195+ (column [ Font.size 12, spacing 5, moveDown 10 ]
196+ [ text ("height: " ++ String.left 5 (String.fromFloat converted.height))
197+ , text ("vertical: " ++ String.left 5 (String.fromFloat converted.vertical))
198+ ]
199+ )
200+ ]
201+ (el
202+ [ style "display" "inline-block"
203+ , style "line-height" (String.fromFloat converted.height)
204+ , style "vertical-align" (String.fromFloat converted.vertical ++ "em")
205+ ]
206+ (text "Typography")
207+ )
208+
209+
210+convertAdjustment adjustment =
211+ let
212+ base =
213+ adjustment.lineHeight
214+
215+ normalDescender =
216+ (adjustment.lineHeight - 1)
217+ / 2
218+
219+ oldMiddle =
220+ adjustment.lineHeight / 2
221+
222+ newCapitalMiddle =
223+ ((ascender - newBaseline) / 2) + newBaseline
224+
225+ newFullMiddle =
226+ ((ascender - descender) / 2) + descender
227+
228+ lines =
229+ [ adjustment.capital
230+ , adjustment.baseline
231+ , adjustment.descender
232+ , adjustment.lowercase
233+ ]
234+
235+ ascender =
236+ Maybe.withDefault adjustment.capital (List.maximum lines)
237+
238+ descender =
239+ Maybe.withDefault adjustment.descender (List.minimum lines)
240+
241+ newBaseline =
242+ lines
243+ |> List.filter (\x -> x /= descender)
244+ |> List.minimum
245+ |> Maybe.withDefault adjustment.baseline
246+
247+
248+
249+ capitalVertical =
250+ (oldMiddle - newCapitalMiddle) * 2
251+
252+ fullVertical =
253+ (oldMiddle - newFullMiddle) * 2
254+ in
255+ { full =
256+ { vertical = fullVertical
257+ , height =
258+ (ascender - descender)
259+ - abs fullVertical
260+ }
261+ , capital =
262+ { vertical = capitalVertical
263+ , height = (ascender - newBaseline) - abs capitalVertical
264+ }
265+ }
266+
267+
106−viewAdjustment label adjustment size left updateWith =
268+viewAdjustment label adjustment size left lineHeight updateWith =
269+ let
270+ fullHeight =
271+ toFloat size * 1.5
272+ in
107 onLeft
273 onLeft
274+ (el
275+ [ moveLeft left
276+
277+ -- , moveUp (0.125 * toFloat size)
108− (el [ moveLeft left, moveUp (0.25 * toFloat size), height (px (round (toFloat size * 1.5))) ] <|
278+ , height (px (round (toFloat size * lineHeight)))
279+ ]
280+ <|
109 Input.slider
281 Input.slider
110 [ Font.size 24
282 [ Font.size 24
111 , Element.behindContent
283 , Element.behindContent
@@ -118,13 +290,32 @@ viewAdjustment label adjustment size left updateWith =
118 ]
290 ]
119 Element.none
291 Element.none
120 )
292 )
121− , height (px (round (toFloat size * 1.5)))
293+ , height (px (round fullHeight))
122 , width (px 1)
294 , width (px 1)
295+ , spacing 0
123 , Background.color charcoal
296 , Background.color charcoal
124 , below (el [ centerX ] (text (String.fromFloat adjustment)))
297 , below (el [ centerX ] (text (String.fromFloat adjustment)))
298+ , onRight
299+ (el
300+ [ height (px 0)
301+ , width (px 800)
302+ , moveRight 10
303+ , alignBottom
304+ , moveUp (fullHeight * (adjustment / lineHeight))
305+ , Border.color (rgb 0 0 0)
306+ , Border.dashed
307+ , Border.widthEach
308+ { top = 1
309+ , right = 0
310+ , bottom = 0
311+ , left = 0
312+ }
313+ ]
314+ none
315+ )
125 ]
316 ]
126 { label = Input.labelAbove [ Font.size 18 ] (text "")
317 { label = Input.labelAbove [ Font.size 18 ] (text "")
127− , max = 1.0
318+ , max = lineHeight
128 , min = 0
319 , min = 0
129 , onChange =
320 , onChange =
130 \x ->
321 \x ->
@@ -139,37 +330,24 @@ viewAdjustment label adjustment size left updateWith =
139 , Border.width 1
330 , Border.width 1
140 , Border.color (Element.rgb 0.5 0.5 0.5)
331 , Border.color (Element.rgb 0.5 0.5 0.5)
141 , Background.color (Element.rgb 1 1 1)
332 , Background.color (Element.rgb 1 1 1)
333+
142− , onRight
334+ -- , onRight
143− (el
335+ -- (el
144− [ height (px 0)
336+ -- [ height (px 0)
145− , width (px 1200)
337+ -- , width (px 1200)
146− , moveDown 8
338+ -- , moveDown 8
147− , Border.color charcoal
339+ -- , Border.color (rgb 0 0 0)
148− , Border.dashed
340+ -- , Border.dashed
149− , Border.widthEach
341+ -- , Border.widthEach
150− { top = 1
342+ -- { top = 1
151− , right = 0
343+ -- , right = 0
152− , bottom = 0
344+ -- , bottom = 0
153− , left = 0
345+ -- , left = 0
154− }
346+ -- }
155− ]
347+ -- ]
156− none
348+ -- none
157− )
349+ -- )
158 ]
350 ]
159 , value = adjustment
351 , value = adjustment
160 }
352 }
161 )
353 )
162−
163−
164−adjustor size adjustment =
165− let
166− labels =
167− [ viewAdjustment "Type Height" adjustment.capital size 180 (\capital -> { adjustment | capital = capital })
168− , viewAdjustment "Lowercase Height" adjustment.lowercase size 60 (\lowercase -> { adjustment | lowercase = lowercase })
169− , viewAdjustment "Baseline" adjustment.baseline size 120 (\baseline -> { adjustment | baseline = baseline })
170− , viewAdjustment "Descender" adjustment.descender size 0 (\descender -> { adjustment | descender = descender })
171− ]
172− in
173− el
174− ([ centerX, centerY ] ++ labels ++ fontSize size "1.0" 0)
175− (text "Typography")