import { Bezier } from "bezier-js"; import { createSimpleSchema, list, object, serializable } from "serializr"; import { ScriptingGlobals } from "../client/util/ScriptingGlobals"; import { Deserializable } from "../client/util/SerializationHelper"; import { Copy, ToScriptString, ToString } from "./FieldSymbols"; import { ObjectField } from "./ObjectField"; // Helps keep track of the current ink tool in use. export enum InkTool { None = "none", Pen = "pen", Highlighter = "highlighter", Eraser = "eraser", Stamp = "stamp", Write = "write", PresentationPin = 'presentationpin' } // Defines a point in an ink as a pair of x- and y-coordinates. export interface PointData { X: number; Y: number; } export type Segment = Array; // Defines an ink as an array of points. export type InkData = Array; export interface ControlPoint { X: number; Y: number; I: number; } export interface HandlePoint { X: number; Y: number; I: number; dot1: number; dot2: number; } export interface HandleLine { X1: number; Y1: number; X2: number; Y2: number; X3: number; Y3: number; dot1: number; dot2: number; } const pointSchema = createSimpleSchema({ X: true, Y: true }); const strokeDataSchema = createSimpleSchema({ pathData: list(object(pointSchema)), "*": true }); @Deserializable("ink") export class InkField extends ObjectField { @serializable(list(object(strokeDataSchema))) readonly inkData: InkData; constructor(data: InkData) { super(); this.inkData = data; } /** * Extacts a simple segment from a compound Bezier curve * @param segIndex the start index of the simple bezier segment to extact (eg., 0, 4, 8, ...) */ public static Segment(inkData: InkData, segIndex: number) { return new Bezier(inkData.slice(segIndex, segIndex + 4).map(pt => ({ x: pt.X, y: pt.Y }))); } [Copy]() { return new InkField(this.inkData); } [ToScriptString]() { return "new InkField([" + this.inkData.map(i => `{X: ${i.X}, Y: ${i.Y}`) + "])"; } [ToString]() { return "InkField"; } } ScriptingGlobals.add("InkField", InkField);