mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 06:23:37 -05:00
Move the place where we divide rotation center by resolution into the VM. Also revert the method of putting data into storage to the one that was convoluted but working
This commit is contained in:
parent
9f0f2fcd27
commit
78cd327237
2 changed files with 45 additions and 29 deletions
|
@ -34,6 +34,7 @@
|
|||
"babel-loader": "^7.0.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"buffer-loader": "0.0.1",
|
||||
"canvas-toBlob": "1.0.0",
|
||||
"copy-webpack-plugin": "4.2.1",
|
||||
"decode-html": "2.0.0",
|
||||
"escape-html": "1.0.3",
|
||||
|
|
|
@ -2,6 +2,7 @@ const TextEncoder = require('text-encoding').TextEncoder;
|
|||
const EventEmitter = require('events');
|
||||
const JSZip = require('jszip');
|
||||
|
||||
const Buffer = require('buffer').Buffer;
|
||||
const centralDispatch = require('./dispatch/central-dispatch');
|
||||
const ExtensionManager = require('./extension-support/extension-manager');
|
||||
const log = require('./util/log');
|
||||
|
@ -17,6 +18,7 @@ const Variable = require('./engine/variable');
|
|||
const {loadCostume} = require('./import/load-costume.js');
|
||||
const {loadSound} = require('./import/load-sound.js');
|
||||
const {serializeSounds, serializeCostumes} = require('./serialization/serialize-assets');
|
||||
require('canvas-toBlob');
|
||||
|
||||
const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_'];
|
||||
|
||||
|
@ -554,7 +556,7 @@ class VirtualMachine extends EventEmitter {
|
|||
return this.runtime.storage.get(id).decodeText();
|
||||
} else if (format === this.runtime.storage.DataFormat.PNG ||
|
||||
format === this.runtime.storage.DataFormat.JPG) {
|
||||
return this.runtime.storage.get(id).encodeDataURI('image/png');
|
||||
return this.runtime.storage.get(id).encodeDataURI();
|
||||
}
|
||||
log.error(`Unhandled format: ${this.runtime.storage.get(id).dataFormat}`);
|
||||
return null;
|
||||
|
@ -562,41 +564,54 @@ class VirtualMachine extends EventEmitter {
|
|||
|
||||
/**
|
||||
* Update a costume with the given bitmap
|
||||
* @param {int} costumeIndex - the index of the costume to be updated.
|
||||
* @param {ImageData} bitmap - new bitmap for the renderer.
|
||||
* @param {number} rotationCenterX x of point about which the costume rotates, relative to its upper left corner
|
||||
* @param {number} rotationCenterY y of point about which the costume rotates, relative to its upper left corner
|
||||
* @param {number} bitmapResolution 1 for bitmaps that have 1 pixel per unit of stage,
|
||||
* @param {!int} costumeIndex - the index of the costume to be updated.
|
||||
* @param {!ImageData} bitmap - new bitmap for the renderer.
|
||||
* @param {!number} rotationCenterX x of point about which the costume rotates, relative to its upper left corner
|
||||
* @param {!number} rotationCenterY y of point about which the costume rotates, relative to its upper left corner
|
||||
* @param {!number} bitmapResolution 1 for bitmaps that have 1 pixel per unit of stage,
|
||||
* 2 for double-resolution bitmaps
|
||||
*/
|
||||
updateBitmap (costumeIndex, bitmap, rotationCenterX, rotationCenterY, bitmapResolution) {
|
||||
const costume = this.editingTarget.getCostumes()[costumeIndex];
|
||||
if (costume && this.runtime && this.runtime.renderer) {
|
||||
costume.rotationCenterX = rotationCenterX;
|
||||
costume.rotationCenterY = rotationCenterY;
|
||||
if (!(costume && this.runtime && this.runtime.renderer)) return;
|
||||
|
||||
// @todo: updateBitmapSkin does not take ImageData
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = bitmap.width;
|
||||
canvas.height = bitmap.height;
|
||||
const context = canvas.getContext('2d');
|
||||
context.putImageData(bitmap, 0, 0);
|
||||
|
||||
this.runtime.renderer.updateBitmapSkin(
|
||||
costume.skinId, canvas, bitmapResolution, [rotationCenterX, rotationCenterY]);
|
||||
}
|
||||
costume.rotationCenterX = rotationCenterX;
|
||||
costume.rotationCenterY = rotationCenterY;
|
||||
|
||||
const storage = this.runtime.storage;
|
||||
costume.assetId = storage.builtinHelper.cache(
|
||||
storage.AssetType.ImageBitmap,
|
||||
storage.DataFormat.PNG,
|
||||
bitmap.data
|
||||
// @todo: updateBitmapSkin does not take ImageData
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = bitmap.width;
|
||||
canvas.height = bitmap.height;
|
||||
const context = canvas.getContext('2d');
|
||||
context.putImageData(bitmap, 0, 0);
|
||||
|
||||
// Divide by resolution because the renderer's definition of the rotation center
|
||||
// is the rotation center divided by the bitmap resolution
|
||||
this.runtime.renderer.updateBitmapSkin(
|
||||
costume.skinId,
|
||||
canvas,
|
||||
bitmapResolution,
|
||||
[rotationCenterX / bitmapResolution, rotationCenterY / bitmapResolution]
|
||||
);
|
||||
costume.dataFormat = storage.DataFormat.PNG;
|
||||
costume.bitmapResolution = bitmapResolution;
|
||||
// costume.size = [bitmap.width, bitmap.height];
|
||||
// costume.md5 = `${costume.assetId}.${costume.dataFormat}`;
|
||||
this.emitTargetsUpdate();
|
||||
|
||||
// @todo there should be a better way to get from ImageData to a decodable storage format
|
||||
canvas.toBlob(blob => {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('loadend', () => {
|
||||
const storage = this.runtime.storage;
|
||||
costume.assetId = storage.builtinHelper.cache(
|
||||
storage.AssetType.ImageBitmap,
|
||||
storage.DataFormat.PNG,
|
||||
Buffer.from(reader.result)
|
||||
);
|
||||
costume.dataFormat = storage.DataFormat.PNG;
|
||||
costume.bitmapResolution = bitmapResolution;
|
||||
costume.size = [bitmap.width, bitmap.height];
|
||||
costume.md5 = `${costume.assetId}.${costume.dataFormat}`;
|
||||
this.emitTargetsUpdate();
|
||||
});
|
||||
reader.readAsArrayBuffer(blob);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue