kopia lustrzana https://github.com/backface/turtlestitch
migrated paint editor
rodzic
d73eb824b3
commit
0d053d3ff7
|
@ -11,9 +11,7 @@
|
|||
<script type="text/javascript" src="src/threads.js?version=2019-12-19"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2020-01-28"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2020-01-28"></script>
|
||||
<!--
|
||||
<script type="text/javascript" src="src/paint.js?version=2019-06-27"></script>
|
||||
//-->
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-12-08"></script>
|
||||
<script type="text/javascript" src="src/byob.js?version=2020-01-03"></script>
|
||||
<script type="text/javascript" src="src/tables.js?version=2020-01-03"></script>
|
||||
|
|
131
src/paint.js
131
src/paint.js
|
@ -68,6 +68,8 @@
|
|||
2018
|
||||
Jan 22 - floodfill alpha tweak (Bernat)
|
||||
Mar 19 - vector paint editor (Bernat)
|
||||
|
||||
2020 Apr 14 - partial Morphic2 migration (Jens)
|
||||
*/
|
||||
|
||||
/*global Point, Rectangle, DialogBoxMorph, AlignmentMorph, PushButtonMorph,
|
||||
|
@ -78,7 +80,7 @@ StageMorph, isNil, SVG_Costume*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.paint = '2019-February-22';
|
||||
modules.paint = '2020-April-14';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -164,7 +166,6 @@ PaintEditorMorph.prototype.buildContents = function () {
|
|||
|
||||
this.refreshToolButtons();
|
||||
this.fixLayout();
|
||||
this.drawNew();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.buildToolbox = function () {
|
||||
|
@ -216,7 +217,6 @@ PaintEditorMorph.prototype.buildToolbox = function () {
|
|||
});
|
||||
|
||||
this.toolbox.bounds = this.toolbox.fullBounds().expandBy(inset * 2);
|
||||
this.toolbox.drawNew();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.buildEdits = function () {
|
||||
|
@ -316,12 +316,7 @@ PaintEditorMorph.prototype.openIn = function (
|
|||
};
|
||||
|
||||
PaintEditorMorph.prototype.fixLayout = function () {
|
||||
var oldFlag = Morph.prototype.trackChanges;
|
||||
|
||||
this.changed();
|
||||
oldFlag = Morph.prototype.trackChanges;
|
||||
Morph.prototype.trackChanges = false;
|
||||
|
||||
if (this.paper) {
|
||||
this.paper.buildContents();
|
||||
this.paper.drawNew();
|
||||
|
@ -329,8 +324,6 @@ PaintEditorMorph.prototype.fixLayout = function () {
|
|||
if (this.controls) {this.controls.fixLayout(); }
|
||||
if (this.body) {this.body.fixLayout(); }
|
||||
PaintEditorMorph.uber.fixLayout.call(this);
|
||||
|
||||
Morph.prototype.trackChanges = oldFlag;
|
||||
this.changed();
|
||||
};
|
||||
|
||||
|
@ -375,42 +368,47 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function () {
|
|||
alpen = new AlignmentMorph("row", this.padding);
|
||||
|
||||
pc.primaryColorViewer = new Morph();
|
||||
pc.primaryColorViewer.isCachingImage = true;
|
||||
|
||||
pc.primaryColorViewer.render = function (ctx) {
|
||||
var color = myself.paper.settings.primarycolor,
|
||||
i,
|
||||
j;
|
||||
if (color === "transparent") {
|
||||
for (i = 0; i < 180; i += 5) {
|
||||
for (j = 0; j < 15; j += 5) {
|
||||
ctx.fillStyle =
|
||||
((j + i) / 5) % 2 === 0 ?
|
||||
"rgba(0, 0, 0, 0.2)" :
|
||||
"rgba(0, 0, 0, 0.5)";
|
||||
ctx.fillRect(i, j, 5, 5);
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.fillStyle = color.toString();
|
||||
ctx.fillRect(0, 0, 180, 15);
|
||||
}
|
||||
ctx.strokeStyle = "black";
|
||||
ctx.lineWidth = Math.min(myself.paper.settings.linewidth, 20);
|
||||
ctx.beginPath();
|
||||
ctx.lineCap = "round";
|
||||
ctx.moveTo(20, 30);
|
||||
ctx.lineTo(160, 30);
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
pc.primaryColorViewer.setExtent(new Point(180, 50));
|
||||
pc.primaryColorViewer.color = new Color(0, 0, 0);
|
||||
|
||||
pc.colorpicker = new PaintColorPickerMorph(
|
||||
new Point(180, 100),
|
||||
function (color) {
|
||||
var ni = newCanvas(pc.primaryColorViewer.extent()),
|
||||
ctx = ni.getContext("2d"),
|
||||
i,
|
||||
j;
|
||||
myself.paper.settings.primarycolor = color;
|
||||
if (color === "transparent") {
|
||||
for (i = 0; i < 180; i += 5) {
|
||||
for (j = 0; j < 15; j += 5) {
|
||||
ctx.fillStyle =
|
||||
((j + i) / 5) % 2 === 0 ?
|
||||
"rgba(0, 0, 0, 0.2)" :
|
||||
"rgba(0, 0, 0, 0.5)";
|
||||
ctx.fillRect(i, j, 5, 5);
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.fillStyle = color.toString();
|
||||
ctx.fillRect(0, 0, 180, 15);
|
||||
}
|
||||
ctx.strokeStyle = "black";
|
||||
ctx.lineWidth = Math.min(myself.paper.settings.linewidth, 20);
|
||||
ctx.beginPath();
|
||||
ctx.lineCap = "round";
|
||||
ctx.moveTo(20, 30);
|
||||
ctx.lineTo(160, 30);
|
||||
ctx.stroke();
|
||||
pc.primaryColorViewer.image = ni;
|
||||
pc.primaryColorViewer.changed();
|
||||
pc.primaryColorViewer.rerender();
|
||||
}
|
||||
);
|
||||
pc.colorpicker.isCachingImage = true;
|
||||
pc.colorpicker.action(new Color(0, 0, 0));
|
||||
|
||||
pc.penSizeSlider = new SliderMorph(0, 20, 5, 5);
|
||||
|
@ -424,24 +422,26 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function () {
|
|||
myself.paper.settings.linewidth = num;
|
||||
pc.colorpicker.action(myself.paper.settings.primarycolor);
|
||||
};
|
||||
|
||||
pc.penSizeField = new InputFieldMorph("5", true, null, false);
|
||||
pc.penSizeField.contents().minWidth = 20;
|
||||
pc.penSizeField.setWidth(25);
|
||||
pc.penSizeField.accept = function () {
|
||||
var val = parseFloat(pc.penSizeField.getValue());
|
||||
pc.penSizeSlider.value = val;
|
||||
pc.penSizeSlider.drawNew();
|
||||
pc.penSizeSlider.updateValue();
|
||||
this.setContents(val);
|
||||
myself.paper.settings.linewidth = val;
|
||||
this.world().keyboardReceiver = myself;
|
||||
this.world().keyboardFocus = myself;
|
||||
pc.colorpicker.action(myself.paper.settings.primarycolor);
|
||||
};
|
||||
|
||||
alpen.add(pc.penSizeSlider);
|
||||
alpen.add(pc.penSizeField);
|
||||
alpen.color = myself.color;
|
||||
alpen.fixLayout();
|
||||
pc.penSizeField.drawNew();
|
||||
|
||||
pc.penSizeField.fixLayout();
|
||||
pc.constrain = new ToggleMorph(
|
||||
"checkbox",
|
||||
this,
|
||||
|
@ -449,6 +449,7 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function () {
|
|||
"Constrain proportions of shapes?\n(you can also hold shift)",
|
||||
function () {return myself.shift; }
|
||||
);
|
||||
|
||||
c.add(pc.colorpicker);
|
||||
//c.add(pc.primaryColorButton);
|
||||
c.add(pc.primaryColorViewer);
|
||||
|
@ -476,8 +477,6 @@ PaintEditorMorph.prototype.toolButton = function (icon, hint) {
|
|||
);
|
||||
|
||||
button.hint = hint;
|
||||
button.drawNew();
|
||||
button.fixLayout();
|
||||
return button;
|
||||
};
|
||||
|
||||
|
@ -541,16 +540,14 @@ function PaintColorPickerMorph(extent, action) {
|
|||
}
|
||||
|
||||
PaintColorPickerMorph.prototype.init = function (extent, action) {
|
||||
this.isCachingImage = true;
|
||||
this.setExtent(extent || new Point(200, 100));
|
||||
this.action = action || nop;
|
||||
this.drawNew();
|
||||
};
|
||||
|
||||
PaintColorPickerMorph.prototype.drawNew = function () {
|
||||
PaintColorPickerMorph.prototype.render = function (ctx) {
|
||||
var x = 0,
|
||||
y = 0,
|
||||
can = newCanvas(this.extent()),
|
||||
ctx = can.getContext("2d"),
|
||||
colorselection,
|
||||
r;
|
||||
for (x = 0; x < this.width(); x += 1) {
|
||||
|
@ -587,7 +584,6 @@ PaintColorPickerMorph.prototype.drawNew = function () {
|
|||
}
|
||||
}
|
||||
}
|
||||
this.image = can;
|
||||
};
|
||||
|
||||
PaintColorPickerMorph.prototype.mouseDownLeft = function (pos) {
|
||||
|
@ -624,10 +620,10 @@ PaintCanvasMorph.prototype.init = function (shift) {
|
|||
this.dragRect = new Rectangle();
|
||||
// rectangle with origin being the starting drag position and
|
||||
// corner being the current drag position
|
||||
this.mask = newCanvas(this.extent(), true); // Temporary canvas
|
||||
this.paper = newCanvas(this.extent(), true); // Actual canvas
|
||||
this.erasermask = newCanvas(this.extent(), true); // eraser memory
|
||||
this.background = newCanvas(this.extent()); // checkers
|
||||
this.mask = null; // Temporary canvas
|
||||
this.paper = null; // Actual canvas
|
||||
this.erasermask = null; // eraser memory
|
||||
this.background = null; // checkers
|
||||
this.settings = {
|
||||
"primarycolor": new Color(0, 0, 0, 255), // usually fill color
|
||||
"secondarycolor": new Color(0, 0, 0, 255), // (unused)
|
||||
|
@ -642,8 +638,9 @@ PaintCanvasMorph.prototype.init = function (shift) {
|
|||
// should we calculate the center of the image ourselves,
|
||||
// or use the user position
|
||||
this.automaticCrosshairs = true;
|
||||
this.noticesTransparentClick = true; // optimization
|
||||
this.isCachingImage = true;
|
||||
this.buildContents();
|
||||
this.drawNew();
|
||||
};
|
||||
|
||||
// Calculate the center of all the non-transparent pixels on the canvas.
|
||||
|
@ -721,12 +718,11 @@ PaintCanvasMorph.prototype.centermerge = function (a, b) {
|
|||
|
||||
PaintCanvasMorph.prototype.clearCanvas = function () {
|
||||
this.buildContents();
|
||||
this.drawNew();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.toolChanged = function (tool) {
|
||||
this.mask = newCanvas(this.extent(), true);
|
||||
this.mask = newCanvas(this.extent(), true, this.mask);
|
||||
if (tool === "crosshairs") {
|
||||
this.updateAutomaticCenter();
|
||||
this.drawcrosshair();
|
||||
|
@ -739,6 +735,7 @@ PaintCanvasMorph.prototype.drawcrosshair = function (context) {
|
|||
var ctx = context || this.mask.getContext("2d"),
|
||||
rp = this.rotationCenter;
|
||||
|
||||
ctx.save();
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.clearRect(0, 0, this.mask.width, this.mask.height);
|
||||
|
@ -784,8 +781,9 @@ PaintCanvasMorph.prototype.drawcrosshair = function (context) {
|
|||
ctx.lineTo(rp.x, this.mask.height);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
|
||||
this.drawNew();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.floodfill = function (sourcepoint) {
|
||||
|
@ -867,7 +865,7 @@ PaintCanvasMorph.prototype.mouseDownLeft = function (pos) {
|
|||
}
|
||||
if (this.settings.primarycolor === "transparent" &&
|
||||
this.currentTool !== "crosshairs") {
|
||||
this.erasermask = newCanvas(this.extent(), true);
|
||||
this.erasermask = newCanvas(this.extent(), true, this.erasermask);
|
||||
this.merge(this.paper, this.erasermask);
|
||||
}
|
||||
};
|
||||
|
@ -1017,8 +1015,8 @@ PaintCanvasMorph.prototype.mouseMove = function (pos) {
|
|||
}
|
||||
this.previousDragPoint = relpos;
|
||||
this.drawNew();
|
||||
this.changed();
|
||||
mctx.restore();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.mouseClickLeft = function () {
|
||||
|
@ -1032,10 +1030,10 @@ PaintCanvasMorph.prototype.mouseLeaveDragging
|
|||
= PaintCanvasMorph.prototype.mouseClickLeft;
|
||||
|
||||
PaintCanvasMorph.prototype.buildContents = function () {
|
||||
this.background = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent(), true);
|
||||
this.mask = newCanvas(this.extent(), true);
|
||||
this.erasermask = newCanvas(this.extent(), true);
|
||||
this.background = newCanvas(this.extent(), false, this.background);
|
||||
this.paper = newCanvas(this.extent(), true, this.paper);
|
||||
this.mask = newCanvas(this.extent(), true, this.mask);
|
||||
this.erasermask = newCanvas(this.extent(), true, this.erasermask);
|
||||
var i, j, bkctx = this.background.getContext("2d");
|
||||
for (i = 0; i < this.background.width; i += 5) {
|
||||
for (j = 0; j < this.background.height; j += 5) {
|
||||
|
@ -1050,18 +1048,21 @@ PaintCanvasMorph.prototype.buildContents = function () {
|
|||
};
|
||||
|
||||
PaintCanvasMorph.prototype.drawNew = function () {
|
||||
var can = newCanvas(this.extent(), true);
|
||||
var can = newCanvas(this.extent(), true, this.cachedImage);
|
||||
this.merge(this.background, can);
|
||||
this.merge(this.paper, can);
|
||||
this.merge(this.mask, can);
|
||||
this.image = can;
|
||||
this.cachedImage = can;
|
||||
this.drawFrame();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.rerender // ugly hack, but hey, it works ;-) jens
|
||||
= PaintCanvasMorph.prototype.drawNew;
|
||||
|
||||
PaintCanvasMorph.prototype.drawFrame = function () {
|
||||
var context, borderColor;
|
||||
|
||||
context = this.image.getContext('2d');
|
||||
context = this.cachedImage.getContext('2d');
|
||||
if (this.parent) {
|
||||
this.color = this.parent.color.lighter(this.contrast * 0.75);
|
||||
borderColor = this.parent.color;
|
||||
|
|
Ładowanie…
Reference in New Issue