В настоящее время у меня есть холст, на котором я сначала нарисую изображение, прежде чем появятся все остальные функции рисования мышью холста (для рисования прямоугольников).У меня также есть функция отмены, которая удаляет последний нарисованный блок, очищает весь холст и перерисовывает все оставшиеся блоки обратно на холст.Однако после удаления изображение каким-то образом появится поверх полей и покрывает их, а не внизу, как должно быть.Я мог исправить это с помощью z-index в HTML5 ранее, но не знаю, как это сделать, используя способ Java.
Это мой Canvas.java (метод отмены ближе к концу):
package com.vaadin.starter.beveragebuddy.ui.components;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.dom.Element;
import com.vaadin.flow.dom.ElementFactory;
import com.vaadin.flow.shared.Registration;
import com.vaadin.starter.beveragebuddy.backend.MainLayout;
import elemental.json.JsonObject;
import java.util.ArrayList;
import java.util.List;
/**
* Canvas component that you can draw shapes and images on. It's a Java wrapper
* for the
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">HTML5
* canvas</a>.
* <p>
* Use {@link #getContext()} to get API for rendering shapes and images on the
* canvas.
* <p>
*/
@Tag("canvas")
@SuppressWarnings("serial")
public class Canvas extends Component implements HasStyle, HasSize {
private static CanvasRenderingContext2D context;
private Element element;
private boolean mouseSelect = false;
private boolean mouseIsDown = false;
private double endX;
private double endY;
public static int boxCount = 0;
public static boolean undoCalled = false;
public static ArrayList <BoundingBox> arrayBoxes = new ArrayList<BoundingBox>();
public static ArrayList <MousePosition> mousePosArray = new ArrayList<MousePosition>();
public static ArrayList <SelectBox> selectBoxes = new ArrayList<SelectBox>();
private List<Runnable> mouseMoveListeners = new ArrayList<>(0);
public static ArrayList<BoundingBox> getArrayBoxes() {
return arrayBoxes;
}
public static ArrayList<MousePosition> getMousePosArray() {
return mousePosArray;
}
public static void setMousePosArray(ArrayList<MousePosition> mousePosArray) {
Canvas.mousePosArray = mousePosArray;
}
/**
* Creates a new canvas component with the given size.
* <p>
* Use the API provided by {@link #getContext()} to render graphics on the
* canvas.
* <p>
* The width and height parameters will be used for the canvas' coordinate
* system. They will determine the size of the component in pixels, unless
* you explicitly set the component's size with {@link #setWidth(String)} or
* {@link #setHeight(String)}.
*
// * @param width
// * the width of the canvas
// * @param height
// * the height of the canvas
// */
public Registration addMouseMoveListener(Runnable listener) {
mouseMoveListeners.add(listener);
return () -> mouseMoveListeners.remove(listener);
}
public Canvas(int width, int height) {
context = new CanvasRenderingContext2D(this);
context.drawImage("https://freedesignfile.com/upload/2016/10/Red-Clouds-and-Prairie-Background.jpg", 0, 0);
element = getElement();
element.getStyle().set("border", "1px solid");
getElement().setAttribute("width", String.valueOf(width));
getElement().setAttribute("height", String.valueOf(height));
element.addEventListener("mousedown", event -> { // Retrieve Starting Position on MouseDown
Element boundingBoxResult = ElementFactory.createDiv();
element.appendChild(boundingBoxResult);
JsonObject evtData = event.getEventData();
double xBox = evtData.getNumber("event.x");
double yBox = evtData.getNumber("event.y");
boundingBoxResult.setAttribute("data-x", String.format("%f", xBox));
boundingBoxResult.setAttribute("data-y", String.format("%f", yBox));
BoundingBox newBox = new BoundingBox("","", xBox, yBox, 0.0, 0.0);
arrayBoxes.add(newBox);
SelectBox select = new SelectBox(xBox, 0.0, yBox, 0.0);
selectBoxes.add(0, select);
mouseIsDown=true;
mouseMoveListeners.forEach(Runnable::run);
}).addEventData("event.x").addEventData("event.y");
element.addEventListener("mouseup", event -> { // Draw Box on MouseUp
Element boundingBoxResult2 = ElementFactory.createDiv();
element.appendChild(boundingBoxResult2);
JsonObject evtData2 = event.getEventData();
endX = evtData2.getNumber("event.x");
endY = evtData2.getNumber("event.y");
boundingBoxResult2.setAttribute("end-x", String.format("%f", endX));
boundingBoxResult2.setAttribute("end-y", String.format("%f", endY));
// System.out.println(endX);
// System.out.println(endY);
double xcoordi = 0;
double ycoordi = 0;
double boxWidth = 0;
double boxHeight = 0;
// for (int i = 0; i < arrayBoxes.size(); i++) {
System.out.println(endX);
System.out.println(endY);
arrayBoxes.get(boxCount).setWidth(endX, arrayBoxes.get(boxCount).xcoordi);
arrayBoxes.get(boxCount).setHeight(endY, arrayBoxes.get(boxCount).ycoordi);
xcoordi = arrayBoxes.get(boxCount).getXcoordi();
ycoordi = arrayBoxes.get(boxCount).getYcoordi();
boxWidth = arrayBoxes.get(boxCount).getWidth();
boxHeight = arrayBoxes.get(boxCount).getHeight();
boxCount++;
mouseIsDown=false;
context.beginPath();
context.setStrokeStyle("green");
context.setLineWidth(2);
context.strokeRect(xcoordi, ycoordi, boxWidth, boxHeight);
context.stroke();
context.fill();
SelectBox select = new SelectBox(endX, 0.0, endY, 0.0);
selectBoxes.add(1, select);
// if (selectBoxes.get(1).getSelectEndX() == selectBoxes.get(0).getSelectStartX()){
// mouseSelect = true;
// context.beginPath();
// context.setStrokeStyle("yellow");
// context.setLineWidth(2);
// context.strokeRect(arrayBoxes.get(i).xcoordi, arrayBoxes.get(i).ycoordi, arrayBoxes.get(i).boxWidth, arrayBoxes.get(i).boxHeight);
// context.fill();
// }
System.out.println(arrayBoxes.toString());
//
// for (int i = 0; i < arrayBoxes.size(); i++){
// if(arrayBoxes.get(i).xcoordi)
// if (endX > arrayBoxes.get(i).xcoordi){
// if (endX < arrayBoxes.get(i).endY)
// }
// }
mouseMoveListeners.forEach(Runnable::run);
}).addEventData("event.x").addEventData("event.y");
element.addEventListener("mousemove", event -> { // Retrieve Mouse Position when Moving
JsonObject mousePos = event.getEventData();
double mouseX = mousePos.getNumber("event.x");
double mouseY = mousePos.getNumber("event.y");
MousePosition currentPos = new MousePosition(mouseX, mouseY);
mousePosArray.add(0, currentPos);
setMousePosArray(mousePosArray);
mouseMoveListeners.forEach(Runnable::run);
}).addEventData("event.x").addEventData("event.y");
}
public static void undoLast() {
undoCalled = true;
if (arrayBoxes.size() > 0) {
arrayBoxes.remove(arrayBoxes.size() - 1);
}
System.out.println(arrayBoxes.toString());
System.out.println(arrayBoxes.size());
context.clearRect(0, 0, 1580, 700);
context.drawImage("https://freedesignfile.com/upload/2016/10/Red-Clouds-and-Prairie-Background.jpg", 0, 0);
for (int i = 0; i < arrayBoxes.size(); i++){
context.beginPath();
context.setStrokeStyle("green");
context.setLineWidth(2);
context.strokeRect(arrayBoxes.get(i).xcoordi, arrayBoxes.get(i).ycoordi, arrayBoxes.get(i).boxWidth, arrayBoxes.get(i).boxHeight);
context.fill();
}
boxCount--;
System.out.println("Box Count: " + boxCount);
}
/**
* Gets the context for rendering shapes and images in the canvas.
* <p>
* It is a Java wrapper for the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">same
* client-side API</a>.
*
* @return the 2D rendering context of this canvas
*/
public CanvasRenderingContext2D getContext() {
return context;
}
/**
* {@inheritDoc}
* <p>
* <b>NOTE:</b> Canvas has an internal coordinate system that it uses for
* drawing, and it uses the width and height provided in the constructor.
* This coordinate system is independent of the component's size. Changing
* the component's size with this method may scale/stretch the rendered
* graphics.
*/
@Override
public void setWidth(String width) {
HasSize.super.setWidth(width);
}
/**
* {@inheritDoc}
* <p>
* <b>NOTE:</b> Canvas has an internal coordinate system that it uses for
* drawing, and it uses the width and height provided in the constructor.
* This coordinate system is independent of the component's size. Changing
* the component's size with this method may scale/stretch the rendered
* graphics.
*/
@Override
public void setHeight(String height) {
HasSize.super.setHeight(height);
}
/**
* {@inheritDoc}
* <p>
* <b>NOTE:</b> Canvas has an internal coordinate system that it uses for
* drawing, and it uses the width and height provided in the constructor.
* This coordinate system is independent of the component's size. Changing
* the component's size with this method may scale/stretch the rendered
* graphics.
*/
@Override
public void setSizeFull() {
HasSize.super.setSizeFull();
}
public void addComponent(Label label) {
}
}
Любая помощь очень ценится, спасибо!