Anchored Shapes are abstract shapes that have an associated anchor point. This anchor point along with Anchor Alignment property shown below determine where and how the shape is drawn. AnchoredShapes also have width, height and a flag to determine if these dimensions are in screen pixels or in parent node coordinates. The best example of an AnchoredShape is the Text object. The features of an AnchoredShape are more geared towards making this text object more powerful but easy to use. Other examples are Symbol and Images.
# Anchor Alignment
Anchors can be placed in any one of 9 places using the enum geotoolkit/util/AnchorType. These values include LeftTop, TopCenter, RightTop, LeftCenter, Center,RightCenter, LeftBottom, BottomCenter, RightBottom.
import { SquarePainter } from "@int/geotoolkit/scene/shapes/painters/SquarePainter.ts";
import { AlignmentStyle, BaseLineStyle, TextStyle } from "@int/geotoolkit/attributes/TextStyle.ts";
import { Text } from "@int/geotoolkit/scene/shapes/Text.ts";
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
function getAnchorShape(x, y) {
return new SymbolShape({
"ax": x,
"ay": y,
"width": 7,
"height": 7,
"painter": SquarePainter,
"fillstyle": "#D05B28"
});
}
function createScene(canvas) {
const textStyle = new TextStyle({
"color": KnownColors.DarkGray,
"alignment": AlignmentStyle.Left,
"font": "16px Arial",
"baseline": BaseLineStyle.Bottom
});
const text1 = new Text("Alignment", 75, 20, 175, 50, textStyle, false).setFillStyle("lightgray").setAnchorType(AnchorType.LeftTop);
const text2 = new Text("Alignment", 162.5, 125, 175, 50, textStyle, false).setFillStyle("lightgray").setAnchorType(AnchorType.Center);
const text3 = new Text("Alignment", 250, 230, 175, 50, textStyle, false).setFillStyle("lightgray").setAnchorType(AnchorType.RightBottom);
const group = new Group().addChild([
text1,
getAnchorShape(text1.getAnchorX(), text1.getAnchorY()),
text2,
getAnchorShape(text2.getAnchorX(), text2.getAnchorY()),
text3,
getAnchorShape(text3.getAnchorX(), text3.getAnchorY())
]);
return new Plot({
"canvaselement": canvas,
"root": group
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Preserve reading orientation
Preserve reading orientation will keep text from being mirrored left to right regardless of what transformations are applied to it.
import { initTextPreserved } from "/src/code/Carnac/Shapes/AnchoredShapes/initTextPreserved.ts";
function createScene(canvas) {
return initTextPreserved(canvas, (text, groupOriginal, groupPreserved) => {
text.setPreserveReadingOrientation(true);
groupOriginal.setHorizontalFlip(true);
groupPreserved.setHorizontalFlip(true);
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Always Points Up
Always points up will prevent text from being flipped vertically no matter what transforms are applied. Will not preserve reading orientation, so it's possible for text to be mirrored left or right.
import { initTextPreserved } from "/src/code/Carnac/Shapes/AnchoredShapes/initTextPreserved.ts";
function createScene(canvas) {
return initTextPreserved(canvas, (text, groupOriginal, groupPreserved) => {
text.setIsPointingUp(true);
groupOriginal.rotate(Math.PI, 150, 50);
groupPreserved.rotate(Math.PI, 150, 150);
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Preserve Right Angles
Preserve right angles will prevent text from being skewed in a way that will distort right angles. This helps keep text readable even as other transforms are applied.
import { initTextPreserved } from "/src/code/Carnac/Shapes/AnchoredShapes/initTextPreserved.ts";
function createScene(canvas) {
return initTextPreserved(canvas, (text, groupOriginal, groupPreserved) => {
text.setPreserveRightAngle(true);
groupOriginal.scale(0.9, 0.8).shear(1.1, 0.4);
groupPreserved.scale(0.9, 0.8).shear(1.1, 0.4);
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Size in Device Space
If "Size in device space" is set to true, then the text size passed into the text constructor will be in device space and unaffected by transforms.
import { initTextPreserved } from "/src/code/Carnac/Shapes/AnchoredShapes/initTextPreserved.ts";
function createScene(canvas) {
return initTextPreserved(canvas, (text, groupOriginal, groupPreserved) => {
text.setSizeIsInDeviceSpace(true);
groupOriginal.scale(0.3, 0.5);
groupPreserved.scale(0.3, 0.5);
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Preserve Aspect Ratio
Preserve right angles will prevent text from being skewed in a way that will distort right angles. Can keep text readable even as other transforms are applied.
import { initTextPreserved } from "/src/code/Carnac/Shapes/AnchoredShapes/initTextPreserved.ts";
function createScene(canvas) {
return initTextPreserved(canvas, (text, groupOriginal, groupPreserved) => {
text.setPreserveAspectRatio(true);
groupOriginal.setBounds(groupOriginal.getBounds().clone().setX(100).setY(200));
groupPreserved.setBounds(groupPreserved.getBounds().clone().setX(100).setY(400));
groupOriginal.scale(1, 0.3);
groupPreserved.scale(1, 0.3);
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Use Min Max Size
This is a hybrid of using device shape and model space, this allows us to set maximum and minimum device sizes for shapes, while allowing the shape to scale between those values.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { AnnotatedWidget } from "@int/geotoolkit/widgets/AnnotatedWidget.ts";
import { Image } from "@int/geotoolkit/scene/shapes/Image.ts";
import { Dimension } from "@int/geotoolkit/util/Dimension.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { Rectangle } from "@int/geotoolkit/scene/shapes/Rectangle.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import intImage from "/src/assets/images/slb-134x80.png?import";
function createScene(canvas) {
const image = new Image({
"x": 200,
"y": 200,
"w": 168,
"h": 70,
"alignment": AnchorType.Center,
"url": intImage,
"useminmaxdimensions": true,
"mindimension": new Dimension(85, 35),
"maxdimension": new Dimension(296, 123),
"fillstyle": "white"
});
const annotatedNode = new AnnotatedWidget({
"tools": {
"crosshair": {
"enabled": false
}
},
"border": null,
"model": new Group().setModelLimits(new Rect(0, 0, 400, 400)).addChild([
new Rectangle(100, 100, 300, 300).setFillStyle(KnownColors.LightBlue),
new Rectangle(200 - 168 / 2, 200 - 70 / 2, 200 + 168 / 2, 200 + 70 / 2).setFillStyle(KnownColors.Orange),
image
]),
"annotationssizes": {
"north": 0,
"south": 0,
"west": 0,
"east": 0
}
});
return new Plot({
"canvaselement": canvas,
"root": annotatedNode
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));