Skip to content
This repository has been archived by the owner on May 2, 2024. It is now read-only.

ios splash screen #4

Merged
merged 17 commits into from
May 30, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/splash.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { remove, mkdirp } = require('fs-extra')
const { join } = require('pathe')
const sharp = require('sharp')

async function splashCreation({ input, distDir, backgroundColor, devices }) {
await remove(distDir)
await mkdirp(distDir)
await Promise.all(devices.map(device =>
sharp({
create: {
width: device.width,
height: device.height,
channels: 4,
background: backgroundColor
}
}).composite([
{ input }
])
.png()
.toFile(join(distDir, `${device.width}x${device.height}-splash-screen.png`))
))
}

splashCreation(JSON.parse(process.argv[2])).then(() => {
process.exit(0)
}).catch((error) => {
console.error(error) // eslint-disable-line no-console
process.exit(1)
})
29 changes: 29 additions & 0 deletions src/devices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export default [
{ width: 2732, height: 2048, pixelRatio: 2, orientation: 'landscape' },
{ width: 1668, height: 2388, pixelRatio: 2, orientation: 'portrait' },
{ width: 2388, height: 1668, pixelRatio: 2, orientation: 'landscape' },
{ width: 1536, height: 2048, pixelRatio: 2, orientation: 'portrait' },
{ width: 2048, height: 1536, pixelRatio: 2, orientation: 'landscape' },
{ width: 1668, height: 2224, pixelRatio: 2, orientation: 'portrait' },
{ width: 2224, height: 1668, pixelRatio: 2, orientation: 'landscape' },
{ width: 1620, height: 2160, pixelRatio: 2, orientation: 'portrait' },
{ width: 2160, height: 1620, pixelRatio: 2, orientation: 'landscape' },
{ width: 1284, height: 2778, pixelRatio: 2, orientation: 'portrait' },
{ width: 2778, height: 1284, pixelRatio: 3, orientation: 'landscape' },
{ width: 1170, height: 2532, pixelRatio: 3, orientation: 'portrait' },
{ width: 2532, height: 1170, pixelRatio: 3, orientation: 'landscape' },
{ width: 1125, height: 2436, pixelRatio: 3, orientation: 'portrait' },
{ width: 2436, height: 1125, pixelRatio: 3, orientation: 'landscape' },
{ width: 1242, height: 2688, pixelRatio: 3, orientation: 'portrait' },
{ width: 2688, height: 1242, pixelRatio: 3, orientation: 'landscape' },
{ width: 828, height: 1792, pixelRatio: 2, orientation: 'portrait' },
{ width: 1792, height: 828, pixelRatio: 2, orientation: 'landscape' },
{ width: 1242, height: 2208, pixelRatio: 3, orientation: 'portrait' },
{ width: 2208, height: 1242, pixelRatio: 3, orientation: 'landscape' },
{ width: 750, height: 1334, pixelRatio: 2, orientation: 'portrait' },
{ width: 1334, height: 750, pixelRatio: 2, orientation: 'landscape' },
{ width: 640, height: 1136, pixelRatio: 2, orientation: 'portrait' },
{ width: 1136, height: 640, pixelRatio: 2, orientation: 'landscape' }
]

// https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/#device-screen-sizes-and-orientations
19 changes: 19 additions & 0 deletions src/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import hasha from 'hasha'
import { join, resolve } from 'pathe'
import { useNuxt } from '@nuxt/kit'
import type { PWAContext } from './types'
import devices from './devices'

async function getFileHash (filePath: string): Promise<string> {
const hash = await hasha.fromFile(filePath, { algorithm: 'md5' })
Expand Down Expand Up @@ -54,7 +55,15 @@ export default async (pwa: PWAContext) => {
suffix: iconSuffix
})

const iosSplashSreenOption = JSON.stringify({
input: options.source,
distDir: join(pwa._assetsDir, options.targetDir),
backgroundColor: pwa.manifest.background_color,
devices
})

let generate: Promise<void>
let generateIosSplashScreen: Promise<void>

// Start generation when Nuxt build dir (.nuxt) is available
nuxt.hook('prepare:types', () => {
Expand All @@ -67,10 +76,20 @@ export default async (pwa: PWAContext) => {
}).then(() => {
consola.success(`PWA icons generated in ${Date.now() - start} ms`)
})
generateIosSplashScreen = new Promise<void>((resolve, reject) => {
const child = fork(pwa._resolver.resolve('../lib/splash.cjs'), [iosSplashSreenOption])
child.on('exit', (code: number) => code ? reject(code) : resolve())
}).then(() => {
consola.success(`Splash Screen genrated in ${Date.now() - start} ms`)
})
})

// Ensure icons have been generated before Nitro build
nuxt.hook('nitro:build:before', async () => {
await generate

if (pwa.icon.mobileAppIOS) {
await generateIosSplashScreen
}
})
}
9 changes: 7 additions & 2 deletions src/meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useNuxt } from '@nuxt/kit'
import { join } from 'pathe'
import type { PWAContext } from './types'
import devices from './devices'

export default (pwa: PWAContext) => {
if (!pwa.meta || !pwa.manifest) { return }
Expand All @@ -16,6 +18,11 @@ export default (pwa: PWAContext) => {
// mobileApp (IOS)
if (options.mobileAppIOS) {
head.meta.push({ name: 'apple-mobile-web-app-capable', content: 'yes' })

// inject splash-screen based on devices list
head.link.push(...devices.map(device => (
{ href: `${join(nuxt.options.app.buildAssetsDir, pwa.icon.targetDir, `${device.width}x${device.height}-splash-screen.png`)}`, media: `(device-width: ${device.width / device.pixelRatio}px) and (device-height: ${device.height / device.pixelRatio}px) and (-webkit-device-pixel-ratio: ${device.pixelRatio}) and (orientation: ${device.orientation})`, rel: 'apple-touch-startup-image' }
xlanex6 marked this conversation as resolved.
Show resolved Hide resolved
)))
}

// statusBarStyle (IOS)
Expand All @@ -36,8 +43,6 @@ export default (pwa: PWAContext) => {
head.link.push({ rel: 'shortcut icon', href: iconSmall.src })
head.link.push({ rel: 'apple-touch-icon', href: iconBig.src, sizes: iconBig.sizes })
}

// TODO: Launch Screen Image (IOS)
}

// Title
Expand Down