mirror of
https://github.com/aNNiMON/HotaruFX.git
synced 2024-09-19 14:14:21 +03:00
Add svg path node
This commit is contained in:
parent
5b68371d6a
commit
1c5adfe885
@ -7,6 +7,7 @@ import com.annimon.hotarufx.lib.Validator;
|
|||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
@ -17,6 +18,7 @@ public class NodesBundle implements Bundle {
|
|||||||
public void load(Context context) {
|
public void load(Context context) {
|
||||||
context.functions().put("circle", node(CircleNode::new));
|
context.functions().put("circle", node(CircleNode::new));
|
||||||
context.functions().put("rectangle", node(RectangleNode::new));
|
context.functions().put("rectangle", node(RectangleNode::new));
|
||||||
|
context.functions().put("svgPath", node(SVGPathNode::new));
|
||||||
context.functions().put("text", node(TextNode::new));
|
context.functions().put("text", node(TextNode::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.annimon.hotarufx.visual.objects;
|
||||||
|
|
||||||
|
import com.annimon.hotarufx.visual.PropertyBindings;
|
||||||
|
import com.annimon.hotarufx.visual.PropertyTimeline;
|
||||||
|
import com.annimon.hotarufx.visual.PropertyTimelineHolder;
|
||||||
|
import com.annimon.hotarufx.visual.TimeLine;
|
||||||
|
import com.annimon.hotarufx.visual.visitors.NodeVisitor;
|
||||||
|
import javafx.scene.shape.SVGPath;
|
||||||
|
import static com.annimon.hotarufx.visual.PropertyType.STRING;
|
||||||
|
|
||||||
|
public class SVGPathNode extends ShapeNode {
|
||||||
|
|
||||||
|
public final SVGPath svgPath;
|
||||||
|
|
||||||
|
private PropertyTimelineHolder<String> content;
|
||||||
|
|
||||||
|
public SVGPathNode() {
|
||||||
|
this(new SVGPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SVGPathNode(SVGPath svgPath) {
|
||||||
|
super(svgPath);
|
||||||
|
this.svgPath = svgPath;
|
||||||
|
content = PropertyTimelineHolder.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyTimeline<String> contentProperty() {
|
||||||
|
return content.setIfEmptyThenGet(svgPath::contentProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildTimeline(TimeLine timeline) {
|
||||||
|
super.buildTimeline(timeline);
|
||||||
|
content.applyIfPresent(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyBindings propertyBindings(PropertyBindings bindings) {
|
||||||
|
return super.propertyBindings(bindings)
|
||||||
|
.add("content", STRING, this::contentProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, T> R accept(NodeVisitor<R, T> visitor, T input) {
|
||||||
|
return visitor.visit(this, input);
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,13 @@ package com.annimon.hotarufx.visual.visitors;
|
|||||||
|
|
||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
|
|
||||||
public interface NodeVisitor<R, T> {
|
public interface NodeVisitor<R, T> {
|
||||||
|
|
||||||
R visit(CircleNode node, T input);
|
R visit(CircleNode node, T input);
|
||||||
R visit(RectangleNode node, T input);
|
R visit(RectangleNode node, T input);
|
||||||
|
R visit(SVGPathNode node, T input);
|
||||||
R visit(TextNode node, T input);
|
R visit(TextNode node, T input);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import com.annimon.hotarufx.visual.VirtualScene;
|
|||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@ -23,6 +24,11 @@ public class RenderVisitor implements NodeVisitor<Void, VirtualScene> {
|
|||||||
return render(node, scene);
|
return render(node, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(SVGPathNode node, VirtualScene scene) {
|
||||||
|
return render(node, scene);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(TextNode node, VirtualScene scene) {
|
public Void visit(TextNode node, VirtualScene scene) {
|
||||||
return render(node, scene);
|
return render(node, scene);
|
||||||
|
@ -61,4 +61,14 @@ C@scaleY
|
|||||||
.add(100, 1)
|
.add(100, 1)
|
||||||
.add(120, 1.8)
|
.add(120, 1.8)
|
||||||
|
|
||||||
render(B, A, C, CLIP)
|
HEART = svgPath({
|
||||||
|
layoutX: -15,
|
||||||
|
layoutY: -12,
|
||||||
|
content: "M23.6,0c-3.4,0-6.3,2.7-7.6,5.6C14.7,2.7,11.8,0,8.4,0C3.8,0,0,3.8,0,8.4c0,9.4,9.5,11.9,16,21.2
|
||||||
|
6.1-9.3,16-12.1,16-21.2C32,3.8,28.2,0,23.6,0z",
|
||||||
|
fill: "red",
|
||||||
|
strokeWidth: 2,
|
||||||
|
stroke: "white"
|
||||||
|
})
|
||||||
|
|
||||||
|
render(B, A, C, CLIP, HEART)
|
Loading…
Reference in New Issue
Block a user