1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
import { computed } from "mobx";
import { observer } from "mobx-react";
import { documentSchema } from "../../new_fields/documentSchemas";
import { InkData, InkField, InkTool } from "../../new_fields/InkField";
import { makeInterface } from "../../new_fields/Schema";
import { Cast } from "../../new_fields/Types";
import { DocExtendableComponent } from "./DocComponent";
import { InkingControl } from "./InkingControl";
import "./InkingStroke.scss";
import { FieldView, FieldViewProps } from "./nodes/FieldView";
import React = require("react");
type InkDocument = makeInterface<[typeof documentSchema]>;
const InkDocument = makeInterface(documentSchema);
export function CreatePolyline(points: { x: number, y: number }[], left: number, top: number, color?: string, width?: number) {
const pts = points.reduce((acc: string, pt: { x: number, y: number }) => acc + `${pt.x - left},${pt.y - top} `, "");
return (
<polyline
points={pts}
style={{
fill: "none",
stroke: color ?? InkingControl.Instance.selectedColor,
strokeWidth: width ?? InkingControl.Instance.selectedWidth
}}
/>
);
}
@observer
export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocument>(InkDocument) {
public static LayoutString(fieldStr: string) { return FieldView.LayoutString(InkingStroke, fieldStr); }
@computed get PanelWidth() { return this.props.PanelWidth(); }
@computed get PanelHeight() { return this.props.PanelHeight(); }
render() {
const data: InkData = Cast(this.Document.data, InkField)?.inkData ?? [];
const xs = data.map(p => p.x);
const ys = data.map(p => p.y);
const left = Math.min(...xs);
const top = Math.min(...ys);
const right = Math.max(...xs);
const bottom = Math.max(...ys);
const points = CreatePolyline(data, 0, 0, this.Document.color, this.Document.strokeWidth);
const width = right - left;
const height = bottom - top;
const scaleX = this.PanelWidth / width;
const scaleY = this.PanelHeight / height;
return (
<svg width={width} height={height} style={{
transformOrigin: "top left",
transform: `translate(${left}px, ${top}px) scale(${scaleX}, ${scaleY})`,
mixBlendMode: this.Document.tool === InkTool.Highlighter ? "multiply" : "unset",
pointerEvents: "all"
}} onTouchStart={this.onTouchStart}>
{points}
</svg>
);
}
}
|