Meta tweaks
This commit is contained in:
parent
a428a90e55
commit
045533850c
|
@ -1,2 +1 @@
|
|||
* text=auto
|
||||
*.js text eol=lf
|
||||
* text=auto eol=lf
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
os: osx
|
||||
language: node_js
|
||||
node_js:
|
||||
- '12'
|
||||
- '10'
|
||||
- '8'
|
||||
|
|
8
cli.js
8
cli.js
|
@ -117,7 +117,7 @@ async function init() {
|
|||
ee.on('finish', async () => {
|
||||
try {
|
||||
ora.text = 'Replacing DMG icon';
|
||||
// Seticon is a native tool to change files icons (Source: https://github.com/sveinbjornt/osxiconutils)
|
||||
// `seticon`` is a native tool to change files icons (Source: https://github.com/sveinbjornt/osxiconutils)
|
||||
await execa(path.join(__dirname, 'seticon'), [composedIconPath, dmgPath]);
|
||||
|
||||
ora.text = 'Code signing DMG';
|
||||
|
@ -128,9 +128,9 @@ async function init() {
|
|||
} else if (stdout.includes('Mac Developer:')) {
|
||||
identity = 'Mac Developer';
|
||||
} else {
|
||||
const err = new Error();
|
||||
err.stderr = 'No usable identity found';
|
||||
throw err;
|
||||
const error = new Error();
|
||||
error.stderr = 'No usable identity found';
|
||||
throw error;
|
||||
}
|
||||
|
||||
await execa('codesign', ['--sign', identity, dmgPath]);
|
||||
|
|
|
@ -9,7 +9,8 @@ const readFile = promisify(fs.readFile);
|
|||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
const filterMap = (map, filterFn) => Object.entries(map).filter(filterFn).reduce((out, [key, item]) => ({...out, [key]: item}), {});
|
||||
// Drive icon from /System/Library/Extensions/IOStorageFamily.kext/Contents/Resources/Removable.icns
|
||||
|
||||
// Drive icon from `/System/Library/Extensions/IOStorageFamily.kext/Contents/Resources/Removable.icns``
|
||||
const baseDiskIconPath = `${__dirname}/disk-icon.icns`;
|
||||
|
||||
async function composeIcon(type, appIcon, mountIcon, composedIcon) {
|
||||
|
@ -20,11 +21,13 @@ async function composeIcon(type, appIcon, mountIcon, composedIcon) {
|
|||
|
||||
// Change the perspective of the app icon to match the mount drive icon
|
||||
appIcon = appIcon.out('-matte').out('-virtual-pixel', 'transparent').out('-distort', 'Perspective', `1,1 ${appIconSize.width * 0.08},1 ${appIconSize.width},1 ${appIconSize.width * 0.92},1 1,${appIconSize.height} 1,${appIconSize.height} ${appIconSize.width},${appIconSize.height} ${appIconSize.width},${appIconSize.height}`);
|
||||
|
||||
// Resize the app icon to fit it inside the mount icon, aspect ration should not be kept to create the perspective illution
|
||||
appIcon = appIcon.resize(appIconSize.width / 1.7, appIconSize.height / 1.78, '!');
|
||||
|
||||
const tempAppIconPath = tempy.file({extension: 'png'});
|
||||
await promisify(appIcon.write.bind(appIcon))(tempAppIconPath);
|
||||
|
||||
// Compose the two icons
|
||||
const iconGravityFactor = mountIconSize.height * 0.155;
|
||||
mountIcon = mountIcon.composite(tempAppIconPath).gravity('Center').geometry(`+0-${iconGravityFactor}`);
|
||||
|
@ -40,14 +43,16 @@ const hasGm = async () => {
|
|||
if (error.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = async function (appIconPath) {
|
||||
module.exports = async appIconPath => {
|
||||
if (!await hasGm()) {
|
||||
return baseDiskIconPath;
|
||||
}
|
||||
|
||||
const baseDiskIcons = filterMap(icns.parse(await readFile(baseDiskIconPath)), ([key]) => icns.isImageType(key));
|
||||
const appIcon = filterMap(icns.parse(await readFile(appIconPath)), ([key]) => icns.isImageType(key));
|
||||
|
||||
|
@ -56,9 +61,13 @@ module.exports = async function (appIconPath) {
|
|||
if (baseDiskIcons[type]) {
|
||||
return composeIcon(type, icon, baseDiskIcons[type], composedIcon);
|
||||
}
|
||||
|
||||
console.warn('There is no base image for this type', type);
|
||||
}));
|
||||
|
||||
const tempComposedIcon = tempy.file({extension: 'icns'});
|
||||
|
||||
await writeFile(tempComposedIcon, icns.format(composedIcon));
|
||||
|
||||
return tempComposedIcon;
|
||||
};
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 62 KiB |
BIN
icon-example.png
BIN
icon-example.png
Binary file not shown.
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 54 KiB |
|
@ -20,6 +20,7 @@
|
|||
},
|
||||
"files": [
|
||||
"cli.js",
|
||||
"compose-icon.js",
|
||||
"assets",
|
||||
"disk-icon.icns",
|
||||
"seticon"
|
||||
|
@ -45,10 +46,10 @@
|
|||
"meow": "^5.0.0",
|
||||
"ora": "^3.0.0",
|
||||
"plist": "^3.0.1",
|
||||
"tempy": "^0.2.1"
|
||||
"tempy": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^0.25.0",
|
||||
"xo": "^0.23.0"
|
||||
"ava": "^1.4.1",
|
||||
"xo": "^0.24.0"
|
||||
}
|
||||
}
|
||||
|
|
18
readme.md
18
readme.md
|
@ -49,18 +49,20 @@ It will try to code sign the DMG, but the DMG is still created and fine even if
|
|||
|
||||
### DMG Icon
|
||||
|
||||
[GraphicsMagick](http://www.graphicsmagick.org/) is required to create the DMG icon based on the application icon and macOS mounted device icon.
|
||||
[GraphicsMagick](http://www.graphicsmagick.org) is required to create the custom DMG icon that's based on the app icon and the macOS mounted device icon.
|
||||
|
||||
### Steps using Brew
|
||||
```bash
|
||||
brew install imagemagick
|
||||
brew install graphicsmagick
|
||||
#### Steps using Homebrew
|
||||
|
||||
```
|
||||
$ brew install graphicsmagick imagemagick
|
||||
```
|
||||
|
||||
### Icon Example
|
||||
#### Icon Example
|
||||
|
||||
Original icon → DMG icon
|
||||
|
||||
<img src="icon-example-app.png" width="300"><img src="icon-example.png" width="300">
|
||||
|
||||
<img src="icon-example-app.png" width="300">
|
||||
<img src="icon-example.png" width="300">
|
||||
|
||||
## License
|
||||
|
||||
|
|
Loading…
Reference in New Issue