mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-22 18:30:09 +00:00
fix(ios): remove white frame from app icon by eliminating alpha channel
iOS renders transparent pixels as white, causing a white frame around the app icon. This fix generates a 1024x1024 RGB PNG (no alpha channel) from the existing build/icons/sq2160x2160.png source. Changes: - Add tools/generate-ios-icon.js script using Sharp to resize and remove alpha - Add npm script 'generate:ios-icon' for reproducible icon generation - Update AppIcon-512@2x.png to RGB format (was RGBA) - Install Sharp as dev dependency for image processing Icon is now fully opaque with correct brand blue color and white checkmark.
This commit is contained in:
parent
522ebb39a7
commit
f2c1c2ab5e
4 changed files with 716 additions and 339 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 44 KiB |
950
package-lock.json
generated
950
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -98,6 +98,7 @@
|
|||
"startFrontend:e2e": "npm run env && ng serve --port=4242",
|
||||
"startFrontend:prod": "npm run env && ng serve --configuration production",
|
||||
"startFrontend:stage": "npm run env && ng serve --configuration stage",
|
||||
"generate:ios-icon": "node tools/generate-ios-icon.js",
|
||||
"sync:android": "npx cap sync android",
|
||||
"sync:ios": "npx cap sync ios",
|
||||
"dist:ios:prod": "npm run buildFrontend:prodWeb && npm run sync:ios",
|
||||
|
|
@ -256,6 +257,7 @@
|
|||
"pretty-quick": "^4.2.2",
|
||||
"query-string": "^7.1.3",
|
||||
"rxjs": "^7.8.2",
|
||||
"sharp": "^0.34.5",
|
||||
"shepherd.js": "^11.2.0",
|
||||
"spark-md5": "^3.0.2",
|
||||
"stacktrace-js": "^2.0.2",
|
||||
|
|
|
|||
103
tools/generate-ios-icon.js
Normal file
103
tools/generate-ios-icon.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate iOS app icon from existing PNG source
|
||||
*
|
||||
* iOS requires a fully opaque 1024x1024 PNG with no alpha channel.
|
||||
* This script resizes the existing logo and ensures it has no alpha channel.
|
||||
*/
|
||||
|
||||
const sharp = require('sharp');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Configuration
|
||||
const ICON_SIZE = 1024;
|
||||
|
||||
// Paths
|
||||
const SOURCE_PNG = path.join(__dirname, '../build/icons/sq2160x2160.png');
|
||||
const OUTPUT_PATH = path.join(
|
||||
__dirname,
|
||||
'../ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png',
|
||||
);
|
||||
|
||||
async function generateIcon() {
|
||||
console.log('🎨 Generating iOS app icon...\n');
|
||||
|
||||
// Step 1: Read source PNG
|
||||
console.log('📖 Reading source PNG:', SOURCE_PNG);
|
||||
|
||||
if (!fs.existsSync(SOURCE_PNG)) {
|
||||
throw new Error(`Source PNG not found: ${SOURCE_PNG}`);
|
||||
}
|
||||
|
||||
console.log('✓ Source PNG found\n');
|
||||
|
||||
// Step 2: Resize and remove alpha channel
|
||||
console.log(`🔄 Resizing to ${ICON_SIZE}x${ICON_SIZE} and removing alpha channel...`);
|
||||
|
||||
const iconBuffer = await sharp(SOURCE_PNG)
|
||||
.resize(ICON_SIZE, ICON_SIZE, {
|
||||
fit: 'cover',
|
||||
position: 'center',
|
||||
})
|
||||
.flatten({ background: { r: 100, g: 149, b: 237 } }) // Fallback background if source has transparency
|
||||
.removeAlpha() // Explicitly remove alpha channel
|
||||
.toColorspace('srgb')
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
console.log('✓ Icon resized\n');
|
||||
|
||||
// Step 3: Write to output file
|
||||
console.log('💾 Writing icon to:', OUTPUT_PATH);
|
||||
|
||||
// Ensure output directory exists
|
||||
const outputDir = path.dirname(OUTPUT_PATH);
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(OUTPUT_PATH, iconBuffer);
|
||||
console.log('✓ Icon written\n');
|
||||
|
||||
// Step 4: Verify output
|
||||
console.log('🔍 Verifying icon properties...');
|
||||
const metadata = await sharp(OUTPUT_PATH).metadata();
|
||||
|
||||
const checks = {
|
||||
Dimensions: metadata.width === ICON_SIZE && metadata.height === ICON_SIZE,
|
||||
Format: metadata.format === 'png',
|
||||
Channels: metadata.channels === 3,
|
||||
'No alpha': !metadata.hasAlpha,
|
||||
'Color space': metadata.space === 'srgb',
|
||||
};
|
||||
|
||||
console.log('\nVerification results:');
|
||||
for (const [check, passed] of Object.entries(checks)) {
|
||||
console.log(` ${passed ? '✅' : '❌'} ${check}: ${passed ? 'PASS' : 'FAIL'}`);
|
||||
}
|
||||
|
||||
console.log('\nMetadata:');
|
||||
console.log(` Size: ${metadata.width}x${metadata.height}`);
|
||||
console.log(` Format: ${metadata.format}`);
|
||||
console.log(` Channels: ${metadata.channels} (${metadata.hasAlpha ? 'RGBA' : 'RGB'})`);
|
||||
console.log(` Color space: ${metadata.space}`);
|
||||
|
||||
const allPassed = Object.values(checks).every((v) => v);
|
||||
|
||||
if (!allPassed) {
|
||||
throw new Error('❌ Icon verification failed! Icon has incorrect properties.');
|
||||
}
|
||||
|
||||
console.log('\n✅ SUCCESS! iOS app icon generated with no alpha channel.');
|
||||
console.log('\nNext steps:');
|
||||
console.log(' 1. Run: npm run sync:ios');
|
||||
console.log(' 2. Test in iOS Simulator/device to verify no white frame');
|
||||
}
|
||||
|
||||
// Run the script
|
||||
generateIcon().catch((error) => {
|
||||
console.error('\n❌ Error generating icon:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue