Add STriangle
This commit is contained in:
8
out.html
Normal file
8
out.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<!DOCTYPE html><html lang="fr"><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="style.css" /> <title>Reactive shapes HTML</title></head><body>
|
||||||
|
<div class="triangle110717522"></div>
|
||||||
|
<div id="rec209793789"></div>
|
||||||
|
<div id="rec365617083"></div>
|
||||||
|
<div id="rec1121327988"></div>
|
||||||
|
<div id="rec256914054"></div>
|
||||||
|
<div class="circle172224331"></div>
|
||||||
|
</body>
|
||||||
10
out.svg
Normal file
10
out.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="600">
|
||||||
|
|
||||||
|
<polygon points="200,250 225,200 250,250" style="fill:#ffff00;stroke:#000000;stroke-width:1" />
|
||||||
|
<rect width="40" height="60" x="10" y="10" stroke="#ff0000" stroke-width="1" fill="none" />
|
||||||
|
<rect width="40" height="60" x="70" y="10" stroke="#000000" stroke-width="1" fill="none" />
|
||||||
|
<rect width="40" height="60" x="100" y="200" stroke="#ff00ff" stroke-width="1" fill="none" />
|
||||||
|
<rect width="40" height="60" x="150" y="200" stroke="#ff00ff" stroke-width="1" fill="none" />
|
||||||
|
<circle cx="230" cy="280" r="30" stroke="#000000" stroke-width="1" fill="none" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 682 B |
@@ -3,9 +3,7 @@ package ovh.gasser.newshapes;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||||
import ovh.gasser.newshapes.shapes.SCircle;
|
import ovh.gasser.newshapes.shapes.*;
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
|
||||||
import ovh.gasser.newshapes.shapes.Shape;
|
import ovh.gasser.newshapes.shapes.Shape;
|
||||||
import ovh.gasser.newshapes.ui.ShapesView;
|
import ovh.gasser.newshapes.ui.ShapesView;
|
||||||
import ovh.gasser.newshapes.ui.listeners.MenuAddListener;
|
import ovh.gasser.newshapes.ui.listeners.MenuAddListener;
|
||||||
@@ -51,6 +49,7 @@ public class App {
|
|||||||
|
|
||||||
private void buildModel() {
|
private void buildModel() {
|
||||||
model = SCollection.of(
|
model = SCollection.of(
|
||||||
|
STriangle.create(200, 200, 50, Color.YELLOW, Color.BLACK),
|
||||||
SRectangle.create(10, 10, 40, 60, Color.RED),
|
SRectangle.create(10, 10, 40, 60, Color.RED),
|
||||||
SRectangle.create(70, 10, 40, 60),
|
SRectangle.create(70, 10, 40, 60),
|
||||||
SCollection.of(
|
SCollection.of(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ovh.gasser.newshapes;
|
|||||||
import ovh.gasser.newshapes.shapes.SCircle;
|
import ovh.gasser.newshapes.shapes.SCircle;
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
import ovh.gasser.newshapes.shapes.SCollection;
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
import ovh.gasser.newshapes.shapes.SRectangle;
|
||||||
|
import ovh.gasser.newshapes.shapes.STriangle;
|
||||||
|
|
||||||
public interface ShapeVisitor {
|
public interface ShapeVisitor {
|
||||||
void visitRectangle(SRectangle sRectangle);
|
void visitRectangle(SRectangle sRectangle);
|
||||||
@@ -10,4 +11,6 @@ public interface ShapeVisitor {
|
|||||||
void visitCollection(SCollection collection);
|
void visitCollection(SCollection collection);
|
||||||
|
|
||||||
void visitCircle(SCircle sCircle);
|
void visitCircle(SCircle sCircle);
|
||||||
|
|
||||||
|
void visitTriangle(STriangle sTriangle);
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/main/java/ovh/gasser/newshapes/shapes/STriangle.java
Normal file
31
src/main/java/ovh/gasser/newshapes/shapes/STriangle.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package ovh.gasser.newshapes.shapes;
|
||||||
|
|
||||||
|
import ovh.gasser.newshapes.ShapeVisitor;
|
||||||
|
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||||
|
import ovh.gasser.newshapes.attributes.SelectionAttributes;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class STriangle extends AbstractShape {
|
||||||
|
private STriangle(int x, int y, int size){
|
||||||
|
super(new Rectangle(x, y, size, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ShapeVisitor visitor) {
|
||||||
|
visitor.visitTriangle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Shape clone() {
|
||||||
|
var color = (ColorAttributes) getAttributes(ColorAttributes.ID);
|
||||||
|
return STriangle.create(super.getBounds().x, super.getBounds().y, super.getBounds().height, color.strokedColor, color.filledColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static STriangle create(int x, int y, int size, Color filledColor, Color strokedColor) {
|
||||||
|
var tri = new STriangle(x, y, size);
|
||||||
|
tri.addAttributes(new SelectionAttributes());
|
||||||
|
tri.addAttributes(new ColorAttributes(true, true, filledColor, strokedColor));
|
||||||
|
return tri;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,7 @@ package ovh.gasser.newshapes.ui;
|
|||||||
import ovh.gasser.newshapes.ShapeVisitor;
|
import ovh.gasser.newshapes.ShapeVisitor;
|
||||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||||
import ovh.gasser.newshapes.attributes.SelectionAttributes;
|
import ovh.gasser.newshapes.attributes.SelectionAttributes;
|
||||||
import ovh.gasser.newshapes.shapes.SCircle;
|
import ovh.gasser.newshapes.shapes.*;
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
|
||||||
import ovh.gasser.newshapes.shapes.Shape;
|
import ovh.gasser.newshapes.shapes.Shape;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -64,6 +62,32 @@ public class ShapeDraftman implements ShapeVisitor {
|
|||||||
drawHandlerIfSelected(circle);
|
drawHandlerIfSelected(circle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTriangle(STriangle tri) {
|
||||||
|
ColorAttributes colAttrs = (ColorAttributes) tri.getAttributes(ColorAttributes.ID);
|
||||||
|
var bounds = tri.getBounds();
|
||||||
|
var size = Math.min(bounds.width, bounds.height); // Should be the same because we only support equilateral triangles
|
||||||
|
if (colAttrs == null){
|
||||||
|
colAttrs = DEFAULT_COLOR_ATTRIBUTES;
|
||||||
|
}
|
||||||
|
if (colAttrs.filled) {
|
||||||
|
this.g2d.setColor(colAttrs.filledColor);
|
||||||
|
this.g2d.fillPolygon(
|
||||||
|
new int[]{ bounds.x, bounds.x + (size/2), bounds.x + size },
|
||||||
|
new int[]{ bounds.y + size, bounds.y, bounds.y + size },
|
||||||
|
3);
|
||||||
|
}
|
||||||
|
if (colAttrs.stroked) {
|
||||||
|
this.g2d.setColor(colAttrs.strokedColor);
|
||||||
|
this.g2d.drawPolygon(
|
||||||
|
new int[]{bounds.x, bounds.x + (size / 2), bounds.x + size},
|
||||||
|
new int[]{bounds.y + size, bounds.y, bounds.y + size},
|
||||||
|
3);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawHandlerIfSelected(tri);
|
||||||
|
}
|
||||||
|
|
||||||
private void drawHandlerIfSelected(Shape s) {
|
private void drawHandlerIfSelected(Shape s) {
|
||||||
SelectionAttributes selAttrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID);
|
SelectionAttributes selAttrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID);
|
||||||
if ((selAttrs != null) && (selAttrs.selected)){
|
if ((selAttrs != null) && (selAttrs.selected)){
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ package ovh.gasser.newshapes.ui.visitors;
|
|||||||
|
|
||||||
import ovh.gasser.newshapes.ShapeVisitor;
|
import ovh.gasser.newshapes.ShapeVisitor;
|
||||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||||
import ovh.gasser.newshapes.shapes.SCircle;
|
import ovh.gasser.newshapes.shapes.*;
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
|
||||||
import ovh.gasser.newshapes.shapes.Shape;
|
import ovh.gasser.newshapes.shapes.Shape;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HTMLDraftman implements ShapeVisitor {
|
public class HTMLDraftman implements ShapeVisitor {
|
||||||
|
|
||||||
@@ -50,19 +52,39 @@ public class HTMLDraftman implements ShapeVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitCircle(SCircle circle) {
|
public void visitCircle(SCircle circle) {
|
||||||
htmlOutput.println("<div class=\"circle"+circle.hashCode()+"\"></div>");
|
htmlOutput.printf("<div class=\"circle%d\"></div>\n", circle.hashCode());
|
||||||
cssOutput.println(".circle" + circle.hashCode() + "{ ");
|
cssOutput.println(" .circle" + circle.hashCode() + "{\n");
|
||||||
cssOutput.println("position: absolute;");
|
cssOutput.println(" position: absolute;");
|
||||||
cssOutput.println("top:" + circle.getBounds().y + "px;");
|
cssOutput.println(" top:" + circle.getBounds().y + "px;");
|
||||||
cssOutput.println("left:" + circle.getBounds().x + "px;");
|
cssOutput.println(" left:" + circle.getBounds().x + "px;");
|
||||||
cssOutput.println("width:" + circle.getRadius() + "px;");
|
cssOutput.println(" width:" + circle.getRadius() + "px;");
|
||||||
cssOutput.println("height:" + circle.getRadius() + "px;");
|
cssOutput.println(" height:" + circle.getRadius() + "px;");
|
||||||
cssOutput.println("border-radius:" + circle.getRadius() / 2 + "px;");
|
cssOutput.println(" border-radius:" + circle.getRadius() / 2 + "px;");
|
||||||
cssOutput.println("-webkit-border-radius:" + circle.getRadius() / 2 + "px;");
|
cssOutput.println(" -webkit-border-radius:" + circle.getRadius() / 2 + "px;");
|
||||||
cssOutput.println("-o-border-radius:" + circle.getRadius() / 2 + "px;");
|
cssOutput.println(" -o-border-radius:" + circle.getRadius() / 2 + "px;");
|
||||||
cssOutput.println("-moz-border-radius:" + circle.getRadius() / 2 + "px;");
|
cssOutput.println(" -moz-border-radius:" + circle.getRadius() / 2 + "px;");
|
||||||
cssOutput.println("position: absolute;");
|
cssOutput.println(" position: absolute;");
|
||||||
cssOutput.println(this.attributesToCss(circle) + " }");
|
cssOutput.println(this.attributesToCss(circle) + "\n}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTriangle(STriangle sTriangle) {
|
||||||
|
htmlOutput.printf("<div class=\"triangle%d\"></div>\n", this.hashCode());
|
||||||
|
var bounds = sTriangle.getBounds();
|
||||||
|
ColorAttributes colAttrs = (ColorAttributes) sTriangle.getAttributes(ColorAttributes.ID);
|
||||||
|
String colorString = formatCSSColor(colAttrs.filledColor);
|
||||||
|
StringJoiner joiner = new StringJoiner("\n", ".triangle%d{\n".formatted(this.hashCode()), "\n}\n");
|
||||||
|
joiner.add(" position: absolute;");
|
||||||
|
joiner.add(" top: %dpx;".formatted(bounds.y));
|
||||||
|
joiner.add(" left: %dpx;".formatted(bounds.x));
|
||||||
|
joiner.add(" width: 0px;");
|
||||||
|
joiner.add(" height: 0px;");
|
||||||
|
joiner.add(" border: 0 solid transparent;");
|
||||||
|
joiner.add(" border-left-width: %spx;".formatted(Math.ceil(bounds.width / 1.72)));
|
||||||
|
joiner.add(" border-right-width: %spx;".formatted(Math.ceil(bounds.width / 1.72)));
|
||||||
|
joiner.add(" border-bottom: %dpx solid %s;".formatted(bounds.width, colorString));
|
||||||
|
String strBuilder = joiner.toString();
|
||||||
|
cssOutput.write(strBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String attributesToCss(Shape shape) {
|
private String attributesToCss(Shape shape) {
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import ovh.gasser.newshapes.attributes.ColorAttributes;
|
|||||||
import ovh.gasser.newshapes.shapes.SCircle;
|
import ovh.gasser.newshapes.shapes.SCircle;
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
import ovh.gasser.newshapes.shapes.SCollection;
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
import ovh.gasser.newshapes.shapes.SRectangle;
|
||||||
|
import ovh.gasser.newshapes.shapes.STriangle;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
public class SVGDraftman implements ShapeVisitor {
|
public class SVGDraftman implements ShapeVisitor {
|
||||||
private static final String SVG_PRELUDE = """
|
private static final String SVG_PRELUDE = """
|
||||||
@@ -51,6 +53,24 @@ public class SVGDraftman implements ShapeVisitor {
|
|||||||
x, y, r, buildColorParameters(attrs)));
|
x, y, r, buildColorParameters(attrs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTriangle(STriangle sTriangle) {
|
||||||
|
int x = sTriangle.getBounds().x;
|
||||||
|
int y = sTriangle.getBounds().y;
|
||||||
|
int size = sTriangle.getBounds().width;
|
||||||
|
var points = new StringJoiner(" ", "", "");
|
||||||
|
points.add("%d,%d".formatted(x, y + size));
|
||||||
|
points.add("%d,%d".formatted(x + size / 2, y));
|
||||||
|
points.add("%d,%d".formatted(x + size, y + size));
|
||||||
|
var attrs = (ColorAttributes) sTriangle.getAttributes(ColorAttributes.ID);
|
||||||
|
var style = new StringJoiner(";", "fill:", "");
|
||||||
|
style.add(attrs.filled ? colorToHex(attrs.filledColor) : "none");
|
||||||
|
if (attrs.stroked) {
|
||||||
|
style.add("stroke:%s;stroke-width:1".formatted(colorToHex(attrs.strokedColor)));
|
||||||
|
}
|
||||||
|
this.output.printf("<polygon points=\"%s\" style=\"%s\" />\n", points, style);
|
||||||
|
}
|
||||||
|
|
||||||
public void generateSVG(SCollection model) {
|
public void generateSVG(SCollection model) {
|
||||||
output.println(String.format(SVG_PRELUDE, App.WIN_SIZE.width, App.WIN_SIZE.height));
|
output.println(String.format(SVG_PRELUDE, App.WIN_SIZE.width, App.WIN_SIZE.height));
|
||||||
visitCollection(model);
|
visitCollection(model);
|
||||||
|
|||||||
54
style.css
Normal file
54
style.css
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
.triangle110717522{
|
||||||
|
position: absolute;
|
||||||
|
top: 162px;
|
||||||
|
left: 367px;
|
||||||
|
width: 0px;
|
||||||
|
height: 0px;
|
||||||
|
border: 0 solid transparent;
|
||||||
|
border-left-width: 30.0px;
|
||||||
|
border-right-width: 30.0px;
|
||||||
|
border-bottom: 50px solid #ffff00;
|
||||||
|
}
|
||||||
|
#rec209793789{
|
||||||
|
position:absolute;
|
||||||
|
top:10px;
|
||||||
|
left:10px;
|
||||||
|
width:40px;
|
||||||
|
height:60px;
|
||||||
|
background:#ffffff;border:1px solid #ff0000; }
|
||||||
|
#rec365617083{
|
||||||
|
position:absolute;
|
||||||
|
top:10px;
|
||||||
|
left:70px;
|
||||||
|
width:40px;
|
||||||
|
height:60px;
|
||||||
|
background:#ffffff;border:1px solid #000000; }
|
||||||
|
#rec1121327988{
|
||||||
|
position:absolute;
|
||||||
|
top:200px;
|
||||||
|
left:100px;
|
||||||
|
width:40px;
|
||||||
|
height:60px;
|
||||||
|
background:#ffffff;border:1px solid #ff00ff; }
|
||||||
|
#rec256914054{
|
||||||
|
position:absolute;
|
||||||
|
top:200px;
|
||||||
|
left:150px;
|
||||||
|
width:40px;
|
||||||
|
height:60px;
|
||||||
|
background:#ffffff;border:1px solid #ff00ff; }
|
||||||
|
.circle172224331{
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top:250px;
|
||||||
|
left:200px;
|
||||||
|
width:30px;
|
||||||
|
height:30px;
|
||||||
|
border-radius:15px;
|
||||||
|
-webkit-border-radius:15px;
|
||||||
|
-o-border-radius:15px;
|
||||||
|
-moz-border-radius:15px;
|
||||||
|
position: absolute;
|
||||||
|
background:#ffffff;border:1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user