I have to draw a sinus curve in a javafx canvas dot after dot and connect these. But as you can change the width of the line to it sometimes gets cut in width because the line is near the border. So is there a possibility to like make a padding or a border to avoid this? It would be possible to like manipulate the coordinates but tbh I dont want to do that as I think there should be a better solution. Picture of the canvas
EDIT:
This is the code example to reproduce it in a javafx project
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
Canvas c = new Canvas(715,495);
GraphicsContext gc = c.getGraphicsContext2D();
VBox v = new VBox();
Pane p = new Pane();
p.getChildren().add(c);
Button b1 = new Button("Draw Sinus at Canvas");
b1.setOnAction(e -> drawSinus(c, gc));
v.getChildren().addAll(b1, p);
Scene sc = new Scene(v);
stage.setScene(sc);
stage.setTitle("Drawing Lines - Dynamically at Runtime");
stage.show();
}
private void drawSinus(Canvas c, GraphicsContext gc) {
double height = c.getHeight();
double width = c.getWidth();
double multiplier = (2 * Math.PI)/width;
double x1 = 0;
double y1 = height/2;
double x2 = 1;
double y2 = 0;
int i = 0;
gc.setStroke(Color.BLACK);
gc.setLineWidth(10);
while(i < width) {
y2 = (height/2) - ((height/2) * Math.sin(x2 * multiplier));
gc.strokeLine(x1,y1,x2,y2);
x1 = x2;
y1 = y2;
x2 ;
i ;
}
}
public static void main(String[] args) {
launch();
}
}
CodePudding user response:
One way to add some padding around the area in which you're drawing, without changing the coordinates you use, is to add a transform to the graphics context. Basically, you first scale the drawing area to make it smaller by ratios (width-2*padding)/width
and (height-2*padding)/height
(so the actual drawing area is reduced by a size 2*padding
in each dimension). Then translate by padding
in each dimension. This looks like:
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
Canvas c = new Canvas(715,495);
GraphicsContext gc = c.getGraphicsContext2D();
VBox v = new VBox();
Pane p = new Pane();
p.getChildren().add(c);
Button b1 = new Button("Draw Sinus at Canvas");
b1.setOnAction(e -> drawSinus(c, gc, 10));
v.getChildren().addAll(b1, p);
Scene sc = new Scene(v);
stage.setScene(sc);
stage.setTitle("Drawing Lines - Dynamically at Runtime");
stage.show();
}
private void drawSinus(Canvas c, GraphicsContext gc, double padding) {
double height = c.getHeight();
double width = c.getWidth();
Affine transform = new Affine(Transform.scale((width-2*padding)/width, (height-2*padding)/height));
transform.appendTranslation(padding, padding);
gc.setTransform(transform);
double multiplier = (2 * Math.PI)/width;
double x1 = 0;
double y1 = height/2;
double x2 = 1;
double y2 = 0;
int i = 0;
gc.setStroke(Color.BLACK);
gc.setLineWidth(10);
while(i < width) {
y2 = (height/2) - ((height/2) * Math.sin(x2 * multiplier));
gc.strokeLine(x1,y1,x2,y2);
x1 = x2;
y1 = y2;
x2 ;
i ;
}
// reset transform; may not be necessary depending on actual use case
gc.setTransform(new Affine());
}
public static void main(String[] args) {
launch();
}
}
You need to reset the transform if you want to, e.g., clear the entire canvas, including the padded area.
CodePudding user response:
Place the canvas a StackPane
and set padding on the StackPane.
Canvas canvas = new Canvas(715,495);
StackPane stackPane = new StackPane(canvas);
stackPane.setPadding(new Insets(5));
Adjust canvas and padding sizes as needed for your requirements.