mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
distance marks and rounded rects
This commit is contained in:
parent
3f2e2ba856
commit
e532a43f2e
2 changed files with 102 additions and 12 deletions
|
@ -41,7 +41,7 @@ import { MODES } from '$constants/modes';
|
||||||
import { DEFAULT_USER } from '$constants/auth';
|
import { DEFAULT_USER } from '$constants/auth';
|
||||||
import { TIPS } from '$constants/tips';
|
import { TIPS } from '$constants/tips';
|
||||||
import {
|
import {
|
||||||
composeArrows,
|
composeArrows, composeDistMark,
|
||||||
composeImages,
|
composeImages,
|
||||||
composePoly, composeStickers, downloadCanvas,
|
composePoly, composeStickers, downloadCanvas,
|
||||||
fetchImages,
|
fetchImages,
|
||||||
|
@ -355,6 +355,8 @@ function* getRenderData() {
|
||||||
const geometry = getTilePlacement();
|
const geometry = getTilePlacement();
|
||||||
const points = getPolyPlacement();
|
const points = getPolyPlacement();
|
||||||
const stickers = getStickersPlacement();
|
const stickers = getStickersPlacement();
|
||||||
|
const distance = editor.poly.poly.distance;
|
||||||
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
const images = yield fetchImages(ctx, geometry);
|
const images = yield fetchImages(ctx, geometry);
|
||||||
|
@ -362,6 +364,7 @@ function* getRenderData() {
|
||||||
yield put(setRenderer({ info: 'Отрисовка', progress: 0.5 }));
|
yield put(setRenderer({ info: 'Отрисовка', progress: 0.5 }));
|
||||||
|
|
||||||
yield composeImages({ geometry, images, ctx });
|
yield composeImages({ geometry, images, ctx });
|
||||||
|
yield composeDistMark({ ctx, points, distance });
|
||||||
yield composePoly({ points, ctx });
|
yield composePoly({ points, ctx });
|
||||||
yield composeArrows({ points, ctx });
|
yield composeArrows({ points, ctx });
|
||||||
yield composeStickers({ stickers, ctx });
|
yield composeStickers({ stickers, ctx });
|
||||||
|
|
|
@ -229,6 +229,17 @@ const measureText = (
|
||||||
), { width: 0, height: 0 })
|
), { width: 0, height: 0 })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const measureDistText = (
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
text: string,
|
||||||
|
height: number
|
||||||
|
): { width: number, height: number } => (
|
||||||
|
{
|
||||||
|
width: ctx.measureText(text).width,
|
||||||
|
height,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const composeStickerArrow = (
|
const composeStickerArrow = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
x: number,
|
x: number,
|
||||||
|
@ -264,13 +275,58 @@ const measureRect = (
|
||||||
textX: reversed ? (x - width - 36) : x + 36
|
textX: reversed ? (x - width - 36) : x + 36
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const measureDistRect = (
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
reversed: boolean,
|
||||||
|
) => ({
|
||||||
|
rectX: reversed ? (x - width - 12) : x - 8,
|
||||||
|
rectY: (y - 4 - (height / 2)),
|
||||||
|
rectW: width + 16,
|
||||||
|
rectH: height + 4,
|
||||||
|
textX: reversed ? (x - width - 8) : x + 8
|
||||||
|
});
|
||||||
|
|
||||||
|
export const roundedRect = (ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, fill: string, rad: number = 5): void => {
|
||||||
|
ctx.fillStyle = fill;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, y + rad);
|
||||||
|
ctx.lineTo(x, y + height - rad);
|
||||||
|
|
||||||
|
ctx.lineTo(x + rad, y + height - rad);
|
||||||
|
ctx.lineTo(x + rad, y + height);
|
||||||
|
ctx.lineTo(x + width - rad, y + height);
|
||||||
|
ctx.lineTo(x + width - rad, y + height - rad);
|
||||||
|
ctx.lineTo(x + width, y + height - rad);
|
||||||
|
ctx.lineTo(x + width, y + rad);
|
||||||
|
ctx.lineTo(x + width - rad, y + rad);
|
||||||
|
ctx.lineTo(x + width - rad, y);
|
||||||
|
ctx.lineTo(x + rad, y);
|
||||||
|
ctx.lineTo(x + rad, y + rad);
|
||||||
|
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x + rad, y + rad, rad, 0, 360);
|
||||||
|
ctx.arc(x + width - rad, y + height - rad, rad, 0, 360);
|
||||||
|
ctx.arc(x + width - rad, y + rad, rad, 0, 360);
|
||||||
|
ctx.arc(x + rad, y + height - rad, rad, 0, 360);
|
||||||
|
ctx.closePath();
|
||||||
|
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
const composeStickerText = (
|
const composeStickerText = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
angle: number,
|
angle: number,
|
||||||
text: string,
|
text: string,
|
||||||
) => {
|
): void => {
|
||||||
const rad = 56;
|
const rad = 56;
|
||||||
const tX = ((Math.cos(angle + Math.PI) * rad) - 30) + x + 28;
|
const tX = ((Math.cos(angle + Math.PI) * rad) - 30) + x + 28;
|
||||||
const tY = ((Math.sin(angle + Math.PI) * rad) - 30) + y + 29;
|
const tY = ((Math.sin(angle + Math.PI) * rad) - 30) + y + 29;
|
||||||
|
@ -283,16 +339,17 @@ const composeStickerText = (
|
||||||
rectX, rectY, rectW, rectH, textX
|
rectX, rectY, rectW, rectH, textX
|
||||||
} = measureRect(tX, tY, width, height, (angle > -(Math.PI / 2) && angle < (Math.PI / 2)));
|
} = measureRect(tX, tY, width, height, (angle > -(Math.PI / 2) && angle < (Math.PI / 2)));
|
||||||
// rectangle
|
// rectangle
|
||||||
ctx.fillStyle = '#222222';
|
// ctx.fillStyle = '#222222';
|
||||||
ctx.beginPath();
|
// ctx.beginPath();
|
||||||
ctx.rect(
|
// ctx.rect(
|
||||||
rectX,
|
// rectX,
|
||||||
rectY,
|
// rectY,
|
||||||
rectW,
|
// rectW,
|
||||||
rectH,
|
// rectH,
|
||||||
);
|
// );
|
||||||
ctx.closePath();
|
// ctx.closePath();
|
||||||
ctx.fill();
|
// ctx.fill();
|
||||||
|
roundedRect(ctx, rectX, rectY, rectW, rectH, '#222222', 2);
|
||||||
|
|
||||||
// text
|
// text
|
||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
|
@ -305,6 +362,36 @@ const composeStickerText = (
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const composeDistMark = (
|
||||||
|
{ ctx, points, distance }:
|
||||||
|
{
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
points: Point[],
|
||||||
|
distance: number,
|
||||||
|
}
|
||||||
|
): void => {
|
||||||
|
if (points.length <= 1) return;
|
||||||
|
|
||||||
|
ctx.font = 'bold 12px "Helvetica Neue", Arial';
|
||||||
|
|
||||||
|
const angle = angleBetweenPoints(points[points.length - 2], points[points.length - 1]);
|
||||||
|
const dist = parseFloat(distance.toFixed(2));
|
||||||
|
const { x, y } = points[points.length - 1];
|
||||||
|
const { width, height } = measureDistText(ctx, String(dist), 16);
|
||||||
|
const {
|
||||||
|
rectX, rectY, rectW, rectH, textX
|
||||||
|
} = measureDistRect(x, y, width, height, !(angle > -90 && angle < 90));
|
||||||
|
|
||||||
|
roundedRect(ctx, rectX, rectY, rectW, rectH, '#ff3344', 2);
|
||||||
|
|
||||||
|
ctx.fillStyle = 'white';
|
||||||
|
ctx.fillText(
|
||||||
|
String(dist),
|
||||||
|
textX,
|
||||||
|
rectY + 14,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const composeStickerImage = async (
|
const composeStickerImage = async (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
x: number,
|
x: number,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue