kopia lustrzana https://github.com/backface/turtlestitch
new experimental "paste on" block in the "pen" category
currently hidden in dev modepull/89/head
rodzic
681de687c0
commit
a2237b7a53
|
@ -2,12 +2,14 @@
|
|||
|
||||
## in development:
|
||||
* **New Features:**
|
||||
* new experimental "paste on" block in the "pen" category, currently hidden in dev mode
|
||||
* **Notable Changes:**
|
||||
* **Notable Fixes:**
|
||||
* **Translation Updates:**
|
||||
|
||||
### 2019-08-06
|
||||
* new dev version
|
||||
* objects, threads: new experimental "paste on" block in the "pen" category, hidden in dev mode
|
||||
|
||||
## v5.0.8
|
||||
* **Notable Fix:**
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
<script type="text/javascript" src="src/morphic.js?version=2019-07-23"></script>
|
||||
<script type="text/javascript" src="src/widgets.js?version=2019-06-27"></script>
|
||||
<script type="text/javascript" src="src/blocks.js?version=2019-07-25"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-07-15"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-07-15"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-08-06"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-08-06"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-08-06"></script>
|
||||
<script type="text/javascript" src="src/paint.js?version=2019-06-27"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-07-01"></script>
|
||||
|
|
158
src/objects.js
158
src/objects.js
|
@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, BooleanSlotMorph,
|
|||
localize, TableMorph, TableFrameMorph, normalizeCanvas, VectorPaintEditorMorph,
|
||||
HandleMorph, AlignmentMorph, Process, XML_Element, WorldMap*/
|
||||
|
||||
modules.objects = '2019-July-15';
|
||||
modules.objects = '2019-August-06';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -678,6 +678,14 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
spec: 'pen trails'
|
||||
},
|
||||
|
||||
// Pen - experimental primitives for development mode
|
||||
doPasteOn: {
|
||||
dev: true,
|
||||
type: 'command',
|
||||
category: 'pen',
|
||||
spec: 'paste on %spr'
|
||||
},
|
||||
|
||||
// Control
|
||||
receiveGo: {
|
||||
type: 'hat',
|
||||
|
@ -2316,6 +2324,24 @@ SpriteMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('write'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('reportPenTrailsAsCostume'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
if (this.world().isDevMode) {
|
||||
|
||||
blocks.push('-');
|
||||
txt = new TextMorph(localize(
|
||||
'development mode \ndebugging primitives:'
|
||||
));
|
||||
txt.fontSize = 9;
|
||||
txt.setColor(this.paletteTextColor);
|
||||
blocks.push(txt);
|
||||
blocks.push('-');
|
||||
blocks.push(block('doPasteOn'));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
blocks.push('=');
|
||||
blocks.push(this.makeBlockButton(cat));
|
||||
|
||||
|
@ -4311,6 +4337,114 @@ SpriteMorph.prototype.changeSize = function (delta) {
|
|||
this.setSize(this.size + (+delta || 0));
|
||||
};
|
||||
|
||||
// SpriteMorph printing on another sprite:
|
||||
|
||||
SpriteMorph.prototype.pasteOn = function (target) {
|
||||
// draw my costume onto a copy of the target's costume scaled and rotated
|
||||
// so it appears as though I'm "stamped" onto it.
|
||||
|
||||
var sourceHeading = (this.rotationStyle === 1) ? this.heading : 90,
|
||||
targetHeading = (target.rotationStyle === 1) ? target.heading : 90,
|
||||
sourceCostume, targetCostume, ctx,
|
||||
relRot, relScale, stageScale,
|
||||
centerDist, centerDelta, centerAngleRadians, center,
|
||||
originDist, originAngleRadians,
|
||||
spriteCenter, thisCenter, relPos, pos;
|
||||
|
||||
// prevent pasting an object onto itself
|
||||
if (this === target) {return; }
|
||||
|
||||
// check if both source and target have costumes,
|
||||
// rasterize copy of target costume if it's an SVG
|
||||
if (this.costume && target.costume) {
|
||||
sourceCostume = this.costume;
|
||||
if (sourceCostume instanceof SVG_Costume) {
|
||||
sourceCostume = sourceCostume.rasterized();
|
||||
}
|
||||
if (target.costume instanceof SVG_Costume) {
|
||||
targetCostume = target.costume.rasterized();
|
||||
} else {
|
||||
targetCostume = target.costume.copy();
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// do the math:
|
||||
if (target instanceof SpriteMorph) {
|
||||
if (this instanceof SpriteMorph) {
|
||||
// stamp a sprite on a sprite:
|
||||
relRot = sourceHeading - targetHeading;
|
||||
relScale = this.scale / target.scale;
|
||||
stageScale = this.parentThatIsA(StageMorph).scale;
|
||||
centerDist = target.center().distanceTo(this.center());
|
||||
centerDelta = this.center().subtract(target.center());
|
||||
centerAngleRadians = Math.atan2(centerDelta.y, centerDelta.x);
|
||||
center = new Point(
|
||||
sourceCostume.width(),
|
||||
sourceCostume.height()
|
||||
).multiplyBy(0.5 * this.scale * stageScale);
|
||||
originDist = center.distanceTo(new Point(0, 0));
|
||||
originAngleRadians = Math.atan2(center.y, center.x);
|
||||
spriteCenter = new Point(
|
||||
target.costume.width(),
|
||||
target.costume.height()
|
||||
).multiplyBy(0.5 * target.scale * stageScale)
|
||||
.rotateBy(radians(relRot));
|
||||
thisCenter = spriteCenter.distanceAngle(
|
||||
centerDist,
|
||||
degrees(centerAngleRadians) - sourceHeading + 180
|
||||
);
|
||||
relPos = thisCenter.distanceAngle(
|
||||
originDist,
|
||||
degrees(originAngleRadians) -90
|
||||
);
|
||||
pos = relPos.divideBy(stageScale)
|
||||
.divideBy(relScale)
|
||||
.divideBy(target.scale);
|
||||
} else { // if the stage is the source
|
||||
// stamp the stage on a sprite:
|
||||
relRot = 90 - targetHeading;
|
||||
relScale = 1 / target.scale;
|
||||
centerDist = target.center().distanceTo(this.position());
|
||||
centerDelta = this.position().subtract(target.center());
|
||||
centerAngleRadians = Math.atan2(centerDelta.y, centerDelta.x);
|
||||
center = new Point(
|
||||
target.costume.width(),
|
||||
target.costume.height()
|
||||
).multiplyBy(0.5 * target.scale)
|
||||
.rotateBy(radians(90 - targetHeading));
|
||||
pos = center.distanceAngle(
|
||||
centerDist / this.scale,
|
||||
degrees(centerAngleRadians) + 90
|
||||
);
|
||||
}
|
||||
} else { // if the stage is the target
|
||||
// stamp a sprite on the stage:
|
||||
relRot = sourceHeading - 90;
|
||||
relScale = this.scale;
|
||||
center = this.center().subtract(target.position())
|
||||
.divideBy(this.scale * target.scale)
|
||||
.rotateBy(radians(sourceHeading - 90));
|
||||
pos = center.subtract(
|
||||
new Point(
|
||||
sourceCostume.width(),
|
||||
sourceCostume.height()
|
||||
).multiplyBy(0.5)
|
||||
);
|
||||
}
|
||||
|
||||
// draw my costume onto the target's costume copy:
|
||||
ctx = targetCostume.contents.getContext('2d');
|
||||
ctx.rotate(radians(relRot));
|
||||
ctx.scale(relScale, relScale);
|
||||
ctx.globalCompositeOperation = 'source-atop';
|
||||
ctx.drawImage(sourceCostume.contents, pos.x, pos.y);
|
||||
|
||||
// make the target wear the new costume
|
||||
target.doSwitchToCostume(targetCostume);
|
||||
};
|
||||
|
||||
// SpriteMorph pen up and down:
|
||||
|
||||
SpriteMorph.prototype.down = function () {
|
||||
|
@ -8162,6 +8296,24 @@ StageMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('setBackgroundHSVA'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('reportPenTrailsAsCostume'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
if (this.world().isDevMode) {
|
||||
|
||||
blocks.push('-');
|
||||
txt = new TextMorph(localize(
|
||||
'development mode \ndebugging primitives:'
|
||||
));
|
||||
txt.fontSize = 9;
|
||||
txt.setColor(this.paletteTextColor);
|
||||
blocks.push(txt);
|
||||
blocks.push('-');
|
||||
blocks.push(block('doPasteOn'));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
blocks.push('=');
|
||||
blocks.push(this.makeBlockButton(cat));
|
||||
|
||||
|
@ -8652,6 +8804,10 @@ StageMorph.prototype.setBackgroundColor = StageMorph.prototype.setColor;
|
|||
StageMorph.prototype.getPenAttribute
|
||||
= SpriteMorph.prototype.getPenAttribute;
|
||||
|
||||
// StageMorph printing on another sprite:
|
||||
|
||||
StageMorph.prototype.pasteOn = SpriteMorph.prototype.pasteOn;
|
||||
|
||||
// StageMorph pseudo-inherited behavior
|
||||
|
||||
StageMorph.prototype.categories = SpriteMorph.prototype.categories;
|
||||
|
|
|
@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
|||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
|
||||
TableFrameMorph, ColorSlotMorph, isSnapObject, Map, newCanvas, Symbol*/
|
||||
|
||||
modules.threads = '2019-July-15';
|
||||
modules.threads = '2019-August-06';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -3762,6 +3762,31 @@ Process.prototype.changePenHSVA = Process.prototype.changeHSVA;
|
|||
Process.prototype.setBackgroundHSVA = Process.prototype.setHSVA;
|
||||
Process.prototype.changeBackgroundHSVA = Process.prototype.changeHSVA;
|
||||
|
||||
// Process pasting primitives
|
||||
|
||||
Process.prototype.doPasteOn = function (name, thisObj, stage) {
|
||||
// allow for lists of sprites and also check for temparary clones,
|
||||
// as in Scratch 2.0,
|
||||
var myself = this,
|
||||
those;
|
||||
thisObj = thisObj || this.blockReceiver();
|
||||
stage = stage || thisObj.parentThatIsA(StageMorph);
|
||||
if (stage.name === name) {
|
||||
name = stage;
|
||||
}
|
||||
if (isSnapObject(name)) {
|
||||
return thisObj.pasteOn(name);
|
||||
}
|
||||
if (name instanceof List) { // assume all elements to be sprites
|
||||
those = name.itemsArray();
|
||||
} else {
|
||||
those = this.getObjectsNamed(name, thisObj, stage); // clones
|
||||
}
|
||||
those.forEach(function (each) {
|
||||
myself.doPasteOn(each, thisObj, stage);
|
||||
});
|
||||
};
|
||||
|
||||
// Process temporary cloning (Scratch-style)
|
||||
|
||||
Process.prototype.createClone = function (name) {
|
||||
|
|
Ładowanie…
Reference in New Issue