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:
DD 2018-04-30 16:35:24 -04:00
parent 9f0f2fcd27
commit 78cd327237
2 changed files with 45 additions and 29 deletions

View file

@ -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",

View file

@ -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);
});
}
/**