@makefully/platypus 4.1.21 → 4.1.23
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/CHANGELOG.md +12 -0
- package/lib/platypus.js +1 -1
- package/package.json +1 -1
- package/src/Game.js +105 -1
package/package.json
CHANGED
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,110 @@ 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
|
+
* Uses the same crop approach as Paco's ScreenShooter: after camera
|
|
832
|
+
* transforms, the visible area is stage space (0, 0, screenWidth, screenHeight).
|
|
833
|
+
* Extracting only that frame avoids pulling in off-screen world content and
|
|
834
|
+
* avoids GPU texture-size failures when a full level's stage bounds are huge.
|
|
835
|
+
*
|
|
836
|
+
* @param {Object} [options]
|
|
837
|
+
* @param {string} [options.format='png'] Image format for data URLs (`png`, `jpg`/`jpeg`, `webp`).
|
|
838
|
+
* @param {number} [options.quality] Encoder quality for lossy formats (0–1).
|
|
839
|
+
* @param {boolean} [options.render=true] Render the stage before capturing.
|
|
840
|
+
* @param {string} [options.as='dataURL'] Return type: `dataURL` or `canvas`.
|
|
841
|
+
* @return {Promise<string|HTMLCanvasElement|null>} Screenshot, or null if unavailable.
|
|
842
|
+
**/
|
|
843
|
+
async captureViewport (options = {}) {
|
|
844
|
+
const
|
|
845
|
+
{
|
|
846
|
+
format = 'png',
|
|
847
|
+
quality,
|
|
848
|
+
render = true,
|
|
849
|
+
as = 'dataURL'
|
|
850
|
+
} = options,
|
|
851
|
+
{renderer, stage} = this;
|
|
852
|
+
|
|
853
|
+
if (!renderer || !stage) {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (render) {
|
|
858
|
+
renderer.render(stage);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const
|
|
862
|
+
width = Math.max(1, renderer.screen.width | 0),
|
|
863
|
+
height = Math.max(1, renderer.screen.height | 0),
|
|
864
|
+
resolution = renderer.resolution || 1,
|
|
865
|
+
backgroundColor = this.options?.display?.backgroundColor,
|
|
866
|
+
hasBackground = typeof backgroundColor === 'number' && backgroundColor >= 0,
|
|
867
|
+
// Opaque clear — transparent extracts read as a black shot in Notefully.
|
|
868
|
+
clearColor = hasBackground ? backgroundColor : 0x000000,
|
|
869
|
+
mime = format === 'jpg' || format === 'jpeg'
|
|
870
|
+
? 'image/jpeg'
|
|
871
|
+
: format === 'webp'
|
|
872
|
+
? 'image/webp'
|
|
873
|
+
: 'image/png',
|
|
874
|
+
toOutput = (canvas) => {
|
|
875
|
+
if (as === 'canvas') {
|
|
876
|
+
return canvas;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
return typeof quality === 'number'
|
|
880
|
+
? canvas.toDataURL(mime, quality)
|
|
881
|
+
: canvas.toDataURL(mime);
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
try {
|
|
885
|
+
// Screen-sized framed extract (viewport only).
|
|
886
|
+
return toOutput(renderer.extract.canvas({
|
|
887
|
+
target: stage,
|
|
888
|
+
frame: new Rectangle(0, 0, width, height),
|
|
889
|
+
resolution,
|
|
890
|
+
clearColor
|
|
891
|
+
}));
|
|
892
|
+
} catch (err) {
|
|
893
|
+
platypus.debug.warn('Game.captureViewport framed extract failed; trying bounds crop.', err);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// Paco ScreenShooter fallback: full extract, then crop the screen origin.
|
|
897
|
+
try {
|
|
898
|
+
const
|
|
899
|
+
bounds = stage.getBounds(),
|
|
900
|
+
full = renderer.extract.canvas(stage),
|
|
901
|
+
dest = document.createElement('canvas'),
|
|
902
|
+
ctx = dest.getContext('2d');
|
|
903
|
+
|
|
904
|
+
dest.width = width;
|
|
905
|
+
dest.height = height;
|
|
906
|
+
|
|
907
|
+
if (hasBackground) {
|
|
908
|
+
ctx.fillStyle = `#${backgroundColor.toString(16).padStart(6, '0')}`;
|
|
909
|
+
ctx.fillRect(0, 0, width, height);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
ctx.drawImage(
|
|
913
|
+
full,
|
|
914
|
+
-bounds.x,
|
|
915
|
+
-bounds.y,
|
|
916
|
+
width,
|
|
917
|
+
height,
|
|
918
|
+
0,
|
|
919
|
+
0,
|
|
920
|
+
width,
|
|
921
|
+
height
|
|
922
|
+
);
|
|
923
|
+
|
|
924
|
+
return toOutput(dest);
|
|
925
|
+
} catch (err) {
|
|
926
|
+
platypus.debug.warn('Game.captureViewport failed.', err);
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
826
930
|
|
|
827
931
|
/**
|
|
828
932
|
* This method destroys the game.
|