codeplay-common 4.3.3 → 4.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,9 +3,12 @@ const path = require('node:path');
|
|
|
3
3
|
const readline = require('node:readline/promises');
|
|
4
4
|
const { spawn, spawnSync } = require('node:child_process');
|
|
5
5
|
|
|
6
|
-
const screenshotDirectory = path.join(__dirname, 'Auto-Screenshot', '
|
|
7
|
-
const inFrameDirectory = path.join(__dirname, 'Auto-Screenshot', '
|
|
8
|
-
const
|
|
6
|
+
const screenshotDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Screenshot');
|
|
7
|
+
const inFrameDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Frame');
|
|
8
|
+
const amazonAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Amazon-assets');
|
|
9
|
+
const samsungAssetsDirectory = path.join(__dirname, 'Auto-Screenshot', 'Samsung-assets');
|
|
10
|
+
const capacitorConfigPath = path.join(__dirname, 'capacitor.config.json');
|
|
11
|
+
const amazonIconPath = path.join(__dirname, 'resources', 'icon-only.png');
|
|
9
12
|
const temporaryDirectory = path.join(__dirname, 'agent-temp');
|
|
10
13
|
const browserExecutablePaths = [
|
|
11
14
|
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
@@ -21,20 +24,33 @@ const deviceProfiles = [
|
|
|
21
24
|
outputDirectory: 'Android',
|
|
22
25
|
frameType: 'android-phone',
|
|
23
26
|
width: 360,
|
|
24
|
-
height: 800,
|
|
25
|
-
deviceScaleFactor: 3,
|
|
26
|
-
|
|
27
|
+
height: 800,
|
|
28
|
+
deviceScaleFactor: 3,
|
|
29
|
+
orientationSensitive: true,
|
|
30
|
+
mobile: true,
|
|
27
31
|
},
|
|
28
|
-
{
|
|
29
|
-
name: 'android-tablet',
|
|
30
|
-
label: 'Android tablet',
|
|
32
|
+
{
|
|
33
|
+
name: 'android-tablet',
|
|
34
|
+
label: 'Android tablet',
|
|
31
35
|
outputDirectory: 'Android-Tab',
|
|
32
36
|
frameType: 'tablet',
|
|
33
37
|
width: 800,
|
|
34
|
-
height: 1280,
|
|
35
|
-
deviceScaleFactor: 2,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
height: 1280,
|
|
39
|
+
deviceScaleFactor: 2,
|
|
40
|
+
orientationSensitive: true,
|
|
41
|
+
mobile: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'android-tablet-10-inch',
|
|
45
|
+
label: 'Android 10-inch Play Store tablet',
|
|
46
|
+
outputDirectory: 'Android-Tab-10-Inch',
|
|
47
|
+
frameType: 'tablet',
|
|
48
|
+
width: 720,
|
|
49
|
+
height: 1280,
|
|
50
|
+
deviceScaleFactor: 2,
|
|
51
|
+
orientationSensitive: true,
|
|
52
|
+
mobile: true,
|
|
53
|
+
},
|
|
38
54
|
{
|
|
39
55
|
name: 'iphone',
|
|
40
56
|
label: 'iPhone 6.9-inch App Store viewport',
|
|
@@ -45,6 +61,7 @@ const deviceProfiles = [
|
|
|
45
61
|
deviceScaleFactor: 3,
|
|
46
62
|
framedWidth: 1284,
|
|
47
63
|
framedHeight: 2778,
|
|
64
|
+
orientationSensitive: true,
|
|
48
65
|
mobile: true,
|
|
49
66
|
},
|
|
50
67
|
{
|
|
@@ -57,17 +74,55 @@ const deviceProfiles = [
|
|
|
57
74
|
deviceScaleFactor: 2,
|
|
58
75
|
framedWidth: 2048,
|
|
59
76
|
framedHeight: 2732,
|
|
77
|
+
orientationSensitive: true,
|
|
60
78
|
mobile: true,
|
|
61
|
-
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'apple-vision-pro',
|
|
82
|
+
label: 'Apple Vision Pro',
|
|
83
|
+
outputDirectory: 'Apple-Vision-Pro',
|
|
84
|
+
frameType: 'apple-vision-pro',
|
|
85
|
+
width: 3840,
|
|
86
|
+
height: 2160,
|
|
87
|
+
deviceScaleFactor: 1,
|
|
88
|
+
framedWidth: 3840,
|
|
89
|
+
framedHeight: 2160,
|
|
90
|
+
mobile: false,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'apple-tv',
|
|
94
|
+
label: 'Apple TV',
|
|
95
|
+
outputDirectory: 'Apple-TV',
|
|
96
|
+
frameType: 'apple-tv',
|
|
97
|
+
width: 1920,
|
|
98
|
+
height: 1080,
|
|
99
|
+
deviceScaleFactor: 1,
|
|
100
|
+
framedWidth: 1920,
|
|
101
|
+
framedHeight: 1080,
|
|
102
|
+
mobile: false,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'apple-watch',
|
|
106
|
+
label: 'Apple Watch Ultra 3',
|
|
107
|
+
outputDirectory: 'Apple-Watch',
|
|
108
|
+
frameType: 'apple-watch',
|
|
109
|
+
width: 422,
|
|
110
|
+
height: 514,
|
|
111
|
+
deviceScaleFactor: 1,
|
|
112
|
+
framedWidth: 422,
|
|
113
|
+
framedHeight: 514,
|
|
114
|
+
mobile: true,
|
|
115
|
+
},
|
|
62
116
|
{
|
|
63
117
|
name: 'amazon-mobile',
|
|
64
118
|
label: 'Amazon mobile store viewport',
|
|
65
119
|
outputDirectory: 'Amazon-Phone',
|
|
66
120
|
frameType: 'android-phone',
|
|
67
121
|
width: 360,
|
|
68
|
-
height: 640,
|
|
69
|
-
deviceScaleFactor: 3,
|
|
70
|
-
|
|
122
|
+
height: 640,
|
|
123
|
+
deviceScaleFactor: 3,
|
|
124
|
+
orientationSensitive: true,
|
|
125
|
+
mobile: true,
|
|
71
126
|
},
|
|
72
127
|
{
|
|
73
128
|
name: 'amazon-fire-tablet',
|
|
@@ -75,9 +130,10 @@ const deviceProfiles = [
|
|
|
75
130
|
outputDirectory: 'Amazon-Tab',
|
|
76
131
|
frameType: 'tablet',
|
|
77
132
|
width: 800,
|
|
78
|
-
height: 1280,
|
|
79
|
-
deviceScaleFactor: 2,
|
|
80
|
-
|
|
133
|
+
height: 1280,
|
|
134
|
+
deviceScaleFactor: 2,
|
|
135
|
+
orientationSensitive: true,
|
|
136
|
+
mobile: true,
|
|
81
137
|
},
|
|
82
138
|
{
|
|
83
139
|
name: 'amazon-fire-tv',
|
|
@@ -99,16 +155,16 @@ const deviceProfiles = [
|
|
|
99
155
|
deviceScaleFactor: 1,
|
|
100
156
|
mobile: false,
|
|
101
157
|
},
|
|
102
|
-
{
|
|
103
|
-
name: 'chromebook',
|
|
104
|
-
label: 'Chromebook
|
|
105
|
-
outputDirectory: 'Chromebook',
|
|
106
|
-
frameType: 'laptop',
|
|
107
|
-
width:
|
|
108
|
-
height:
|
|
109
|
-
deviceScaleFactor: 1,
|
|
110
|
-
mobile: false,
|
|
111
|
-
},
|
|
158
|
+
{
|
|
159
|
+
name: 'chromebook',
|
|
160
|
+
label: 'Chromebook Play Store viewport',
|
|
161
|
+
outputDirectory: 'Chromebook',
|
|
162
|
+
frameType: 'laptop',
|
|
163
|
+
width: 1920,
|
|
164
|
+
height: 1080,
|
|
165
|
+
deviceScaleFactor: 1,
|
|
166
|
+
mobile: false,
|
|
167
|
+
},
|
|
112
168
|
{
|
|
113
169
|
name: 'android-xr',
|
|
114
170
|
label: 'Android XR 2D panel approximation',
|
|
@@ -139,7 +195,7 @@ function getConfiguredOrientation() {
|
|
|
139
195
|
}
|
|
140
196
|
|
|
141
197
|
function orientProfile(profile, orientation) {
|
|
142
|
-
if (orientation !== 'landscape') {
|
|
198
|
+
if (orientation !== 'landscape' || !profile.orientationSensitive) {
|
|
143
199
|
return profile;
|
|
144
200
|
}
|
|
145
201
|
|
|
@@ -297,7 +353,9 @@ function getScreenshotFileName(fileNameInput, selectedProfiles) {
|
|
|
297
353
|
|
|
298
354
|
function parseArguments() {
|
|
299
355
|
const args = process.argv.slice(2);
|
|
300
|
-
const options = {
|
|
356
|
+
const options = {
|
|
357
|
+
amazonAssets: false,
|
|
358
|
+
samsungAssets: false,
|
|
301
359
|
dryRun: false,
|
|
302
360
|
frameExisting: false,
|
|
303
361
|
help: false,
|
|
@@ -309,7 +367,11 @@ function parseArguments() {
|
|
|
309
367
|
for (let index = 0; index < args.length; index += 1) {
|
|
310
368
|
const argument = args[index];
|
|
311
369
|
|
|
312
|
-
if (argument === '--
|
|
370
|
+
if (argument === '--amazon-assets') {
|
|
371
|
+
options.amazonAssets = true;
|
|
372
|
+
} else if (argument === '--samsung-assets') {
|
|
373
|
+
options.samsungAssets = true;
|
|
374
|
+
} else if (argument === '--dry-run') {
|
|
313
375
|
options.dryRun = true;
|
|
314
376
|
} else if (argument === '--frame-existing') {
|
|
315
377
|
options.frameExisting = true;
|
|
@@ -353,12 +415,14 @@ function printHelp() {
|
|
|
353
415
|
console.log('Capture the current live Android WebView at multiple responsive viewport sizes.');
|
|
354
416
|
console.log('');
|
|
355
417
|
console.log('Usage:');
|
|
356
|
-
console.log(' node take-
|
|
357
|
-
console.log(' node take-
|
|
358
|
-
console.log(' node take-
|
|
359
|
-
console.log(' node take-
|
|
360
|
-
console.log(' node take-
|
|
361
|
-
console.log(' node take-
|
|
418
|
+
console.log(' node take-screen-image.js');
|
|
419
|
+
console.log(' node take-screen-image.js --profiles iphone,ipad');
|
|
420
|
+
console.log(' node take-screen-image.js --prefix home --profiles android-phone,ipad');
|
|
421
|
+
console.log(' node take-screen-image.js --frame-existing');
|
|
422
|
+
console.log(' node take-screen-image.js --amazon-assets');
|
|
423
|
+
console.log(' node take-screen-image.js --samsung-assets');
|
|
424
|
+
console.log(' node take-screen-image.js --dry-run');
|
|
425
|
+
console.log(' node take-screen-image.js --list');
|
|
362
426
|
}
|
|
363
427
|
|
|
364
428
|
function selectProfiles(input) {
|
|
@@ -802,7 +866,7 @@ async function waitForReplayLayout(client, snapshot) {
|
|
|
802
866
|
});
|
|
803
867
|
}
|
|
804
868
|
|
|
805
|
-
function getFrameAdornment(frameType) {
|
|
869
|
+
function getFrameAdornment(frameType) {
|
|
806
870
|
if (frameType === 'iphone') {
|
|
807
871
|
return '<div class="dynamic-island"></div>';
|
|
808
872
|
}
|
|
@@ -815,9 +879,17 @@ function getFrameAdornment(frameType) {
|
|
|
815
879
|
return '<div class="tablet-camera"></div>';
|
|
816
880
|
}
|
|
817
881
|
|
|
818
|
-
if (frameType === 'tv') {
|
|
819
|
-
return '<div class="tv-stand"></div>';
|
|
820
|
-
}
|
|
882
|
+
if (frameType === 'tv' || frameType === 'apple-tv') {
|
|
883
|
+
return '<div class="tv-stand"></div>';
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (frameType === 'apple-watch') {
|
|
887
|
+
return '<div class="watch-crown"></div><div class="watch-button"></div>';
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (frameType === 'apple-vision-pro') {
|
|
891
|
+
return '<div class="vision-sensor vision-sensor-left"></div><div class="vision-sensor vision-sensor-right"></div>';
|
|
892
|
+
}
|
|
821
893
|
|
|
822
894
|
if (frameType === 'laptop') {
|
|
823
895
|
return '<div class="laptop-camera"></div><div class="laptop-base"></div>';
|
|
@@ -826,7 +898,7 @@ function getFrameAdornment(frameType) {
|
|
|
826
898
|
return '<div class="xr-status"></div>';
|
|
827
899
|
}
|
|
828
900
|
|
|
829
|
-
function createDeviceFrameHtml(profile, screenshotBuffer) {
|
|
901
|
+
function createDeviceFrameHtml(profile, screenshotBuffer) {
|
|
830
902
|
const screenshotDataUrl = `data:image/png;base64,${screenshotBuffer.toString('base64')}`;
|
|
831
903
|
const aspectRatio = `${profile.width} / ${profile.height}`;
|
|
832
904
|
|
|
@@ -922,9 +994,64 @@ function createDeviceFrameHtml(profile, screenshotBuffer) {
|
|
|
922
994
|
padding: 1.05%;
|
|
923
995
|
border-radius: clamp(18px, 3.2vw, 48px);
|
|
924
996
|
}
|
|
925
|
-
.device.tablet .screen {
|
|
926
|
-
border-radius: clamp(13px, 2.5vw, 38px);
|
|
927
|
-
}
|
|
997
|
+
.device.tablet .screen {
|
|
998
|
+
border-radius: clamp(13px, 2.5vw, 38px);
|
|
999
|
+
}
|
|
1000
|
+
.device.apple-watch {
|
|
1001
|
+
height: 82%;
|
|
1002
|
+
padding: 2.2%;
|
|
1003
|
+
border: clamp(3px, 1.4vw, 7px) solid #8b929b;
|
|
1004
|
+
border-radius: 24% / 20%;
|
|
1005
|
+
background: linear-gradient(145deg, #d5d8dc, #363b43 28%, #11151b 72%, #9299a2);
|
|
1006
|
+
}
|
|
1007
|
+
.device.apple-watch .screen {
|
|
1008
|
+
border-radius: 20% / 17%;
|
|
1009
|
+
}
|
|
1010
|
+
.watch-crown {
|
|
1011
|
+
position: absolute;
|
|
1012
|
+
top: 24%;
|
|
1013
|
+
right: -5.5%;
|
|
1014
|
+
width: 5.5%;
|
|
1015
|
+
height: 15%;
|
|
1016
|
+
border-radius: 0 45% 45% 0;
|
|
1017
|
+
background: linear-gradient(90deg, #303640, #a8afb7 55%, #424851);
|
|
1018
|
+
box-shadow: 0 0.8vh 1.5vh rgba(0,0,0,0.45);
|
|
1019
|
+
}
|
|
1020
|
+
.watch-button {
|
|
1021
|
+
position: absolute;
|
|
1022
|
+
top: 43%;
|
|
1023
|
+
right: -3.5%;
|
|
1024
|
+
width: 3.5%;
|
|
1025
|
+
height: 11%;
|
|
1026
|
+
border-radius: 0 35% 35% 0;
|
|
1027
|
+
background: #626a74;
|
|
1028
|
+
}
|
|
1029
|
+
.device.apple-vision-pro {
|
|
1030
|
+
width: 82%;
|
|
1031
|
+
padding: 0.72%;
|
|
1032
|
+
border: clamp(4px, 0.45vw, 18px) solid rgba(201, 214, 224, 0.92);
|
|
1033
|
+
border-radius: 14% / 32%;
|
|
1034
|
+
background: linear-gradient(145deg, #dce5eb, #55616d 25%, #151b22 72%, #aebac3);
|
|
1035
|
+
box-shadow:
|
|
1036
|
+
0 5vh 11vh rgba(0,0,0,0.68),
|
|
1037
|
+
0 0 5vh rgba(180,225,255,0.2),
|
|
1038
|
+
0 0 0 1px rgba(255,255,255,0.4) inset;
|
|
1039
|
+
}
|
|
1040
|
+
.device.apple-vision-pro .screen {
|
|
1041
|
+
border-radius: 13% / 29%;
|
|
1042
|
+
}
|
|
1043
|
+
.vision-sensor {
|
|
1044
|
+
position: absolute;
|
|
1045
|
+
z-index: 3;
|
|
1046
|
+
top: 48%;
|
|
1047
|
+
width: clamp(8px, 0.8vw, 30px);
|
|
1048
|
+
aspect-ratio: 1;
|
|
1049
|
+
border-radius: 50%;
|
|
1050
|
+
background: radial-gradient(circle at 38% 35%, #567793, #05080c 55%, #000 75%);
|
|
1051
|
+
box-shadow: 0 0 0 2px rgba(147,166,181,0.55);
|
|
1052
|
+
}
|
|
1053
|
+
.vision-sensor-left { left: 3.2%; }
|
|
1054
|
+
.vision-sensor-right { right: 3.2%; }
|
|
928
1055
|
.tablet-camera,
|
|
929
1056
|
.laptop-camera {
|
|
930
1057
|
position: absolute;
|
|
@@ -938,13 +1065,15 @@ function createDeviceFrameHtml(profile, screenshotBuffer) {
|
|
|
938
1065
|
background: #080b10;
|
|
939
1066
|
box-shadow: 0 0 0 1px #526071;
|
|
940
1067
|
}
|
|
941
|
-
.device.tv
|
|
942
|
-
|
|
1068
|
+
.device.tv,
|
|
1069
|
+
.device.apple-tv {
|
|
1070
|
+
width: 82%;
|
|
943
1071
|
padding: 0.62%;
|
|
944
1072
|
border-radius: clamp(8px, 1.1vw, 24px);
|
|
945
1073
|
transform: translateY(-4%);
|
|
946
1074
|
}
|
|
947
|
-
.device.tv .screen
|
|
1075
|
+
.device.tv .screen,
|
|
1076
|
+
.device.apple-tv .screen { border-radius: clamp(4px, 0.55vw, 12px); }
|
|
948
1077
|
.tv-stand {
|
|
949
1078
|
position: absolute;
|
|
950
1079
|
z-index: -1;
|
|
@@ -1007,9 +1136,397 @@ function createDeviceFrameHtml(profile, screenshotBuffer) {
|
|
|
1007
1136
|
${getFrameAdornment(profile.frameType)}
|
|
1008
1137
|
</main>
|
|
1009
1138
|
</body>
|
|
1010
|
-
</html>`;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1139
|
+
</html>`;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function escapeHtml(value) {
|
|
1143
|
+
return String(value)
|
|
1144
|
+
.replace(/&/g, '&')
|
|
1145
|
+
.replace(/</g, '<')
|
|
1146
|
+
.replace(/>/g, '>')
|
|
1147
|
+
.replace(/"/g, '"')
|
|
1148
|
+
.replace(/'/g, ''');
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
function createAmazonAssetHtml(asset, appName, iconBuffer) {
|
|
1152
|
+
const iconDataUrl = `data:image/png;base64,${iconBuffer.toString('base64')}`;
|
|
1153
|
+
const safeAppName = escapeHtml(appName);
|
|
1154
|
+
const logoMarkup = asset.type === 'featured-logo'
|
|
1155
|
+
? `<main class="featured-logo"><img src="${iconDataUrl}" /><div><small>POCKET RHYTHM STUDIO</small><strong>${safeAppName}</strong></div></main>`
|
|
1156
|
+
: '';
|
|
1157
|
+
const iconMarkup = asset.type === 'icon'
|
|
1158
|
+
? `<main class="icon-card"><img src="${iconDataUrl}" /><div><small>MAKE THE NEXT BEAT YOURS</small><strong>${safeAppName}</strong></div></main>`
|
|
1159
|
+
: '';
|
|
1160
|
+
const backgroundMarkup = asset.type.includes('background')
|
|
1161
|
+
? '<main class="background-art"><div class="pulse pulse-one"></div><div class="pulse pulse-two"></div><div class="equalizer"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div><div class="pad-grid"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></main>'
|
|
1162
|
+
: '';
|
|
1163
|
+
|
|
1164
|
+
return `<!doctype html>
|
|
1165
|
+
<html>
|
|
1166
|
+
<head>
|
|
1167
|
+
<meta charset="utf-8" />
|
|
1168
|
+
<style>
|
|
1169
|
+
* { box-sizing: border-box; }
|
|
1170
|
+
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; }
|
|
1171
|
+
body {
|
|
1172
|
+
position: relative;
|
|
1173
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
1174
|
+
color: #f8fbff;
|
|
1175
|
+
background: transparent;
|
|
1176
|
+
}
|
|
1177
|
+
body.icon,
|
|
1178
|
+
body.background-image,
|
|
1179
|
+
body.featured-background {
|
|
1180
|
+
background:
|
|
1181
|
+
radial-gradient(circle at 16% 18%, rgba(52, 211, 235, 0.32), transparent 28%),
|
|
1182
|
+
radial-gradient(circle at 82% 82%, rgba(201, 255, 65, 0.24), transparent 30%),
|
|
1183
|
+
linear-gradient(135deg, #24113c 0%, #15152d 48%, #071725 100%);
|
|
1184
|
+
}
|
|
1185
|
+
body.icon::before,
|
|
1186
|
+
body.background-image::before,
|
|
1187
|
+
body.featured-background::before {
|
|
1188
|
+
content: '';
|
|
1189
|
+
position: absolute;
|
|
1190
|
+
inset: 0;
|
|
1191
|
+
opacity: 0.22;
|
|
1192
|
+
background-image:
|
|
1193
|
+
linear-gradient(rgba(255,255,255,0.07) 1px, transparent 1px),
|
|
1194
|
+
linear-gradient(90deg, rgba(255,255,255,0.07) 1px, transparent 1px);
|
|
1195
|
+
background-size: 72px 72px;
|
|
1196
|
+
}
|
|
1197
|
+
.icon-card {
|
|
1198
|
+
position: relative;
|
|
1199
|
+
z-index: 2;
|
|
1200
|
+
width: 100%;
|
|
1201
|
+
height: 100%;
|
|
1202
|
+
display: flex;
|
|
1203
|
+
align-items: center;
|
|
1204
|
+
justify-content: center;
|
|
1205
|
+
gap: 72px;
|
|
1206
|
+
padding: 72px 110px;
|
|
1207
|
+
}
|
|
1208
|
+
.icon-card img {
|
|
1209
|
+
width: 500px;
|
|
1210
|
+
height: 500px;
|
|
1211
|
+
object-fit: contain;
|
|
1212
|
+
border-radius: 104px;
|
|
1213
|
+
box-shadow: 0 38px 80px rgba(0,0,0,0.48), 0 0 70px rgba(52,211,235,0.2);
|
|
1214
|
+
}
|
|
1215
|
+
.icon-card div { display: flex; flex-direction: column; gap: 18px; }
|
|
1216
|
+
.icon-card small,
|
|
1217
|
+
.featured-logo small {
|
|
1218
|
+
color: #35d4eb;
|
|
1219
|
+
font-size: 24px;
|
|
1220
|
+
font-weight: 700;
|
|
1221
|
+
letter-spacing: 7px;
|
|
1222
|
+
}
|
|
1223
|
+
.icon-card strong { font-size: 86px; line-height: 0.96; max-width: 500px; }
|
|
1224
|
+
.featured-logo {
|
|
1225
|
+
width: 100%;
|
|
1226
|
+
height: 100%;
|
|
1227
|
+
display: flex;
|
|
1228
|
+
align-items: center;
|
|
1229
|
+
gap: 24px;
|
|
1230
|
+
padding: 20px 26px;
|
|
1231
|
+
color: #111827;
|
|
1232
|
+
}
|
|
1233
|
+
.featured-logo img {
|
|
1234
|
+
width: 210px;
|
|
1235
|
+
height: 210px;
|
|
1236
|
+
object-fit: contain;
|
|
1237
|
+
border-radius: 44px;
|
|
1238
|
+
}
|
|
1239
|
+
.featured-logo div { display: flex; min-width: 0; flex-direction: column; gap: 8px; }
|
|
1240
|
+
.featured-logo small { font-size: 14px; letter-spacing: 3px; }
|
|
1241
|
+
.featured-logo strong {
|
|
1242
|
+
max-width: 360px;
|
|
1243
|
+
overflow: hidden;
|
|
1244
|
+
color: #ffffff;
|
|
1245
|
+
font-size: 56px;
|
|
1246
|
+
line-height: 1;
|
|
1247
|
+
text-overflow: ellipsis;
|
|
1248
|
+
white-space: nowrap;
|
|
1249
|
+
text-shadow: 0 3px 12px rgba(0,0,0,0.75);
|
|
1250
|
+
}
|
|
1251
|
+
.background-art { position: absolute; inset: 0; }
|
|
1252
|
+
.pulse {
|
|
1253
|
+
position: absolute;
|
|
1254
|
+
border: 3px solid rgba(53,212,235,0.28);
|
|
1255
|
+
border-radius: 50%;
|
|
1256
|
+
box-shadow: 0 0 80px rgba(53,212,235,0.15);
|
|
1257
|
+
}
|
|
1258
|
+
.pulse-one { width: 520px; height: 520px; top: -180px; left: -110px; }
|
|
1259
|
+
.pulse-two { width: 620px; height: 620px; right: -180px; bottom: -310px; border-color: rgba(201,255,65,0.22); }
|
|
1260
|
+
.equalizer {
|
|
1261
|
+
position: absolute;
|
|
1262
|
+
left: 8%;
|
|
1263
|
+
top: 50%;
|
|
1264
|
+
display: flex;
|
|
1265
|
+
align-items: center;
|
|
1266
|
+
gap: 20px;
|
|
1267
|
+
height: 44%;
|
|
1268
|
+
transform: translateY(-50%);
|
|
1269
|
+
}
|
|
1270
|
+
.equalizer i { width: 18px; border-radius: 999px; background: #35d4eb; box-shadow: 0 0 25px rgba(53,212,235,0.5); }
|
|
1271
|
+
.equalizer i:nth-child(1), .equalizer i:nth-child(7) { height: 28%; }
|
|
1272
|
+
.equalizer i:nth-child(2), .equalizer i:nth-child(6) { height: 52%; background: #ff5964; }
|
|
1273
|
+
.equalizer i:nth-child(3), .equalizer i:nth-child(5) { height: 76%; background: #ff9f43; }
|
|
1274
|
+
.equalizer i:nth-child(4) { height: 100%; background: #c9ff41; }
|
|
1275
|
+
.pad-grid {
|
|
1276
|
+
position: absolute;
|
|
1277
|
+
right: 7%;
|
|
1278
|
+
top: 50%;
|
|
1279
|
+
display: grid;
|
|
1280
|
+
width: 46%;
|
|
1281
|
+
height: 64%;
|
|
1282
|
+
grid-template-columns: repeat(3, 1fr);
|
|
1283
|
+
gap: 20px;
|
|
1284
|
+
transform: translateY(-50%) perspective(900px) rotateY(-10deg) rotateX(5deg);
|
|
1285
|
+
}
|
|
1286
|
+
.pad-grid i {
|
|
1287
|
+
border: 2px solid rgba(255,255,255,0.17);
|
|
1288
|
+
border-top: 7px solid #35d4eb;
|
|
1289
|
+
border-radius: 22px;
|
|
1290
|
+
background: linear-gradient(145deg, rgba(42,55,75,0.96), rgba(11,18,29,0.96));
|
|
1291
|
+
box-shadow: 0 20px 28px rgba(0,0,0,0.28);
|
|
1292
|
+
}
|
|
1293
|
+
.pad-grid i:nth-child(2), .pad-grid i:nth-child(6) { border-top-color: #ff9f43; }
|
|
1294
|
+
.pad-grid i:nth-child(3), .pad-grid i:nth-child(7) { border-top-color: #c9ff41; }
|
|
1295
|
+
.pad-grid i:nth-child(4), .pad-grid i:nth-child(8) { border-top-color: #ff5964; }
|
|
1296
|
+
.pad-grid i:nth-child(5) { border-top-color: #ac7cff; }
|
|
1297
|
+
body.featured-background .pad-grid { width: 49%; height: 72%; }
|
|
1298
|
+
body.featured-background .equalizer { height: 52%; }
|
|
1299
|
+
</style>
|
|
1300
|
+
</head>
|
|
1301
|
+
<body class="${asset.type}">
|
|
1302
|
+
${iconMarkup}
|
|
1303
|
+
${logoMarkup}
|
|
1304
|
+
${backgroundMarkup}
|
|
1305
|
+
</body>
|
|
1306
|
+
</html>`;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
async function createAmazonAssets(client) {
|
|
1310
|
+
if (!fs.existsSync(amazonIconPath)) {
|
|
1311
|
+
throw new Error(`Amazon asset source icon was not found: ${amazonIconPath}`);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
const config = JSON.parse(fs.readFileSync(capacitorConfigPath, 'utf8'));
|
|
1315
|
+
const appName = config.appName || 'App';
|
|
1316
|
+
const iconBuffer = fs.readFileSync(amazonIconPath);
|
|
1317
|
+
const assets = [
|
|
1318
|
+
{ fileName: 'icon-1280x720.png', type: 'icon', width: 1280, height: 720 },
|
|
1319
|
+
{ fileName: 'background-image-1920x1080.png', type: 'background-image', width: 1920, height: 1080 },
|
|
1320
|
+
{ fileName: 'featured-content-logo-640x260.png', type: 'featured-logo', width: 640, height: 260, transparent: true },
|
|
1321
|
+
{ fileName: 'featured-content-background-1920x720.png', type: 'featured-background', width: 1920, height: 720 },
|
|
1322
|
+
];
|
|
1323
|
+
|
|
1324
|
+
fs.mkdirSync(amazonAssetsDirectory, { recursive: true });
|
|
1325
|
+
|
|
1326
|
+
for (const asset of assets) {
|
|
1327
|
+
await client.send('Emulation.setDeviceMetricsOverride', {
|
|
1328
|
+
width: asset.width,
|
|
1329
|
+
height: asset.height,
|
|
1330
|
+
deviceScaleFactor: 1,
|
|
1331
|
+
mobile: false,
|
|
1332
|
+
screenWidth: asset.width,
|
|
1333
|
+
screenHeight: asset.height,
|
|
1334
|
+
positionX: 0,
|
|
1335
|
+
positionY: 0,
|
|
1336
|
+
});
|
|
1337
|
+
|
|
1338
|
+
const frameTree = await client.send('Page.getFrameTree');
|
|
1339
|
+
await client.send('Page.setDocumentContent', {
|
|
1340
|
+
frameId: frameTree.frameTree.frame.id,
|
|
1341
|
+
html: createAmazonAssetHtml(asset, appName, iconBuffer),
|
|
1342
|
+
});
|
|
1343
|
+
await client.send('Runtime.evaluate', {
|
|
1344
|
+
expression: `Promise.all([...document.images].map((image) => image.complete
|
|
1345
|
+
? Promise.resolve()
|
|
1346
|
+
: new Promise((resolve) => {
|
|
1347
|
+
image.addEventListener('load', resolve, { once: true });
|
|
1348
|
+
image.addEventListener('error', resolve, { once: true });
|
|
1349
|
+
}))).then(() => new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve))))`,
|
|
1350
|
+
awaitPromise: true,
|
|
1351
|
+
returnByValue: true,
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
const screenshot = await client.send('Page.captureScreenshot', {
|
|
1355
|
+
format: 'png',
|
|
1356
|
+
fromSurface: true,
|
|
1357
|
+
captureBeyondViewport: false,
|
|
1358
|
+
omitBackground: Boolean(asset.transparent),
|
|
1359
|
+
});
|
|
1360
|
+
const outputPath = path.join(amazonAssetsDirectory, asset.fileName);
|
|
1361
|
+
fs.writeFileSync(outputPath, Buffer.from(screenshot.data, 'base64'));
|
|
1362
|
+
console.log(`Saved Amazon asset ${asset.width}x${asset.height}: ${outputPath}`);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
function createSamsungAssetHtml(asset, appName, iconBuffer) {
|
|
1367
|
+
const iconDataUrl = `data:image/png;base64,${iconBuffer.toString('base64')}`;
|
|
1368
|
+
const safeAppName = escapeHtml(appName);
|
|
1369
|
+
const pads = Array.from({ length: 9 }, (_, index) => (
|
|
1370
|
+
`<button><i>0${index + 1}</i><span>${['OPEN', 'CLOSED', 'HIGH', 'CRASH', 'KICK', 'MID', 'RIDE', 'SNARE', 'FLOOR'][index]}</span></button>`
|
|
1371
|
+
)).join('');
|
|
1372
|
+
const content = asset.type === 'edge-screen'
|
|
1373
|
+
? `<main class="edge-panel"><header><img src="${iconDataUrl}" /><strong>${safeAppName}</strong></header><section>${pads}</section></main>`
|
|
1374
|
+
: `<main class="single-panel"><header><img src="${iconDataUrl}" /><div><small>POCKET RHYTHM</small><strong>${safeAppName}</strong></div></header><div class="single-action"><span>+</span><strong>OPEN STUDIO</strong><small>Tap to start playing</small></div><div class="rhythm"><i></i><i></i><i></i><i></i><i></i></div></main>`;
|
|
1375
|
+
|
|
1376
|
+
return `<!doctype html>
|
|
1377
|
+
<html>
|
|
1378
|
+
<head>
|
|
1379
|
+
<meta charset="utf-8" />
|
|
1380
|
+
<style>
|
|
1381
|
+
* { box-sizing: border-box; }
|
|
1382
|
+
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; }
|
|
1383
|
+
body {
|
|
1384
|
+
position: relative;
|
|
1385
|
+
color: #f7fbff;
|
|
1386
|
+
background:
|
|
1387
|
+
radial-gradient(circle at 50% 8%, rgba(53,212,235,0.26), transparent 24%),
|
|
1388
|
+
radial-gradient(circle at 50% 88%, rgba(201,255,65,0.16), transparent 25%),
|
|
1389
|
+
linear-gradient(180deg, #231039, #111729 48%, #071522);
|
|
1390
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
1391
|
+
}
|
|
1392
|
+
body::before {
|
|
1393
|
+
content: '';
|
|
1394
|
+
position: absolute;
|
|
1395
|
+
inset: 0;
|
|
1396
|
+
opacity: 0.18;
|
|
1397
|
+
background: repeating-linear-gradient(0deg, transparent 0 79px, rgba(255,255,255,0.08) 80px);
|
|
1398
|
+
}
|
|
1399
|
+
main { position: relative; z-index: 1; width: 100%; height: 100%; }
|
|
1400
|
+
.edge-panel { display: flex; flex-direction: column; padding: 28px 12px; }
|
|
1401
|
+
.edge-panel header { display: flex; flex-direction: column; align-items: center; gap: 12px; min-height: 230px; }
|
|
1402
|
+
.edge-panel header img { width: 112px; height: 112px; border-radius: 25px; object-fit: contain; }
|
|
1403
|
+
.edge-panel header strong { max-width: 136px; overflow: hidden; font-size: 18px; text-overflow: ellipsis; white-space: nowrap; }
|
|
1404
|
+
.edge-panel section { display: grid; flex: 1; grid-template-rows: repeat(9, 1fr); gap: 13px; }
|
|
1405
|
+
.edge-panel button {
|
|
1406
|
+
display: flex;
|
|
1407
|
+
width: 100%;
|
|
1408
|
+
min-height: 0;
|
|
1409
|
+
flex-direction: column;
|
|
1410
|
+
align-items: center;
|
|
1411
|
+
justify-content: center;
|
|
1412
|
+
gap: 8px;
|
|
1413
|
+
color: #f7fbff;
|
|
1414
|
+
border: 1px solid rgba(255,255,255,0.16);
|
|
1415
|
+
border-top: 5px solid #35d4eb;
|
|
1416
|
+
border-radius: 18px;
|
|
1417
|
+
background: linear-gradient(145deg, rgba(41,55,76,0.98), rgba(10,17,29,0.98));
|
|
1418
|
+
box-shadow: 0 10px 18px rgba(0,0,0,0.3);
|
|
1419
|
+
}
|
|
1420
|
+
.edge-panel button:nth-child(3n+2) { border-top-color: #ff9f43; }
|
|
1421
|
+
.edge-panel button:nth-child(3n) { border-top-color: #c9ff41; }
|
|
1422
|
+
.edge-panel button i { color: #35d4eb; font-size: 14px; font-style: normal; font-weight: 700; }
|
|
1423
|
+
.edge-panel button span { font-size: 12px; font-weight: 700; letter-spacing: 1px; }
|
|
1424
|
+
.single-panel { display: flex; flex-direction: column; align-items: center; padding: 100px 44px; }
|
|
1425
|
+
.single-panel header { display: flex; width: 100%; align-items: center; gap: 24px; }
|
|
1426
|
+
.single-panel header img { width: 160px; height: 160px; border-radius: 36px; object-fit: contain; }
|
|
1427
|
+
.single-panel header div { display: flex; min-width: 0; flex-direction: column; gap: 9px; }
|
|
1428
|
+
.single-panel header small { color: #35d4eb; font-size: 17px; font-weight: 700; letter-spacing: 3px; }
|
|
1429
|
+
.single-panel header strong { overflow: hidden; font-size: 48px; text-overflow: ellipsis; white-space: nowrap; }
|
|
1430
|
+
.single-action {
|
|
1431
|
+
display: flex;
|
|
1432
|
+
width: 100%;
|
|
1433
|
+
height: 880px;
|
|
1434
|
+
margin-top: 380px;
|
|
1435
|
+
flex-direction: column;
|
|
1436
|
+
align-items: center;
|
|
1437
|
+
justify-content: center;
|
|
1438
|
+
border: 3px solid rgba(53,212,235,0.5);
|
|
1439
|
+
border-radius: 90px;
|
|
1440
|
+
background: linear-gradient(145deg, rgba(39,53,75,0.96), rgba(8,16,28,0.98));
|
|
1441
|
+
box-shadow: 0 50px 90px rgba(0,0,0,0.42), 0 0 75px rgba(53,212,235,0.16);
|
|
1442
|
+
}
|
|
1443
|
+
.single-action span {
|
|
1444
|
+
display: grid;
|
|
1445
|
+
width: 260px;
|
|
1446
|
+
height: 260px;
|
|
1447
|
+
place-items: center;
|
|
1448
|
+
color: #0d1721;
|
|
1449
|
+
border-radius: 50%;
|
|
1450
|
+
background: linear-gradient(145deg, #35d4eb, #c9ff41);
|
|
1451
|
+
box-shadow: 0 25px 55px rgba(53,212,235,0.3);
|
|
1452
|
+
font-size: 170px;
|
|
1453
|
+
font-weight: 200;
|
|
1454
|
+
line-height: 1;
|
|
1455
|
+
}
|
|
1456
|
+
.single-action strong { margin-top: 65px; font-size: 42px; letter-spacing: 5px; }
|
|
1457
|
+
.single-action small { margin-top: 18px; color: #a9b7c9; font-size: 24px; }
|
|
1458
|
+
.rhythm { display: flex; align-items: center; gap: 18px; height: 300px; margin-top: auto; }
|
|
1459
|
+
.rhythm i { width: 14px; height: 70px; border-radius: 999px; background: #35d4eb; }
|
|
1460
|
+
.rhythm i:nth-child(2), .rhythm i:nth-child(4) { height: 140px; background: #ff5964; }
|
|
1461
|
+
.rhythm i:nth-child(3) { height: 210px; background: #c9ff41; }
|
|
1462
|
+
</style>
|
|
1463
|
+
</head>
|
|
1464
|
+
<body>${content}</body>
|
|
1465
|
+
</html>`;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
async function createSamsungAssets(client) {
|
|
1469
|
+
if (!fs.existsSync(amazonIconPath)) {
|
|
1470
|
+
throw new Error(`Samsung asset source icon was not found: ${amazonIconPath}`);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
const config = JSON.parse(fs.readFileSync(capacitorConfigPath, 'utf8'));
|
|
1474
|
+
const appName = config.appName || 'App';
|
|
1475
|
+
const iconBuffer = fs.readFileSync(amazonIconPath);
|
|
1476
|
+
const assets = [
|
|
1477
|
+
{ fileName: 'edge-screen-160x2560.png', type: 'edge-screen', width: 160, height: 2560 },
|
|
1478
|
+
{ fileName: 'edge-screen-single-plus-550x2560.png', type: 'edge-screen-single-plus', width: 550, height: 2560 },
|
|
1479
|
+
];
|
|
1480
|
+
const maximumFileSize = 1024 * 1024;
|
|
1481
|
+
|
|
1482
|
+
fs.mkdirSync(samsungAssetsDirectory, { recursive: true });
|
|
1483
|
+
|
|
1484
|
+
for (const asset of assets) {
|
|
1485
|
+
await client.send('Emulation.setDeviceMetricsOverride', {
|
|
1486
|
+
width: asset.width,
|
|
1487
|
+
height: asset.height,
|
|
1488
|
+
deviceScaleFactor: 1,
|
|
1489
|
+
mobile: false,
|
|
1490
|
+
screenWidth: asset.width,
|
|
1491
|
+
screenHeight: asset.height,
|
|
1492
|
+
positionX: 0,
|
|
1493
|
+
positionY: 0,
|
|
1494
|
+
});
|
|
1495
|
+
const frameTree = await client.send('Page.getFrameTree');
|
|
1496
|
+
await client.send('Page.setDocumentContent', {
|
|
1497
|
+
frameId: frameTree.frameTree.frame.id,
|
|
1498
|
+
html: createSamsungAssetHtml(asset, appName, iconBuffer),
|
|
1499
|
+
});
|
|
1500
|
+
await client.send('Runtime.evaluate', {
|
|
1501
|
+
expression: `Promise.all([...document.images].map((image) => image.complete
|
|
1502
|
+
? Promise.resolve()
|
|
1503
|
+
: new Promise((resolve) => image.addEventListener('load', resolve, { once: true }))))
|
|
1504
|
+
.then(() => new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve))))`,
|
|
1505
|
+
awaitPromise: true,
|
|
1506
|
+
returnByValue: true,
|
|
1507
|
+
});
|
|
1508
|
+
const screenshot = await client.send('Page.captureScreenshot', {
|
|
1509
|
+
format: 'png',
|
|
1510
|
+
fromSurface: true,
|
|
1511
|
+
captureBeyondViewport: false,
|
|
1512
|
+
});
|
|
1513
|
+
const outputPath = path.join(samsungAssetsDirectory, asset.fileName);
|
|
1514
|
+
const outputBuffer = Buffer.from(screenshot.data, 'base64');
|
|
1515
|
+
|
|
1516
|
+
if (outputBuffer.length >= maximumFileSize) {
|
|
1517
|
+
throw new Error(
|
|
1518
|
+
`Samsung asset exceeds 1024 KB (${Math.ceil(outputBuffer.length / 1024)} KB): ${asset.fileName}`,
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
fs.writeFileSync(outputPath, outputBuffer);
|
|
1523
|
+
console.log(
|
|
1524
|
+
`Saved Samsung asset ${asset.width}x${asset.height} `
|
|
1525
|
+
+ `(${Math.ceil(outputBuffer.length / 1024)} KB): ${outputPath}`,
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1013
1530
|
async function captureFramedScreenshot(
|
|
1014
1531
|
client,
|
|
1015
1532
|
screenshotBuffer,
|
|
@@ -1225,8 +1742,13 @@ async function runInteractiveCaptureLoop(
|
|
|
1225
1742
|
console.log('\nResponsive screenshot tool closed.');
|
|
1226
1743
|
}
|
|
1227
1744
|
|
|
1228
|
-
async function getInteractiveOptions(options) {
|
|
1229
|
-
if (
|
|
1745
|
+
async function getInteractiveOptions(options) {
|
|
1746
|
+
if (
|
|
1747
|
+
!process.stdin.isTTY
|
|
1748
|
+
|| options.dryRun
|
|
1749
|
+
|| options.amazonAssets
|
|
1750
|
+
|| options.samsungAssets
|
|
1751
|
+
) {
|
|
1230
1752
|
return options;
|
|
1231
1753
|
}
|
|
1232
1754
|
|
|
@@ -1263,9 +1785,43 @@ async function main() {
|
|
|
1263
1785
|
return;
|
|
1264
1786
|
}
|
|
1265
1787
|
|
|
1266
|
-
options = await getInteractiveOptions(options);
|
|
1267
|
-
|
|
1268
|
-
|
|
1788
|
+
options = await getInteractiveOptions(options);
|
|
1789
|
+
|
|
1790
|
+
if (options.amazonAssets) {
|
|
1791
|
+
let amazonBrowser;
|
|
1792
|
+
let amazonClient;
|
|
1793
|
+
|
|
1794
|
+
try {
|
|
1795
|
+
amazonBrowser = await launchReplayBrowser();
|
|
1796
|
+
amazonClient = await createReplayPage(amazonBrowser);
|
|
1797
|
+
await createAmazonAssets(amazonClient);
|
|
1798
|
+
} finally {
|
|
1799
|
+
if (amazonClient) amazonClient.close();
|
|
1800
|
+
if (amazonBrowser) await closeReplayBrowser(amazonBrowser);
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
console.log(`Amazon asset creation completed: ${amazonAssetsDirectory}`);
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
if (options.samsungAssets) {
|
|
1808
|
+
let samsungBrowser;
|
|
1809
|
+
let samsungClient;
|
|
1810
|
+
|
|
1811
|
+
try {
|
|
1812
|
+
samsungBrowser = await launchReplayBrowser();
|
|
1813
|
+
samsungClient = await createReplayPage(samsungBrowser);
|
|
1814
|
+
await createSamsungAssets(samsungClient);
|
|
1815
|
+
} finally {
|
|
1816
|
+
if (samsungClient) samsungClient.close();
|
|
1817
|
+
if (samsungBrowser) await closeReplayBrowser(samsungBrowser);
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
console.log(`Samsung asset creation completed: ${samsungAssetsDirectory}`);
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
const selectedProfiles = selectProfiles(options.profiles);
|
|
1269
1825
|
|
|
1270
1826
|
if (options.frameExisting) {
|
|
1271
1827
|
await frameExistingScreenshots(selectedProfiles);
|