diff --git a/src/blocks/scratch3_pen.js b/src/blocks/scratch3_pen.js index 5ba505cb7..13c0ed42b 100644 --- a/src/blocks/scratch3_pen.js +++ b/src/blocks/scratch3_pen.js @@ -40,7 +40,10 @@ class Scratch3PenBlocks { */ this._penSkinId = -1; + this._onTargetCreated = this._onTargetCreated.bind(this); this._onTargetMoved = this._onTargetMoved.bind(this); + + runtime.on('targetWasCreated', this._onTargetCreated); } /** @@ -129,6 +132,25 @@ class Scratch3PenBlocks { return penState; } + /** + * When a pen-using Target is cloned, clone the pen state. + * @param {Target} newTarget - the newly created target. + * @param {Target} [sourceTarget] - the target used as a source for the new clone, if any. + * @listens Runtime#event:targetWasCreated + * @private + */ + _onTargetCreated (newTarget, sourceTarget) { + if (sourceTarget) { + const penState = sourceTarget.getCustomState(Scratch3PenBlocks.STATE_KEY); + if (penState) { + newTarget.setCustomState(Scratch3PenBlocks.STATE_KEY, Clone.simple(penState)); + if (penState.penDown) { + newTarget.addListener(RenderedTarget.EVENT_TARGET_MOVED, this._onTargetMoved); + } + } + } + } + /** * Handle a target which has moved. This only fires when the pen is down. * @param {RenderedTarget} target - the target which has moved. diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 80a404002..1e06121d0 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -968,6 +968,16 @@ class Runtime extends EventEmitter { return this._cloneCounter < Runtime.MAX_CLONES; } + /** + * Report that a new target has been created, possibly by cloning an existing target. + * @param {Target} newTarget - the newly created target. + * @param {Target} [sourceTarget] - the target used as a source for the new clone, if any. + * @fires Runtime#targetWasCreated + */ + fireTargetWasCreated (newTarget, sourceTarget) { + this.emit('targetWasCreated', newTarget, sourceTarget); + } + /** * Get a target representing the Scratch stage, if one exists. * @return {?Target} The target, if found. @@ -1014,4 +1024,12 @@ class Runtime extends EventEmitter { } } +/** + * Event fired after a new target has been created, possibly by cloning an existing target. + * + * @event Runtime#targetWasCreated + * @param {Target} newTarget - the newly created target. + * @param {Target} [sourceTarget] - the target used as a source for the new clone, if any. + */ + module.exports = Runtime; diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index af29be0fd..7f7fbe0d6 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -732,7 +732,6 @@ class RenderedTarget extends Target { newClone.effects = JSON.parse(JSON.stringify(this.effects)); newClone.variables = JSON.parse(JSON.stringify(this.variables)); newClone.lists = JSON.parse(JSON.stringify(this.lists)); - newClone._customState = JSON.parse(JSON.stringify(this._customState)); newClone.initDrawable(); newClone.updateAllDrawableProperties(); // Place behind the current target. diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js index 293a1f265..9e36c8fea 100644 --- a/src/sprites/sprite.js +++ b/src/sprites/sprite.js @@ -55,6 +55,9 @@ class Sprite { this.clones.push(newClone); if (newClone.isOriginal) { newClone.initDrawable(); + this.runtime.fireTargetWasCreated(newClone); + } else { + this.runtime.fireTargetWasCreated(newClone, this.clones[0]); } return newClone; }