drawing arrows

This commit is contained in:
muerwre 2019-03-07 16:37:40 +07:00
parent f8d16d150a
commit 3f2e2ba856
7 changed files with 65 additions and 14 deletions

View file

@ -1,5 +1,8 @@
import { divIcon, LatLngLiteral, Marker, marker, DivIcon } from "leaflet";
const arrow_image = require('$sprites/arrow.svg');
// <use xlink:href="#path-arrow" transform="scale(2) translate(5 -2)"/>
export const createArrow = (latlng: LatLngLiteral, angle: number): Marker => marker(latlng, {
draggable: false,
interactive: false,
@ -7,7 +10,7 @@ export const createArrow = (latlng: LatLngLiteral, angle: number): Marker => mar
html: `
<div class="leaflet-arrow" style="transform: rotate(${angle}deg);">
<svg width="48" height="48" preserveAspectRatio="xMidYMid">
<use xlink:href="#path-arrow" transform="scale(2) translate(5 -2)"/>
<image xlink:href="${arrow_image}" x="0" y="0" width="48" height="48"/>
</svg>
</div>
`,

View file

@ -1,4 +1,4 @@
import { LatLng, LatLngLiteral, Point, PointExpression } from "leaflet";
import { LatLng, LatLngLiteral, point, Point, PointExpression } from "leaflet";
interface ILatLng {
lat: number,
@ -10,9 +10,18 @@ export const middleCoord = (l1: ILatLng, l2: ILatLng): ILatLng => ({
lng: (l2.lng + ((l1.lng - l2.lng) / 2))
});
export const middleCoordPx = (p1: Point, p2: Point): Point => point({
x: (p1.x + ((p2.x - p1.x) / 2)),
y: (p1.y + ((p2.y - p1.y) / 2))
});
export const deg2rad = (deg: number): number => ((deg * Math.PI) / 180);
export const rad2deg = (rad: number): number => ((rad / Math.PI) * 180);
export const findDistancePx = (p1: Point, p2: Point): number => {
return Math.sqrt(((p1.x - p2.x) ** 2) + ((p1.y - p2.y) ** 2));
};
export const findDistance = (t1: number, n1: number, t2: number, n2: number): number => {
// convert coordinates to radians
const lat1 = deg2rad(t1);

View file

@ -6,11 +6,8 @@ import { STICKERS } from '$constants/stickers';
import { ILatLng } from "$modules/Stickers";
import { IStickerDump } from "$modules/Sticker";
import { IRootState } from "$redux/user/reducer";
export interface IMapPoint {
x: number,
y: number,
}
import { angleBetweenPoints, angleBetweenPointsRad, findDistancePx, middleCoordPx } from "$utils/geom";
import { Point } from "leaflet";
export interface ITilePlacement {
minX: number,
@ -86,7 +83,7 @@ export const getTilePlacement = (): ITilePlacement => {
};
};
export const getPolyPlacement = (): IMapPoint[] => (
export const getPolyPlacement = (): Point[] => (
(!editor.poly.poly || !editor.poly.poly.getLatLngs() || editor.poly.poly.getLatLngs().length <= 0)
? []
: editor.poly.poly.getLatLngs().map((latlng) => ({ ...editor.map.map.latLngToContainerPoint(latlng) }))
@ -148,7 +145,7 @@ export const composeImages = (
});
};
export const composePoly = ({ points, ctx }: { points: IMapPoint[], ctx: CanvasRenderingContext2D }): void => {
export const composePoly = ({ points, ctx }: { points: Point[], ctx: CanvasRenderingContext2D }): void => {
if (editor.poly.isEmpty) return;
let minX = points[0].x;
@ -183,6 +180,42 @@ export const composePoly = ({ points, ctx }: { points: IMapPoint[], ctx: CanvasR
ctx.closePath();
};
export const composeArrows = async ({ points, ctx }: { points: Point[], ctx: CanvasRenderingContext2D }): Promise<boolean[]> => {
const image = await imageFetcher(require('$sprites/arrow.svg'));
const distances = points.map((point, i) => (
(points[i + 1] && findDistancePx(points[i], points[i + 1])) || 0
));
// we want to annotate at least 5 arrows
const min_arrows = (distances.length >= 5 ? 5 : distances.length - 1);
const min_distance = distances.sort((a, b) => (b - a))[min_arrows];
return points.map((point, i) => {
if (!points[i + 1]) return false;
const distance = findDistancePx(points[i], points[i + 1]);
const angle = angleBetweenPointsRad(points[i], points[i + 1]);
if (distance < min_distance && distance < 100) return false;
const middle = middleCoordPx(points[i], points[i + 1]);
ctx.save();
ctx.translate(middle.x, middle.y);
ctx.rotate((Math.PI * 0.5) - angle);
ctx.translate(-middle.x, -middle.y);
ctx.moveTo(middle.x, middle.y);
ctx.drawImage(image, middle.x - 24, middle.y - 24, 48, 48);
ctx.restore();
return true;
});
};
const measureText = (
ctx: CanvasRenderingContext2D,
text: string,