mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-02-11 16:12:06 +08:00
Make texture editing tools work with selections
Selection fixes
This commit is contained in:
parent
05fc5561db
commit
de47f418bf
@ -22,9 +22,11 @@ BARS.defineActions(function() {
|
||||
texture.edit((canvas) => {
|
||||
|
||||
let ctx = canvas.getContext('2d');
|
||||
texture.selection.maskCanvas(ctx);
|
||||
ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
ctx.filter = 'invert(1)';
|
||||
ctx.drawImage(texture.img, 0, 0);
|
||||
ctx.restore();
|
||||
|
||||
}, {no_undo: true});
|
||||
})
|
||||
@ -59,6 +61,7 @@ BARS.defineActions(function() {
|
||||
textures.forEach((texture, i) => {
|
||||
texture.edit((canvas) => {
|
||||
let ctx = canvas.getContext('2d');
|
||||
texture.selection.maskCanvas(ctx);
|
||||
ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
if (this.preview_changes) {
|
||||
ctx.filter = `brightness(${this.brightness / 100}) contrast(${this.contrast / 100})`;
|
||||
@ -66,6 +69,7 @@ BARS.defineActions(function() {
|
||||
ctx.filter = `brightness(1.0) contrast(1.0)`;
|
||||
}
|
||||
ctx.drawImage(original_imgs[i], 0, 0);
|
||||
ctx.restore();
|
||||
|
||||
let ref_ctx = this.$refs.canvas[i].getContext('2d');
|
||||
ref_ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
@ -147,6 +151,7 @@ BARS.defineActions(function() {
|
||||
textures.forEach((texture, i) => {
|
||||
texture.edit((canvas) => {
|
||||
let ctx = canvas.getContext('2d');
|
||||
texture.selection.maskCanvas(ctx);
|
||||
ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
if (this.preview_changes) {
|
||||
ctx.filter = `saturate(${this.saturation / 100}) hue-rotate(${this.hue}deg)`;
|
||||
@ -154,6 +159,7 @@ BARS.defineActions(function() {
|
||||
ctx.filter = `brightness(1.0)`;
|
||||
}
|
||||
ctx.drawImage(original_imgs[i], 0, 0);
|
||||
ctx.restore();
|
||||
|
||||
let ref_ctx = this.$refs.canvas[i].getContext('2d');
|
||||
ref_ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
@ -511,6 +517,7 @@ BARS.defineActions(function() {
|
||||
textures.forEach((texture, i) => {
|
||||
texture.edit((canvas) => {
|
||||
let ctx = canvas.getContext('2d');
|
||||
texture.selection.maskCanvas(ctx);
|
||||
ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
if (this.preview_changes) {
|
||||
ctx.filter = `opacity(${this.opacity}%)`;
|
||||
@ -523,6 +530,7 @@ BARS.defineActions(function() {
|
||||
ctx.filter = `opacity(100%)`;
|
||||
ctx.drawImage(original_imgs[i], 0, 0);
|
||||
}
|
||||
ctx.restore();
|
||||
|
||||
let ref_ctx = this.$refs.canvas[i].getContext('2d');
|
||||
ref_ctx.clearRect(0, 0, texture.width, texture.height);
|
||||
@ -589,7 +597,7 @@ BARS.defineActions(function() {
|
||||
palette[color] = tinycolor(color);
|
||||
})
|
||||
Painter.scanCanvas(ctx, 0, 0, canvas.width, canvas.height, (x, y, pixel) => {
|
||||
|
||||
if (!texture.selection.allow(x, y)) return;
|
||||
if (pixel[3] < 4) return;
|
||||
let smallest_distance = Infinity;
|
||||
let nearest_color = null;
|
||||
|
@ -198,9 +198,10 @@ const Painter = {
|
||||
face_matrices: {}
|
||||
}
|
||||
Painter.startPixel = [x, y];
|
||||
Painter.current.clear.width = texture.width;
|
||||
Painter.current.clear.height = texture.height;
|
||||
Painter.current.clear.getContext('2d').drawImage(texture.img, 0, 0);
|
||||
let {canvas} = texture.getActiveCanvas();
|
||||
Painter.current.clear.width = canvas.width;
|
||||
Painter.current.clear.height = canvas.height;
|
||||
Painter.current.clear.getContext('2d').drawImage(canvas, 0, 0);
|
||||
|
||||
} else {
|
||||
Painter.current.face_matrices = {};
|
||||
@ -843,9 +844,6 @@ const Painter = {
|
||||
|
||||
function drawShape(start_x, start_y, x, y, uvTag) {
|
||||
|
||||
var rect = Painter.setupRectFromFace(uvTag, texture);
|
||||
var [w, h] = [rect[2] - rect[0], rect[3] - rect[1]]
|
||||
|
||||
let diff_x = x - start_x;
|
||||
let diff_y = y - start_y;
|
||||
|
||||
@ -864,7 +862,16 @@ const Painter = {
|
||||
ctx.globalCompositeOperation = Painter.getBlendModeCompositeOperation();
|
||||
}
|
||||
|
||||
|
||||
if (shape === 'rectangle') {
|
||||
if (uvTag) {
|
||||
let rect = Painter.setupRectFromFace(uvTag, texture);
|
||||
let [w, h] = [rect[2] - rect[0], rect[3] - rect[1]];
|
||||
ctx.beginPath();
|
||||
ctx.rect(rect[0], rect[1], w, h);
|
||||
} else {
|
||||
texture.selection.maskCanvas(ctx);
|
||||
}
|
||||
ctx.strokeStyle = ctx.fillStyle = tinycolor(ColorPanel.get()).setAlpha(b_opacity).toRgbString();
|
||||
ctx.lineWidth = width;
|
||||
ctx.beginPath();
|
||||
@ -878,6 +885,8 @@ const Painter = {
|
||||
ctx.fill();
|
||||
}
|
||||
} else if (shape === 'ellipse') {
|
||||
let rect = Painter.setupRectFromFace(uvTag, texture);
|
||||
let [w, h] = [rect[2] - rect[0], rect[3] - rect[1]];
|
||||
Painter.modifyCanvasSection(ctx, rect[0], rect[1], w, h, (changePixel) => {
|
||||
//changePixel(0, 0, editPx)
|
||||
function editPx(pxcolor) {
|
||||
@ -1006,8 +1015,6 @@ const Painter = {
|
||||
}
|
||||
|
||||
function drawGradient(start_x, start_y, x, y, uvTag) {
|
||||
let rect = Painter.setupRectFromFace(uvTag, texture);
|
||||
var [w, h] = [rect[2] - rect[0], rect[3] - rect[1]];
|
||||
let diff_x = x - start_x;
|
||||
let diff_y = y - start_y;
|
||||
|
||||
@ -1044,10 +1051,20 @@ const Painter = {
|
||||
gradient.addColorStop(0, tinycolor(ColorPanel.get()).setAlpha(b_opacity).toRgbString());
|
||||
gradient.addColorStop(1, tinycolor(ColorPanel.get()).setAlpha(0).toRgbString());
|
||||
|
||||
ctx.beginPath();
|
||||
if (uvTag) {
|
||||
let rect = Painter.setupRectFromFace(uvTag, texture);
|
||||
let [w, h] = [rect[2] - rect[0], rect[3] - rect[1]];
|
||||
ctx.beginPath();
|
||||
ctx.rect(rect[0], rect[1], w, h);
|
||||
} else {
|
||||
texture.selection.maskCanvas(ctx);
|
||||
let rect = texture.selection.getBoundingRect(true);
|
||||
ctx.rect(rect.start_x, rect.start_y, rect.width, rect.height);
|
||||
console.log(rect)
|
||||
}
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.rect(rect[0], rect[1], w, h);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
return [diff_x, diff_y];
|
||||
}
|
||||
@ -1301,11 +1318,12 @@ const Painter = {
|
||||
a: data[3]/256
|
||||
})
|
||||
},
|
||||
modifyCanvasSection(ctx, x, y, w, h, cb) {
|
||||
modifyCanvasSection(ctx, x, y, w, h, cb, texture) {
|
||||
var arr = ctx.getImageData(x, y, w, h)
|
||||
var processed = [];
|
||||
|
||||
cb((px, py, editPx) => {
|
||||
if (UVEditor.texture && !UVEditor.texture.selection.allow(px, py)) {;return;}
|
||||
//changePixel
|
||||
px = Math.floor(px)-x;
|
||||
py = Math.floor(py)-y;
|
||||
@ -1699,16 +1717,16 @@ class IntMatrix {
|
||||
getDirect(x, y) {
|
||||
return this.array[y * this.width + x];
|
||||
}
|
||||
getBoundingRect() {
|
||||
getBoundingRect(respect_empty) {
|
||||
let rect = new Rectangle();
|
||||
if (this.override == true) {
|
||||
if (this.override == true || (respect_empty && this.override == false)) {
|
||||
rect.width = this.width;
|
||||
rect.height = this.height;
|
||||
} else if (this.override == null) {
|
||||
let min_x = Infinity;
|
||||
let min_y = Infinity;
|
||||
let max_x = -Infinity;
|
||||
let max_y = -Infinity;
|
||||
let min_x = this.width;
|
||||
let min_y = this.height;
|
||||
let max_x = 0;
|
||||
let max_y = 0;
|
||||
this.forEachPixel((x, y, value) => {
|
||||
if (!value) return;
|
||||
min_x = Math.min(min_x, x);
|
||||
@ -1716,7 +1734,13 @@ class IntMatrix {
|
||||
max_x = Math.max(max_x, x+1);
|
||||
max_y = Math.max(max_y, y+1);
|
||||
})
|
||||
rect.fromCoords(min_x, min_y, max_x, max_y);
|
||||
if (min_x == this.width) {
|
||||
// No pixel selected
|
||||
rect.width = this.width;
|
||||
rect.height = this.height;
|
||||
} else {
|
||||
rect.fromCoords(min_x, min_y, max_x, max_y);
|
||||
}
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
@ -1795,6 +1819,17 @@ class IntMatrix {
|
||||
})
|
||||
this.array = new_array;
|
||||
}
|
||||
maskCanvas(ctx) {
|
||||
if (!this.is_custom) return;
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
this.forEachPixel((x, y, value) => {
|
||||
if (!value) return;
|
||||
ctx.rect(x, y, 1, 1);
|
||||
});
|
||||
ctx.closePath();
|
||||
ctx.clip();
|
||||
}
|
||||
}
|
||||
|
||||
SharedActions.add('copy', {
|
||||
@ -2423,8 +2458,8 @@ BARS.defineActions(function() {
|
||||
options: {
|
||||
rectangle: {name: true, icon: 'fas.fa-square'},
|
||||
rectangle_h: {name: true, icon: 'far.fa-square'},
|
||||
ellipse: {name: true, icon: 'circle'},
|
||||
ellipse_h: {name: true, icon: 'radio_button_unchecked'},
|
||||
ellipse: {name: true, icon: 'fas.fa-circle'},
|
||||
ellipse_h: {name: true, icon: 'far.fa-circle'},
|
||||
}
|
||||
})
|
||||
new BarSelect('blend_mode', {
|
||||
|
@ -117,6 +117,7 @@ const UVEditor = {
|
||||
|
||||
selection_outline_lines: [],
|
||||
async updateSelectionOutline(recalculate_lines = true) {
|
||||
if (!Modes.paint) return;
|
||||
let {texture} = this.vue;
|
||||
if (!texture) {
|
||||
this.vue.selection_outline = '';
|
||||
@ -1442,9 +1443,9 @@ SharedActions.add('select_all', {
|
||||
}
|
||||
})
|
||||
SharedActions.add('select_all', {
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint && Texture.selected,
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint && UVEditor.texture,
|
||||
run() {
|
||||
Texture.selected.selection.setOverride(Texture.selected.selection.override == true ? false : true);
|
||||
UVEditor.texture.selection.setOverride(UVEditor.texture.selection.override == true ? false : true);
|
||||
UVEditor.updateSelectionOutline();
|
||||
}
|
||||
})
|
||||
@ -1456,16 +1457,16 @@ SharedActions.add('unselect_all', {
|
||||
}
|
||||
})
|
||||
SharedActions.add('unselect_all', {
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint,
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint && UVEditor.texture,
|
||||
run() {
|
||||
Texture.selected.selection.setOverride(false);
|
||||
UVEditor.texture.selection.setOverride(false);
|
||||
UVEditor.updateSelectionOutline();
|
||||
}
|
||||
})
|
||||
SharedActions.add('invert_selection', {
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint && Texture.selected,
|
||||
condition: () => Prop.active_panel == 'uv' && Modes.paint && UVEditor.texture,
|
||||
run() {
|
||||
let texture = Texture.selected;
|
||||
let texture = UVEditor.texture;
|
||||
if (texture.selection.is_custom) {
|
||||
texture.selection.forEachPixel((x, y, val, index) => {
|
||||
texture.selection.array[index] = val ? 0 : 1;
|
||||
@ -3856,7 +3857,7 @@ Interface.definePanels(function() {
|
||||
<div class="ellipse" v-if="texture_selection_rect.ellipse" />
|
||||
</div>
|
||||
|
||||
<svg id="uv_selection_outline">
|
||||
<svg id="uv_selection_outline" v-if="mode == 'paint'">
|
||||
<path :d="selection_outline" />
|
||||
<path :d="selection_outline" class="dash_overlay" />
|
||||
</svg>
|
||||
|
Loading…
Reference in New Issue
Block a user