UNPKG

6.2 kBJavaScriptView Raw
1//-------------------------------------
2//-- Icons
3//-------------------------------------
4'use strict';
5
6// const debug = require('gulp-debug');
7const gulp = require('gulp');
8const gm = require('gulp-gm');
9const gulpif = require('gulp-if');
10const imagemin = require('gulp-imagemin');
11const rename = require('gulp-rename');
12const { terminal } = require('@absolunet/terminal');
13const flow = require('~/helpers/flow');
14const paths = require('~/helpers/paths');
15const toolbox = require('~/helpers/toolbox');
16const util = require('~/helpers/util');
17
18
19module.exports = () => {
20 // https://github.com/gleero/grunt-favicons
21 // https://github.com/audreyr/favicon-cheat-sheet
22
23
24 //-- Favicon.ico
25 // https://mathiasbynens.be/notes/rel-shortcut-icon
26 flow.createTask('icons-favicon', () => {
27 const sizes = [
28 16, // IE9 address bar, Pinned site Jump List/Toolbar/Overlay
29 24, // IE9 Pinned site browser UI
30 32, // New tab page in IE, taskbar button in Win 7+, Safari Read Later sidebar
31 48, // Windows site icons
32 64 // Windows site icons, Safari Reading List sidebar in HiDPI/Retina
33 ];
34
35 return util.assetsProcess(paths.files.iconsFavicon, (stream) => {
36
37 return stream
38 .pipe(toolbox.plumber())
39
40 .pipe(gm((gmfile) => {
41 return gmfile
42 .define(`icon:auto-resize=${sizes.join(',')}`)
43 .setFormat('ico')
44 ;
45 }, { imageMagick: true }))
46
47 .pipe(rename(util.assetsRename()))
48 ;
49 });
50 });
51
52
53 //-- Share icons
54 // https://mathiasbynens.be/notes/touch-icons
55 // https://developer.apple.com/ios/human-interface-guidelines/graphics/app-icon/
56 // https://developer.chrome.com/multidevice/android/installtohomescreen
57 // http://operacoast.com/developer
58
59 //-- Touch
60 flow.createTask('icons-touch', () => {
61 const touchSizes = [
62 57, // For non-Retina (@1× display) iPhone, iPod Touch, and Android 2.1+ devices
63 72, // For the iPad mini and the first- and second-generation iPad (@1× display) on iOS ≤ 6
64 76, // For the iPad mini and the first- and second-generation iPad (@1× display) on iOS ≥ 7
65 114, // For iPhone with @2× display running iOS ≤ 6:
66 120, // For iPhone with @2× display running iOS ≥ 7
67 144, // For iPad with @2× display running iOS ≤ 6
68 152, // For iPad with @2× display running iOS ≤ 7
69 167, // For iPad Pro with @2× display running iOS ≤ 9
70 180, // For iPhone 6 Plus with @3× display
71 512 // General share icon
72 ];
73
74 const streams = [];
75
76 // Foreach each sizes
77 for (const size of touchSizes) {
78
79 /* eslint-disable function-paren-newline */
80 streams.push(
81 util.assetsProcess(paths.files.iconsTouch, (stream) => {
82
83 return stream
84 .pipe(toolbox.plumber())
85
86 .pipe(gulpif(size !== 512, gm((gmfile, done) => {
87 gmfile.identify((error, info) => {
88 if (error) {
89 terminal.error(error);
90 }
91 done(null, toolbox.gmOptimization(gmfile.resize(size, size), info));
92 });
93 })))
94
95 .pipe(rename(util.assetsRename(`touch-${size}`)))
96
97 .pipe(imagemin())
98 ;
99 })
100 );
101 /* eslint-disable function-paren-newline */
102 }
103
104 return toolbox.mergeStreams(streams);
105 });
106
107
108 //-- Icons
109 flow.createTask('icons-icon', () => {
110 const iconSizes = [
111 64, // Windows site icons, Safari Reading List, Modern browsers
112 96, // Google TV Favicon
113 192, // For Chrome for Android
114 195, // Opera Speed Dial icon
115 196, // For Chrome for Android home screen icon
116 228 // For Coast for iOS
117 ];
118
119 const streams = [];
120
121 // Foreach each sizes
122 for (const size of iconSizes) {
123
124 /* eslint-disable function-paren-newline */
125 streams.push(
126 util.assetsProcess(paths.files.iconsIcon, (stream) => {
127
128 return stream
129 .pipe(toolbox.plumber())
130
131 .pipe(gulpif(size !== 256, gm((gmfile, done) => {
132 gmfile.identify((error, info) => {
133 if (error) {
134 terminal.error(error);
135 }
136 done(null, toolbox.gmOptimization(gmfile.resize(size, size), info));
137 });
138 })))
139
140 .pipe(rename(util.assetsRename(`icon-${size}`)))
141
142 .pipe(imagemin())
143 ;
144 })
145 );
146 /* eslint-disable function-paren-newline */
147 }
148
149 return toolbox.mergeStreams(streams);
150 });
151
152
153 //-- Large
154 flow.createTask('icons-large', () => {
155 return util.assetsProcess(paths.files.iconsLarge, (stream) => {
156 return stream
157 .pipe(toolbox.plumber())
158 .pipe(rename(util.assetsRename('large')))
159 .pipe(imagemin())
160 ;
161 });
162 });
163
164
165 //-- Windows metro tile
166 // http://msdn.microsoft.com/en-us/library/ie/dn455106(v=vs.85).aspx
167 // http://msdn.microsoft.com/en-us/library/ie/bg183312(v=vs.85).aspx
168 flow.createTask('icons-tile', () => {
169 const sizes = {
170 small: [128, 128], // Officially: 70 x 70 | Recommended: 128 x 128
171 medium: [270, 270], // Officially: 150 x 150 | Recommended: 270 x 270
172 large: [558, 558], // Officially: 310 x 310 | Recommended: 558 x 558
173 wide: [558, 270] // Officially: 310 x 150 | Recommended: 558 x 270
174 };
175
176 const streams = [];
177
178 // Foreach each sizes
179 for (const name of Object.keys(sizes)) {
180 const size = sizes[name];
181
182 /* eslint-disable function-paren-newline */
183 streams.push(
184 util.assetsProcess(paths.files.iconsTile, (stream) => {
185
186 return stream
187 .pipe(toolbox.plumber())
188
189 .pipe(gm((gmfile, done) => {
190 gmfile.identify((error, info) => {
191 if (error) {
192 terminal.error(error);
193 }
194
195 const file = toolbox.gmOptimization(gmfile.resize(size[0], size[1]), info);
196
197 if (name === 'wide') {
198 file.background('transparent').gravity('Center').extent(size[0], size[1]);
199 }
200
201 done(null, file);
202 });
203 }))
204
205 .pipe(rename(util.assetsRename(`tile-${name}`)))
206
207 .pipe(imagemin())
208 ;
209 })
210 );
211 /* eslint-enable function-paren-newline */
212 }
213
214 return toolbox.mergeStreams(streams);
215 });
216
217
218
219
220
221
222 //-- Rebuild
223 flow.createSequence('icons', gulp.parallel('icons-favicon', 'icons-touch', 'icons-icon', 'icons-large', 'icons-tile'), {
224 cleanBundle: ({ bundle }) => {
225 return [`${paths.directory.root}/${bundle.output.build}/${paths.build.icons}`];
226 }
227 });
228
229};