123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import { Path } from "konva/lib/shapes/Path";
- import { Rect } from "konva/lib/shapes/Rect";
- import { getRealAbsoluteSize } from "./shape-helper";
- import { Group } from "konva/lib/Group";
- import { KonvaEventObject } from "konva/lib/Node";
- export type SVGPaths = (
- | string
- | { fill?: string; stroke?: string; strokeWidth?: number; data: string }
- )[];
- const temp = document.createElement("div");
- export const analysisSvg = (
- svgString: string
- ): Pick<PathsToActShapeProps, "paths" | "size"> => {
- temp.innerHTML = svgString;
- const svg = temp.querySelector("svg");
- const size = [svg.width.baseVal.value, svg.height.baseVal.value];
- const paths = Array.from(svg.querySelectorAll("path"));
- const pathDatas = paths.map((path) => {
- const fill = path.getAttribute("fill");
- const data = path.getAttribute("d");
- const stroke = path.getAttribute("stroke");
- const strokeWidth = path.getAttribute("stroke-width");
- return {
- fill,
- data,
- stroke,
- strokeWidth: strokeWidth && Number(strokeWidth),
- };
- });
- return {
- paths: pathDatas,
- size,
- };
- };
- export type PathsToActShapeProps = {
- paths: SVGPaths;
- size: number[];
- realWidth?: number;
- offset?: number[];
- strokeWidth?: number;
- fixed?: boolean;
- strokeColor?: string;
- };
- export const pathsToActShape = (props: PathsToActShapeProps, test = false) => {
- const size = props.size;
- const realSize = props.realWidth || props.size[0];
- const scale = realSize / size[0];
- const realBound = size.map((p) => p * scale);
- const offset = (props.offset || [0, 0]).map((v) => v * scale);
- const strokeWidth = props.strokeWidth ? props.strokeWidth * scale : 1;
- const strokeColor = props.strokeColor || "#000";
- const pathAttribs = props.paths.map((path) => {
- if (typeof path === "string") {
- return {
- strokeWidth,
- stroke: strokeColor,
- fill: strokeColor,
- data: path,
- };
- } else {
- return path;
- }
- });
- const paths = pathAttribs.map(
- (path, ndx) =>
- new Path({
- data: path.data,
- id: `path-${ndx}`,
- name: `path`,
- strokeScaleEnabled: !!props.fixed,
- scale: { x: scale, y: scale },
- })
- );
- const common = () => {
- paths.forEach((path, ndx) => {
- const attrib = pathAttribs[ndx];
- attrib.fill && path.fill(attrib.fill);
- attrib.stroke && path.stroke(attrib.stroke);
- attrib.strokeWidth && path.strokeWidth(attrib.strokeWidth);
- });
- };
- const rect = new Rect({
- x: offset[0],
- y: offset[1],
- name: "rect",
- width: realBound[0],
- height: realBound[1],
- fill: `rgba(0, 0, 0, ${test ? 0.3 : 0})`,
- });
- const setStyle = () => {
- let [width, height] = getRealAbsoluteSize(group, [1, 1]);
- group.scale({ x: width, y: height });
- };
- const offsetGroup = new Group();
- offsetGroup.add(...paths, rect);
- offsetGroup.x(-realBound[0] / 2);
- offsetGroup.y(-realBound[1] / 2);
- const group = new Group();
- group.add(offsetGroup);
- return {
- getSize: () => {
- const size = rect.getSize();
- if (props.fixed) {
- let [scale] = getRealAbsoluteSize(group, [1, 1]);
- return [size.width * scale, size.height * scale];
- }
- return [size.width, size.height];
- },
- shape: group,
- setData(data) {
- group.position(data);
- props.fixed && setStyle();
- if (data.rotate) {
- group.rotation(data.rotate);
- }
- },
- common,
- };
- };
- export const getTouchOffset = (ev: KonvaEventObject<any>) => {
- const dom = ev.evt.target as HTMLElement;
- const rect = dom.getBoundingClientRect();
- const offsetX = ev.evt.changedTouches[0].pageX - rect.left;
- const offsetY = ev.evt.changedTouches[0].pageY - rect.top;
- return {
- offsetX,
- offsetY,
- };
- };
|