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-loader": "^7.0.0",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"buffer-loader": "0.0.1", "buffer-loader": "0.0.1",
"canvas-toBlob": "1.0.0",
"copy-webpack-plugin": "4.2.1", "copy-webpack-plugin": "4.2.1",
"decode-html": "2.0.0", "decode-html": "2.0.0",
"escape-html": "1.0.3", "escape-html": "1.0.3",

View file

@ -2,6 +2,7 @@ const TextEncoder = require('text-encoding').TextEncoder;
const EventEmitter = require('events'); const EventEmitter = require('events');
const JSZip = require('jszip'); const JSZip = require('jszip');
const Buffer = require('buffer').Buffer;
const centralDispatch = require('./dispatch/central-dispatch'); const centralDispatch = require('./dispatch/central-dispatch');
const ExtensionManager = require('./extension-support/extension-manager'); const ExtensionManager = require('./extension-support/extension-manager');
const log = require('./util/log'); const log = require('./util/log');
@ -17,6 +18,7 @@ const Variable = require('./engine/variable');
const {loadCostume} = require('./import/load-costume.js'); const {loadCostume} = require('./import/load-costume.js');
const {loadSound} = require('./import/load-sound.js'); const {loadSound} = require('./import/load-sound.js');
const {serializeSounds, serializeCostumes} = require('./serialization/serialize-assets'); const {serializeSounds, serializeCostumes} = require('./serialization/serialize-assets');
require('canvas-toBlob');
const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_']; const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_'];
@ -554,7 +556,7 @@ class VirtualMachine extends EventEmitter {
return this.runtime.storage.get(id).decodeText(); return this.runtime.storage.get(id).decodeText();
} else if (format === this.runtime.storage.DataFormat.PNG || } else if (format === this.runtime.storage.DataFormat.PNG ||
format === this.runtime.storage.DataFormat.JPG) { 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}`); log.error(`Unhandled format: ${this.runtime.storage.get(id).dataFormat}`);
return null; return null;
@ -562,16 +564,17 @@ class VirtualMachine extends EventEmitter {
/** /**
* Update a costume with the given bitmap * Update a costume with the given bitmap
* @param {int} costumeIndex - the index of the costume to be updated. * @param {!int} costumeIndex - the index of the costume to be updated.
* @param {ImageData} bitmap - new bitmap for the renderer. * @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} 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} 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 {!number} bitmapResolution 1 for bitmaps that have 1 pixel per unit of stage,
* 2 for double-resolution bitmaps * 2 for double-resolution bitmaps
*/ */
updateBitmap (costumeIndex, bitmap, rotationCenterX, rotationCenterY, bitmapResolution) { updateBitmap (costumeIndex, bitmap, rotationCenterX, rotationCenterY, bitmapResolution) {
const costume = this.editingTarget.getCostumes()[costumeIndex]; const costume = this.editingTarget.getCostumes()[costumeIndex];
if (costume && this.runtime && this.runtime.renderer) { if (!(costume && this.runtime && this.runtime.renderer)) return;
costume.rotationCenterX = rotationCenterX; costume.rotationCenterX = rotationCenterX;
costume.rotationCenterY = rotationCenterY; costume.rotationCenterY = rotationCenterY;
@ -582,21 +585,33 @@ class VirtualMachine extends EventEmitter {
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
context.putImageData(bitmap, 0, 0); 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( this.runtime.renderer.updateBitmapSkin(
costume.skinId, canvas, bitmapResolution, [rotationCenterX, rotationCenterY]); costume.skinId,
} canvas,
bitmapResolution,
[rotationCenterX / bitmapResolution, rotationCenterY / bitmapResolution]
);
// @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; const storage = this.runtime.storage;
costume.assetId = storage.builtinHelper.cache( costume.assetId = storage.builtinHelper.cache(
storage.AssetType.ImageBitmap, storage.AssetType.ImageBitmap,
storage.DataFormat.PNG, storage.DataFormat.PNG,
bitmap.data Buffer.from(reader.result)
); );
costume.dataFormat = storage.DataFormat.PNG; costume.dataFormat = storage.DataFormat.PNG;
costume.bitmapResolution = bitmapResolution; costume.bitmapResolution = bitmapResolution;
// costume.size = [bitmap.width, bitmap.height]; costume.size = [bitmap.width, bitmap.height];
// costume.md5 = `${costume.assetId}.${costume.dataFormat}`; costume.md5 = `${costume.assetId}.${costume.dataFormat}`;
this.emitTargetsUpdate(); this.emitTargetsUpdate();
});
reader.readAsArrayBuffer(blob);
});
} }
/** /**