Skip to content

Commit ebd00c2

Browse files
committed
Mirrored rendering for negative dimensions with rect().
ellipse() and arc() use absolute values
1 parent 0923553 commit ebd00c2

File tree

7 files changed

+25
-11
lines changed

7 files changed

+25
-11
lines changed

src/core/helpers.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ function modeAdjust(a, b, c, d, mode) {
1616
if (mode === constants.CORNER) {
1717

1818
// CORNER mode already corresponds to a bounding box (top-left corner, width, height).
19-
// Negative dimensions (width and/or height) result in 'flipping' the shape.
20-
if (c < 0) { c = -c; a -= c; } // Negative width: Move shape to the left (flip left)
21-
if (d < 0) { d = -d; b -= d; } // Negative height: Move shape up (flip up)
19+
// For negative widhts or heights, the absolute value is used.
2220
bbox = {
2321
x: a,
2422
y: b,
25-
w: c,
26-
h: d
23+
w: Math.abs(c),
24+
h: Math.abs(d)
2725
};
2826

2927
} else if (mode === constants.CORNERS) {

src/core/shape/2d_primitives.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,15 @@ p5.prototype._renderRect = function() {
13391339
this._renderer._rectMode
13401340
);
13411341

1342+
// For the default rectMode (CORNER), restore a possible negative width/height
1343+
// removed by modeAdjust(). This results in flipped/mirrored rendering,
1344+
// which is especially noticable when using WEGBL rendering and texture().
1345+
// Note that this behavior only applies to rect(), NOT to ellipse() and arc().
1346+
if (this._renderer._rectMode === constants.CORNER) {
1347+
vals.w = arguments[2];
1348+
vals.h = arguments[3];
1349+
}
1350+
13421351
const args = [vals.x, vals.y, vals.w, vals.h];
13431352
// append the additional arguments (either cornder radii, or
13441353
// segment details) to the argument list

test/unit/visual/cases/shape_modes.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ function shapeCorners(p5, shape, mode, x1, y1, x2, y2) {
1717
// Don't use abs(), so we get negative values as well
1818
let w = x2 - x1; // w
1919
let h = y2 - y1; // h
20-
// With mode CORNER, negative widths/heights result in mirrored/flipped shapes
21-
// In this case, adjust position so the shape is in line with the other cases
22-
if (w < 0) { x += (-w); } // Move right
23-
if (h < 0) { y += (-h); } // Move down
20+
// With mode CORNER, rects with negative widths/heights result in mirrored/flipped rendering
21+
// In this case, adjust position so the rect is in line with the other cases
22+
if (shape === 'rect') {
23+
if (w < 0) { x += (-w); } // Move right
24+
if (h < 0) { y += (-h); } // Move down
25+
}
2426
x1 = x; y1 = y; x2 = w; y2 = h;
2527
} else if (mode === p5.CENTER) {
2628
// Find center
@@ -124,10 +126,11 @@ visualSuite('Shape Modes', function(...args) {
124126

125127
/*
126128
An extra test suite specific to shape mode CORNER and negative dimensions.
127-
Negative width should result in the shape flipped horizontally (to the left).
128-
Negative height should result in the shape flipped vertically (up).
129+
For rect, negative widths/heights result in flipped rendering (horizontally/vertically)
130+
For ellipse and arc, using negative widths/heights has no effect (the absolute value is used)
129131
*/
130132
visualSuite('Negative dimensions', function() {
133+
// Negative widths/height result in flipped rects.
131134
visualTest('rect', function(p5, screenshot) {
132135
p5.createCanvas(50, 50);
133136
p5.translate(p5.width/2, p5.height/2);
@@ -141,6 +144,8 @@ visualSuite('Shape Modes', function(...args) {
141144
p5.rect(0, 0, -20, -10);
142145
screenshot();
143146
});
147+
// Since negative widths/heights are used with their absolute value,
148+
// ellipses are drawn on top of each other, blue one last
144149
visualTest('ellipse', function(p5, screenshot) {
145150
p5.createCanvas(50, 50);
146151
p5.translate(p5.width/2, p5.height/2);
@@ -154,6 +159,8 @@ visualSuite('Shape Modes', function(...args) {
154159
p5.ellipse(0, 0, -20, -10);
155160
screenshot();
156161
});
162+
// Since negative widths/heights are used with their absolute value,
163+
// arcs are drawn on top of each other, blue one last.
157164
visualTest('arc', function(p5, screenshot) {
158165
p5.createCanvas(50, 50);
159166
p5.translate(p5.width/2, p5.height/2);
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)