Skip to content

Commit db079c1

Browse files
authored
Dynamic favicon (#972)
Dynamic favicon
2 parents c4ed883 + be0b819 commit db079c1

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

assets/javascripts/lib/favicon.coffee

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
defaultUrl = null
2+
currentSlug = null
3+
4+
imageCache = {}
5+
urlCache = {}
6+
7+
withImage = (url, action) ->
8+
if imageCache[url]
9+
action(imageCache[url])
10+
else
11+
img = new Image()
12+
img.src = url
13+
img.onload = () =>
14+
imageCache[url] = img
15+
action(img)
16+
17+
@setFaviconForDoc = (doc) ->
18+
return if currentSlug == doc.slug
19+
20+
favicon = $('link[rel="icon"]')
21+
22+
if defaultUrl == null
23+
defaultUrl = favicon.href
24+
25+
if urlCache[doc.slug]
26+
favicon.href = urlCache[doc.slug]
27+
currentSlug = doc.slug
28+
return
29+
30+
styles = window.getComputedStyle($("._icon-#{doc.slug}"), ':before')
31+
32+
bgUrl = styles['background-image'].slice(5, -2)
33+
sourceSize = if bgUrl.includes('@2x') then 32 else 16
34+
sourceX = Math.abs(parseInt(styles['background-position-x'].slice(0, -2)))
35+
sourceY = Math.abs(parseInt(styles['background-position-y'].slice(0, -2)))
36+
37+
withImage(bgUrl, (docImg) ->
38+
withImage(defaultUrl, (defaultImg) ->
39+
size = defaultImg.width
40+
41+
canvas = document.createElement('canvas')
42+
ctx = canvas.getContext('2d')
43+
44+
canvas.width = size
45+
canvas.height = size
46+
ctx.drawImage(defaultImg, 0, 0)
47+
48+
docIconPercentage = 65
49+
destinationCoords = size / 100 * (100 - docIconPercentage)
50+
destinationSize = size / 100 * docIconPercentage
51+
ctx.drawImage(docImg, sourceX, sourceY, sourceSize, sourceSize, destinationCoords, destinationCoords, destinationSize, destinationSize)
52+
53+
urlCache[doc.slug] = canvas.toDataURL()
54+
favicon.href = urlCache[doc.slug]
55+
56+
currentSlug = doc.slug
57+
)
58+
)
59+
60+
@resetFavicon = () ->
61+
if defaultUrl != null and currentSlug != null
62+
$('link[rel="icon"]').href = defaultUrl
63+
currentSlug = null

assets/javascripts/views/content/content.coffee

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ class app.views.Content extends app.View
153153
return
154154

155155
afterRoute: (route, context) =>
156+
if route != 'entry' and route != 'type'
157+
resetFavicon()
158+
156159
switch route
157160
when 'root'
158161
@show @rootPage

assets/javascripts/views/content/entry_page.coffee

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class app.views.EntryPage extends app.View
4040
if app.disabledDocs.findBy 'slug', @entry.doc.slug
4141
@hiddenView = new app.views.HiddenPage @el, @entry
4242

43+
setFaviconForDoc(@entry.doc)
4344
@delay @polyfillMathML
4445
@trigger 'loaded'
4546
return

assets/javascripts/views/content/type_page.coffee

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class app.views.TypePage extends app.View
99

1010
render: (@type) ->
1111
@html @tmpl('typePage', @type)
12+
setFaviconForDoc(@type.doc)
1213
return
1314

1415
getTitle: ->

0 commit comments

Comments
 (0)