Skip to content

Commit

Permalink
feat: add configurable height
Browse files Browse the repository at this point in the history
  • Loading branch information
jaulz committed Oct 4, 2020
1 parent 2882949 commit 43d80c9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 33 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Badgin

The [Badging API](https://web.dev/badging-api/) is a new web platform API that allows installed web apps to set an application-wide badge, shown in an operating-system-specific place associated with the application (such as the shelf or home screen). Starting in Chrome 73, the Badging API is available as an origin trial for Windows (7+) and macOS. If you want to know how origin trials work, please check the[documentation](https://web.dev/badging-api/#ot). Since this API is not available everywhere, `badgin` safely falls back to alternatives.
The [Badging API](https://web.dev/badging-api/) is a new web platform API that allows installed web apps to set an application-wide badge, shown in an operating-system-specific place associated with the application (such as the shelf or home screen). Starting in Chrome 73, the Badging API is available as an origin trial for Windows (7+) and macOS. If you want to know how origin trials work, please check the [documentation](https://web.dev/badging-api/#ot). Since this API is not available everywhere, `badgin` safely falls back to alternatives.

## via badge

Expand Down
24 changes: 18 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -169,17 +169,29 @@ <h1 class="title">Value</h1>
</style>

<script>
const isLocalhost =
location.hostname === 'localhost' || location.hostname === '127.0.0.1'
const isDevelopment =
location.hostname === 'localhost' ||
location.hostname === '127.0.0.1' ||
location.hostname.endsWith('codespaces.githubusercontent.com')
let value = 0
const options = {
favicon: {},
favicon: {
backgroundColor: '#000000',
color: '#FFFFFF',
indicator: '@',
radius: 3,
size: 7,
horizontalMargin: 1,
verticalMargin: 1,
horizontalPadding: 2,
verticalPadding: 2,
},
}

document.getElementById('set').addEventListener('click', () => {
const value = document.getElementById('value').value
localStorage.setItem('value', value)
badgin.set(value ? parseInt(value, 10) : value, options)
badgin.set(value ? parseInt(value, 10) : undefined, options)
})

document.getElementById('clear').addEventListener('click', () => {
Expand Down Expand Up @@ -223,15 +235,15 @@ <h1 class="title">Value</h1>
})

// Add service worker
if (!isLocalhost && 'serviceWorker' in navigator) {
if (!isDevelopment && 'serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js').then(() => {
console.log('Service Worker Registered')
})
}

// Load script
const script = document.createElement('script')
script.src = isLocalhost
script.src = isDevelopment
? '/build/index.iife.js'
: 'https://unpkg.com/badgin/build/index.iife.js'
script.onload = () => {
Expand Down
76 changes: 50 additions & 26 deletions src/favicon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export type Options = {
color: string
indicator: string
radius: number
size: number
horizontalMargin: number
verticalMargin: number
horizontalPadding: number
verticalPadding: number
}

type Favicon = HTMLLinkElement
Expand All @@ -20,6 +25,11 @@ export const DefaultOptions: Options = {
color: '#ffffff',
indicator: '!',
radius: 3,
size: 7,
horizontalMargin: 0,
verticalMargin: 0,
horizontalPadding: 1,
verticalPadding: 1,
}

// Get all favicons of the page
Expand Down Expand Up @@ -119,10 +129,9 @@ const getRatio = () => {
return Math.ceil(window.devicePixelRatio) || 1
}
const handleRatioChange = () => {
console.log('handleRatioChange')
set(current.value, current.options)
}
const getSize = () => {
const getIconSize = () => {
return 16 * getRatio()
}

Expand Down Expand Up @@ -155,18 +164,18 @@ const drawFavicon = (
value: Value,
options: Options
) => {
const size = getSize()
const iconSize = getIconSize()
const canvas = document.createElement('canvas')
canvas.width = size
canvas.height = size
canvas.width = iconSize
canvas.height = iconSize
const context = canvas.getContext('2d')
if (!context) {
return
}

// Draw new image
image.width = size
image.height = size
image.width = iconSize
image.height = iconSize
context.drawImage(image, 0, 0, image.width, image.height)

// Draw bubble on the top
Expand All @@ -182,6 +191,9 @@ const drawBubble = (
value: Value,
options: Options
) => {
const ratio = getRatio()
const iconSize = getIconSize()

// Do we need to render the bubble at all?
let finalValue: string = ''
if (isPositiveNumber(value)) {
Expand All @@ -201,24 +213,27 @@ const drawBubble = (
return
}

// Calculate text width initially
const textHeight = options.size - 2
const font = `${options.size * ratio}px Arial`
context.font = font
const { width: textWidth } = context.measureText(finalValue)
context.restore()

// Calculate position etc.
const size = getSize()
const ratio = getRatio()
const length = finalValue.length - 1
const width = Math.min(8 * ratio + 4 * ratio * length, size)
const height = 7 * ratio
const top = size - height
const left = size - width
const bottom = 16 * ratio
const right = 16 * ratio
const radius = options.radius * ratio
const width = textWidth + 2 * options.horizontalPadding
const height = textHeight * ratio + 2 * options.verticalPadding
const top = iconSize - height - options.verticalMargin
const left = iconSize - width - options.horizontalMargin
const bottom = 16 * ratio - options.verticalMargin
const right = 16 * ratio - options.horizontalMargin
const radius = options.radius

// Bubble
context.save()
context.globalAlpha = 1
context.fillStyle = options.backgroundColor
context.strokeStyle = options.backgroundColor
context.lineWidth = ratio
context.lineWidth = 0
context.beginPath()
context.moveTo(left + radius, top)
context.quadraticCurveTo(left, top, left, top + radius)
Expand All @@ -230,16 +245,25 @@ const drawBubble = (
context.quadraticCurveTo(right, top, right - radius, top)
context.closePath()
context.fill()
context.restore()
context.save()

// Value
context.save()
context.font = `${7 * ratio}px Arial`
context.font = font
context.fillStyle = options.color
context.textAlign = 'center'
context.textBaseline = 'top'
context.fillText(finalValue, left + width / 2, 9 * ratio + 1)
context.textBaseline = 'hanging'
context.fillText(finalValue, left + width / 2, top + options.verticalPadding)
context.save()

/*
// Helper line
context.restore()
context.strokeStyle = '#ff0000'
context.moveTo(0, top + height / 2)
context.lineTo(iconSize, top + height / 2)
context.stroke()
context.save()
*/
}

export function isAvailable() {
Expand Down Expand Up @@ -276,7 +300,7 @@ export function set(value: Value, options?: Partial<Options>) {
}

// Once the device pixel ratio changes we set the value again
devicePixelRatioListener.addListener(handleRatioChange)
devicePixelRatioListener.addEventListener('change', handleRatioChange)
}
if (!current.favicons) {
current.favicons = getFavicons()
Expand Down Expand Up @@ -311,7 +335,7 @@ export function clear() {
current.options = DefaultOptions

// Remove old listener
devicePixelRatioListener.removeListener(handleRatioChange)
devicePixelRatioListener.removeEventListener('change', handleRatioChange)

if (current.favicons) {
// Remove current favicons
Expand Down

0 comments on commit 43d80c9

Please sign in to comment.