distance marks and rounded rects

This commit is contained in:
muerwre 2019-03-07 17:21:38 +07:00
parent 3f2e2ba856
commit e532a43f2e
2 changed files with 102 additions and 12 deletions

View file

@ -41,7 +41,7 @@ import { MODES } from '$constants/modes';
import { DEFAULT_USER } from '$constants/auth';
import { TIPS } from '$constants/tips';
import {
composeArrows,
composeArrows, composeDistMark,
composeImages,
composePoly, composeStickers, downloadCanvas,
fetchImages,
@ -355,6 +355,8 @@ function* getRenderData() {
const geometry = getTilePlacement();
const points = getPolyPlacement();
const stickers = getStickersPlacement();
const distance = editor.poly.poly.distance;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const images = yield fetchImages(ctx, geometry);
@ -362,6 +364,7 @@ function* getRenderData() {
yield put(setRenderer({ info: 'Отрисовка', progress: 0.5 }));
yield composeImages({ geometry, images, ctx });
yield composeDistMark({ ctx, points, distance });
yield composePoly({ points, ctx });
yield composeArrows({ points, ctx });
yield composeStickers({ stickers, ctx });

View file

@ -229,6 +229,17 @@ const measureText = (
), { width: 0, height: 0 })
);
const measureDistText = (
ctx: CanvasRenderingContext2D,
text: string,
height: number
): { width: number, height: number } => (
{
width: ctx.measureText(text).width,
height,
}
);
const composeStickerArrow = (
ctx: CanvasRenderingContext2D,
x: number,
@ -264,13 +275,58 @@ const measureRect = (
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 = (
ctx: CanvasRenderingContext2D,
x: number,
y: number,
angle: number,
text: string,
) => {
): void => {
const rad = 56;
const tX = ((Math.cos(angle + Math.PI) * rad) - 30) + x + 28;
const tY = ((Math.sin(angle + Math.PI) * rad) - 30) + y + 29;
@ -283,16 +339,17 @@ const composeStickerText = (
rectX, rectY, rectW, rectH, textX
} = measureRect(tX, tY, width, height, (angle > -(Math.PI / 2) && angle < (Math.PI / 2)));
// rectangle
ctx.fillStyle = '#222222';
ctx.beginPath();
ctx.rect(
rectX,
rectY,
rectW,
rectH,
);
ctx.closePath();
ctx.fill();
// ctx.fillStyle = '#222222';
// ctx.beginPath();
// ctx.rect(
// rectX,
// rectY,
// rectW,
// rectH,
// );
// ctx.closePath();
// ctx.fill();
roundedRect(ctx, rectX, rectY, rectW, rectH, '#222222', 2);
// text
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 (
ctx: CanvasRenderingContext2D,
x: number,