mobile-snap 1.0.7 → 1.0.9

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.
Files changed (2) hide show
  1. package/bin/cli.js +29 -17
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -399,7 +399,7 @@ async function analyzeRoutes(browser, baseUrl, initialPaths, email, password, lo
399
399
  };
400
400
  }
401
401
 
402
- async function applyMockupBorder(browser, imageBuffer, deviceName, size, platform, isDarkTheme = false) {
402
+ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platform, isDarkTheme = false, shadow = true) {
403
403
  const base64Image = imageBuffer.toString('base64');
404
404
 
405
405
  const now = new Date();
@@ -413,7 +413,10 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
413
413
  const batteryLevelBg = isDarkTheme ? '#ffffff' : '#000000';
414
414
  const indicatorBg = isDarkTheme ? 'rgba(255, 255, 255, 0.85)' : 'rgba(0, 0, 0, 0.8)';
415
415
  const androidIndicatorBg = isDarkTheme ? 'rgba(255, 255, 255, 0.6)' : 'rgba(0, 0, 0, 0.5)';
416
- const tabletIndicatorBg = isDarkTheme ? 'rgba(255, 255, 255, 0.4)' : 'rgba(0, 0, 0, 0.3)';
416
+ const frameScale = shadow ? '0.88' : '0.94';
417
+ const dropShadow = shadow ? '0 20px 50px rgba(0,0,0,0.6)' : 'none';
418
+ const androidDropShadow = shadow ? '0 20px 50px rgba(0,0,0,0.6)' : 'none';
419
+ const tabletDropShadow = shadow ? '0 20px 50px rgba(0,0,0,0.6)' : 'none';
417
420
 
418
421
  let frameClass = 'ios';
419
422
  let topElementHTML = '<div class="dynamic-island"></div>';
@@ -502,21 +505,20 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
502
505
  overflow: hidden;
503
506
  }
504
507
  body {
505
- background: linear-gradient(135deg, #0d1b2a 0%, #1b263b 100%);
508
+ background: transparent;
506
509
  display: flex;
507
510
  justify-content: center;
508
511
  align-items: center;
509
- width: 100vw;
510
- height: 100vh;
512
+ min-height: 100vh;
511
513
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
512
514
  }
513
515
  .device-wrapper {
514
516
  position: relative;
517
+ width: ${size.logical.width}px;
518
+ height: ${size.logical.height}px;
515
519
  display: flex;
516
520
  justify-content: center;
517
521
  align-items: center;
518
- transform: scale(0.85);
519
- transform-origin: center;
520
522
  background: transparent;
521
523
  }
522
524
  .device-frame {
@@ -525,8 +527,11 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
525
527
  box-shadow:
526
528
  0 0 0 12px #1f1f21,
527
529
  0 0 0 13px #2f2f31,
528
- 0 20px 50px rgba(0,0,0,0.6);
530
+ ${dropShadow};
529
531
  overflow: hidden;
532
+ transform: scale(${frameScale});
533
+ transform-origin: center;
534
+ flex-shrink: 0;
530
535
  }
531
536
  .device-frame.ios {
532
537
  border-radius: 54px;
@@ -539,7 +544,7 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
539
544
  box-shadow:
540
545
  0 0 0 14px #1f1f21,
541
546
  0 0 0 15px #2f2f31,
542
- 0 20px 50px rgba(0,0,0,0.6);
547
+ ${dropShadow};
543
548
  }
544
549
  .device-frame.ios-tablet .screenshot-img {
545
550
  border-radius: 20px;
@@ -549,7 +554,7 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
549
554
  box-shadow:
550
555
  0 0 0 10px #2a2a2c,
551
556
  0 0 0 11px #3a3a3c,
552
- 0 20px 50px rgba(0,0,0,0.6);
557
+ ${androidDropShadow};
553
558
  }
554
559
  .device-frame.android-phone .screenshot-img {
555
560
  border-radius: 30px;
@@ -558,7 +563,7 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
558
563
  border-radius: 24px;
559
564
  box-shadow:
560
565
  0 0 0 14px #2a2a2c,
561
- 0 20px 50px rgba(0,0,0,0.6);
566
+ ${tabletDropShadow};
562
567
  }
563
568
  .device-frame.android-tablet .screenshot-img {
564
569
  border-radius: 12px;
@@ -672,8 +677,13 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
672
677
  </html>
673
678
  `;
674
679
 
680
+ const extraWidth = 150;
681
+ const extraHeight = 150;
675
682
  const context = await browser.newContext({
676
- viewport: size.logical,
683
+ viewport: {
684
+ width: size.logical.width + extraWidth,
685
+ height: size.logical.height + extraHeight
686
+ },
677
687
  deviceScaleFactor: size.scale
678
688
  });
679
689
 
@@ -681,15 +691,15 @@ async function applyMockupBorder(browser, imageBuffer, deviceName, size, platfor
681
691
  await page.setContent(htmlContent);
682
692
  await page.waitForLoadState('networkidle');
683
693
 
684
- const buffer = await page.screenshot({
685
- omitBackground: false
694
+ const buffer = await page.locator('.device-wrapper').screenshot({
695
+ omitBackground: true
686
696
  });
687
697
 
688
698
  await context.close();
689
699
  return buffer;
690
700
  }
691
701
 
692
- async function captureScreenshots(url, paths, outputDir, platform, crawl, detectPages, email, password, loginPath, addHtml, mockup) {
702
+ async function captureScreenshots(url, paths, outputDir, platform, crawl, detectPages, email, password, loginPath, addHtml, mockup, shadow = true) {
693
703
  if (!url.startsWith('http://') && !url.startsWith('https://')) {
694
704
  url = 'http://' + url;
695
705
  }
@@ -816,7 +826,7 @@ async function captureScreenshots(url, paths, outputDir, platform, crawl, detect
816
826
  });
817
827
 
818
828
  const raw = await page.screenshot({ fullPage: false });
819
- const framed = await applyMockupBorder(browser, raw, deviceName, size, plat, isDarkTheme);
829
+ const framed = await applyMockupBorder(browser, raw, deviceName, size, plat, isDarkTheme, shadow);
820
830
  fs.writeFileSync(outputPath, framed);
821
831
  } else {
822
832
  await page.screenshot({ path: outputPath, fullPage: false });
@@ -1004,6 +1014,7 @@ program
1004
1014
  .option('--login-path <path>', 'Path to the login page', '/login.html')
1005
1015
  .option('--html', 'Auto append .html extension to detected routes', false)
1006
1016
  .option('-m, --mockup', 'Wrap screenshots in a beautiful iPhone/Android device mockup frame', false)
1017
+ .option('--no-shadow', 'Disable mockup device shadow and stretch border to edges')
1007
1018
  .action((options) => {
1008
1019
  let pathList = [];
1009
1020
  if (options.paths) {
@@ -1027,7 +1038,8 @@ program
1027
1038
  options.password,
1028
1039
  options.loginPath,
1029
1040
  options.html,
1030
- options.mockup
1041
+ options.mockup,
1042
+ options.shadow
1031
1043
  ).catch(err => {
1032
1044
  console.error(pc.red(`An unexpected error occurred: ${err.message}`));
1033
1045
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobile-snap",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Automate pixel-precise App Store & Google Play screenshots from a local web server",
5
5
  "type": "module",
6
6
  "main": "bin/cli.js",