@makefully/platypus 4.1.21 → 4.1.22

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/platypus",
3
- "version": "4.1.21",
3
+ "version": "4.1.22",
4
4
  "description": "2D tile-based HTML5 game engine with a component-based entity model",
5
5
  "license": "MIT",
6
6
  "contributors": [
package/src/Game.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* global document, platypus, window */
2
2
  import {Application} from 'springroll';
3
- import {CullerPlugin, Application as PixiApplication, Ticker, extensions} from 'pixi.js';
3
+ import {CullerPlugin, Application as PixiApplication, Rectangle, Ticker, extensions} from 'pixi.js';
4
4
  import {arrayCache, greenSlice, greenSplice, union} from './utils/array.js';
5
5
  import Data from './Data.js';
6
6
  import Entity from './Entity.js';
@@ -823,6 +823,82 @@ class Game extends Messenger {
823
823
  }
824
824
  return entities;
825
825
  }
826
+
827
+ /**
828
+ * Captures a screenshot of the currently visible game viewport (the canvas /
829
+ * camera view), not the full stage or world bounds.
830
+ *
831
+ * Prefer this over `renderer.extract.*(stage)` without a frame — extracting
832
+ * the bare stage uses content bounds and can include off-screen world area.
833
+ *
834
+ * @param {Object} [options]
835
+ * @param {string} [options.format='png'] Image format for data URLs (`png`, `jpg`/`jpeg`, `webp`).
836
+ * @param {number} [options.quality] Encoder quality for lossy formats (0–1).
837
+ * @param {boolean} [options.render=true] Render the stage before capturing.
838
+ * @param {string} [options.as='dataURL'] Return type: `dataURL` or `canvas`.
839
+ * @return {Promise<string|HTMLCanvasElement|null>} Screenshot, or null if unavailable.
840
+ **/
841
+ async captureViewport (options = {}) {
842
+ const
843
+ {
844
+ format = 'png',
845
+ quality,
846
+ render = true,
847
+ as = 'dataURL'
848
+ } = options,
849
+ {renderer, stage} = this;
850
+
851
+ if (!renderer || !stage) {
852
+ return null;
853
+ }
854
+
855
+ if (render) {
856
+ renderer.render(stage);
857
+ }
858
+
859
+ const
860
+ {resolution, screen} = renderer,
861
+ frame = new Rectangle(0, 0, screen.width, screen.height),
862
+ extractOptions = {
863
+ target: stage,
864
+ frame,
865
+ resolution
866
+ };
867
+
868
+ try {
869
+ if (as === 'canvas') {
870
+ return renderer.extract.canvas(extractOptions);
871
+ }
872
+
873
+ return await renderer.extract.base64({
874
+ ...extractOptions,
875
+ format,
876
+ quality
877
+ });
878
+ } catch (err) {
879
+ platypus.debug.warn('Game.captureViewport failed.', err);
880
+
881
+ // Fallback: canvas buffer after the render above (viewport-sized).
882
+ try {
883
+ if (as === 'canvas') {
884
+ return this.canvas;
885
+ }
886
+
887
+ const mime = format === 'jpg' || format === 'jpeg'
888
+ ? 'image/jpeg'
889
+ : format === 'webp'
890
+ ? 'image/webp'
891
+ : 'image/png';
892
+
893
+ return typeof quality === 'number'
894
+ ? this.canvas.toDataURL(mime, quality)
895
+ : this.canvas.toDataURL(mime);
896
+ } catch (fallbackErr) {
897
+ platypus.debug.warn('Game.captureViewport canvas fallback failed.', fallbackErr);
898
+ return null;
899
+ }
900
+ }
901
+ }
826
902
 
827
903
  /**
828
904
  * This method destroys the game.