增加组件的旋转
This commit is contained in:
@@ -12,6 +12,7 @@ public abstract class DrawableObject implements Serializable {
|
||||
protected double height;
|
||||
protected String id;
|
||||
protected boolean selected;
|
||||
protected double rotation = 0;
|
||||
|
||||
public DrawableObject(double x, double y, double width, double height) {
|
||||
this.x = x;
|
||||
@@ -70,6 +71,14 @@ public abstract class DrawableObject implements Serializable {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
public double getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public void setRotation(double rotation) {
|
||||
this.rotation = (rotation % 360 + 360) % 360;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查点是否在对象内
|
||||
*/
|
||||
|
||||
@@ -274,6 +274,19 @@ public class DrawingCanvas extends Pane {
|
||||
* 绘制单个对象
|
||||
*/
|
||||
private void drawObject(GraphicsContext gc, DrawableObject obj, boolean selected) {
|
||||
// 保存当前状态
|
||||
gc.save();
|
||||
|
||||
// 计算旋转中心(对象中心)
|
||||
double centerX = obj.getX() + obj.getWidth() / 2;
|
||||
double centerY = obj.getY() + obj.getHeight() / 2;
|
||||
|
||||
// 应用旋转
|
||||
gc.translate(centerX, centerY);
|
||||
gc.rotate(obj.getRotation());
|
||||
gc.translate(-centerX, -centerY);
|
||||
|
||||
// 绘制具体对象
|
||||
if (obj instanceof TextObject) {
|
||||
drawTextObject(gc, (TextObject) obj, selected);
|
||||
} else if (obj instanceof ShapeObject) {
|
||||
@@ -281,6 +294,9 @@ public class DrawingCanvas extends Pane {
|
||||
} else if (obj instanceof ImageObject) {
|
||||
drawImageObject(gc, (ImageObject) obj, selected);
|
||||
}
|
||||
|
||||
// 恢复状态
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
package dev.bytevibe.hyperpoint;
|
||||
|
||||
import com.google.gson.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* JSON序列化工具,用于将演示文稿保存和加载为JSON格式
|
||||
@@ -180,6 +186,7 @@ public class JsonSerializationUtil {
|
||||
ImageObject imgObj = (ImageObject) obj;
|
||||
objJson.addProperty("imagePath", imgObj.getImagePath());
|
||||
}
|
||||
objJson.addProperty("rotation", obj.getRotation()); // 添加旋转角度
|
||||
|
||||
return objJson;
|
||||
}
|
||||
@@ -238,6 +245,11 @@ public class JsonSerializationUtil {
|
||||
obj = new ImageObject(x, y, width, height, imagePath);
|
||||
}
|
||||
|
||||
// 读取旋转角度并设置
|
||||
if (objJson.has("rotation")) {
|
||||
obj.setRotation(objJson.get("rotation").getAsDouble());
|
||||
}
|
||||
|
||||
if (obj != null) {
|
||||
obj.setId(id);
|
||||
}
|
||||
|
||||
@@ -584,6 +584,15 @@ public class PresentationWindow {
|
||||
* 绘制单个对象
|
||||
*/
|
||||
private void drawObject(GraphicsContext gc, DrawableObject obj) {
|
||||
gc.save();
|
||||
|
||||
double centerX = obj.getX() + obj.getWidth() / 2;
|
||||
double centerY = obj.getY() + obj.getHeight() / 2;
|
||||
|
||||
gc.translate(centerX, centerY);
|
||||
gc.rotate(obj.getRotation());
|
||||
gc.translate(-centerX, -centerY);
|
||||
|
||||
if (obj instanceof TextObject) {
|
||||
drawTextObject(gc, (TextObject) obj);
|
||||
} else if (obj instanceof ShapeObject) {
|
||||
@@ -591,6 +600,8 @@ public class PresentationWindow {
|
||||
} else if (obj instanceof ImageObject) {
|
||||
drawImageObject(gc, (ImageObject) obj);
|
||||
}
|
||||
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
package dev.bytevibe.hyperpoint;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ColorPicker;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* 属性编辑面板,用于编辑选中对象的属性
|
||||
* 使用FXML加载UI布局
|
||||
@@ -38,6 +44,10 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
private Spinner<Double> strokeWidthSpinner;
|
||||
@FXML
|
||||
private Button deleteButton;
|
||||
@FXML
|
||||
private Slider rotationSlider;
|
||||
@FXML
|
||||
private Label rotationValueLabel;
|
||||
|
||||
private DrawingCanvas canvas;
|
||||
|
||||
@@ -80,6 +90,20 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
"BOLD_ITALIC"
|
||||
);
|
||||
|
||||
// 初始化旋转控制
|
||||
rotationSlider.setMin(0);
|
||||
rotationSlider.setMax(360);
|
||||
rotationSlider.setValue(0);
|
||||
rotationSlider.setMajorTickUnit(15);
|
||||
rotationSlider.setMajorTickUnit(90);
|
||||
rotationSlider.setShowTickMarks(true);
|
||||
rotationSlider.setShowTickLabels(true);
|
||||
|
||||
rotationSlider.valueProperty().addListener((obs, oldVal, newVal) -> {
|
||||
updateRotation();
|
||||
rotationValueLabel.setText(String.format("%.0f°", newVal));
|
||||
});
|
||||
|
||||
// 设置默认值
|
||||
fontFamilyCombo.setValue("Arial");
|
||||
fontStyleCombo.setValue("NORMAL");
|
||||
@@ -112,6 +136,7 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
DrawableObject selected = canvas.getSelectedObject();
|
||||
if (selected == null) {
|
||||
setEditingVisible(false);
|
||||
rotationSlider.setDisable(true);
|
||||
objectTypeLabel.setText("未选中对象");
|
||||
return;
|
||||
}
|
||||
@@ -142,15 +167,31 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
showImageControls();
|
||||
}
|
||||
|
||||
rotationSlider.setValue(selected.getRotation());
|
||||
rotationSlider.setDisable(false);
|
||||
rotationValueLabel.setText(String.format("%.0f°", selected.getRotation()));
|
||||
|
||||
// 重新添加监听
|
||||
textContentField.setOnKeyReleased(e -> updateTextContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新旋转
|
||||
*/
|
||||
private void updateRotation() {
|
||||
DrawableObject selected = canvas.getSelectedObject();
|
||||
if (selected != null) {
|
||||
selected.setRotation(rotationSlider.getValue());
|
||||
canvas.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示文本控件
|
||||
*/
|
||||
private void showTextControls() {
|
||||
textContentField.setDisable(false);
|
||||
rotationSlider.setDisable(false);
|
||||
fontFamilyCombo.setDisable(false);
|
||||
fontSizeSpinner.setDisable(false);
|
||||
fontStyleCombo.setDisable(false);
|
||||
@@ -167,6 +208,7 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
*/
|
||||
private void showShapeControls() {
|
||||
textContentField.setDisable(true);
|
||||
rotationSlider.setDisable(false);
|
||||
fontFamilyCombo.setDisable(true);
|
||||
fontSizeSpinner.setDisable(true);
|
||||
fontStyleCombo.setDisable(true);
|
||||
@@ -183,6 +225,7 @@ public class PropertyPanel extends VBox implements Initializable {
|
||||
*/
|
||||
private void showImageControls() {
|
||||
textContentField.setDisable(true);
|
||||
rotationSlider.setDisable(false);
|
||||
fontFamilyCombo.setDisable(true);
|
||||
fontSizeSpinner.setDisable(true);
|
||||
fontStyleCombo.setDisable(true);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ColorPicker?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
@@ -23,6 +24,11 @@
|
||||
|
||||
<Separator/>
|
||||
|
||||
<!-- 旋转角度 -->
|
||||
<Slider fx:id="rotationSlider" max="360.0" min="0.0" />
|
||||
<Label text="旋转角度:" />
|
||||
<Label fx:id="rotationValueLabel" text="0°" />
|
||||
|
||||
<!-- 文本内容 -->
|
||||
<Label text="文本内容:"/>
|
||||
<TextField fx:id="textContentField"/>
|
||||
|
||||
Reference in New Issue
Block a user