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 8 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
57 changes: 57 additions & 0 deletions lib/splash.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const { remove, mkdirp } = require('fs-extra')
const { join } = require('pathe')
const sharp = require('sharp')

const devices = [
xlanex6 marked this conversation as resolved.
Show resolved Hide resolved
kevinmarrec marked this conversation as resolved.
Show resolved Hide resolved
{ 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' }
]

async function splashCreation({ input, distDir, backgroundColor }) {
xlanex6 marked this conversation as resolved.
Show resolved Hide resolved
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)
})
31 changes: 31 additions & 0 deletions src/devices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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


17 changes: 17 additions & 0 deletions src/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ 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
})

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 +74,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: 8 additions & 1 deletion src/meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useNuxt } from '@nuxt/kit'
import type { PWAContext } from './types'
import { join } from 'pathe'
import devices from './devices'

export default (pwa: PWAContext) => {
if (!pwa.meta || !pwa.manifest) { return }
Expand All @@ -16,6 +18,12 @@ export default (pwa: PWAContext) => {
// mobileApp (IOS)
if (options.mobileAppIOS) {
head.meta.push({ name: 'apple-mobile-web-app-capable', content: 'yes' })
for (const device of devices) {
kevinmarrec marked this conversation as resolved.
Show resolved Hide resolved
const href = join(pwa._assetsDir, pwa.icon.targetDir, `${device.width}x${device.height}-splash-screen.png`)
kevinmarrec marked this conversation as resolved.
Show resolved Hide resolved
head.link.push(
{ href, 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" }
)
}
}

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

// TODO: Launch Screen Image (IOS)
}

// Title
Expand Down
2 changes: 1 addition & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default defineNuxtModule<PWAOptions>({
source: null,
sizes: [],
fileName: 'icon.png',
targetDir: 'icons'
targetDir: 'icons',
xlanex6 marked this conversation as resolved.
Show resolved Hide resolved
},
manifest: {
name: process.env.npm_package_name!,
Expand Down