@fluid-experimental/ink 2.12.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs CHANGED
@@ -4,10 +4,7 @@
4
4
  */
5
5
 
6
6
  module.exports = {
7
- extends: [
8
- require.resolve("@fluidframework/eslint-config-fluid/minimal-deprecated"),
9
- "prettier",
10
- ],
7
+ extends: [require.resolve("@fluidframework/eslint-config-fluid/recommended"), "prettier"],
11
8
  parserOptions: {
12
9
  project: ["./tsconfig.json", "./src/test/tsconfig.json"],
13
10
  },
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @fluid-experimental/ink
2
2
 
3
+ ## 2.20.0
4
+
5
+ Dependency updates only.
6
+
7
+ ## 2.13.0
8
+
9
+ Dependency updates only.
10
+
3
11
  ## 2.12.0
4
12
 
5
13
  Dependency updates only.
package/dist/ink.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EACN,gBAAgB,EAChB,YAAY,EAEZ,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAGN,IAAI,EACJ,UAAU,EAEV,SAAS,EACT,UAAU,EACV,IAAI,EAEJ,MAAM,iBAAiB,CAAC;AAQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,qBAAa,GAAI,SAAQ,YAAY,CAAC,UAAU,CAAE,YAAW,IAAI;IAChE;;;;;OAKG;WACW,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM;IAIjE;;;OAGG;WACW,UAAU;IAIxB;;OAEG;IACH,OAAO,CAAC,OAAO,CAA0B;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB;IAIvF;;OAEG;IACI,YAAY,CAAC,GAAG,EAAE,IAAI,GAAG,UAAU;IAW1C;;OAEG;IACI,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAUpE;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACI,UAAU,IAAI,UAAU,EAAE;IAIjC;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU;IAIzC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,qBAAqB;IAK5E;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,SAAS,CAAC,WAAW,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,GACtB,IAAI;IAuBP;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IAWpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAU9B,SAAS,CAAC,cAAc,IAAI,IAAI;CAGhC"}
1
+ {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EACN,gBAAgB,EAChB,YAAY,EAEZ,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAGN,IAAI,EACJ,UAAU,EAEV,SAAS,EACT,UAAU,EACV,IAAI,EAEJ,MAAM,iBAAiB,CAAC;AAQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,qBAAa,GAAI,SAAQ,YAAY,CAAC,UAAU,CAAE,YAAW,IAAI;IAChE;;;;;OAKG;WACW,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG;IAIvE;;;OAGG;WACW,UAAU,IAAI,UAAU;IAItC;;OAEG;IACH,OAAO,CAAC,OAAO,CAA0B;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB;IAIvF;;OAEG;IACI,YAAY,CAAC,GAAG,EAAE,IAAI,GAAG,UAAU;IAW1C;;OAEG;IACI,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAUpE;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACI,UAAU,IAAI,UAAU,EAAE;IAIjC;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU;IAIzC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,qBAAqB;IAK5E;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,SAAS,CAAC,WAAW,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,GACtB,IAAI;IAuBP;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IAWpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAU9B,SAAS,CAAC,cAAc,IAAI,IAAI;CAGhC"}
package/dist/ink.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ink.js","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tIFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { ISerializableInk, InkData } from \"./snapshot.js\";\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = \"header\";\n\n/**\n * `Ink` is a shared object which holds a collection of ink strokes.\n *\n * @remarks\n * ### Creation and setup\n *\n * To create an `Ink` object, call the static `create` method:\n *\n * ```typescript\n * const ink = Ink.create(this.runtime, id);\n * ```\n *\n * You'll also need an `IPen` that will describe the style of your stroke:\n *\n * ```typescript\n * this.currentPen = {\n * color: { r: 0, g: 161 / 255, b: 241 / 255, a: 0 },\n * thickness: 7,\n * };\n * ```\n *\n * ### Usage\n *\n * Once the `Ink` object is created, you can add and update ink strokes using `createStroke` and\n * `appendPointToStroke`. Most likely you'll want to do this in response to incoming Pointer Events:\n *\n * ```typescript\n * private handlePointerDown(e: PointerEvent) {\n * const newStroke = ink.createStroke(this.currentPen);\n * this.currentStrokeId = newStroke.id;\n * handlePointerMotion(e);\n * }\n *\n * private handlePointerMotion(e: PointerEvent) {\n * const inkPoint = {\n * x: e.clientX,\n * y: e.clientY,\n * time: Date.now(),\n * pressure: e.pressure,\n * };\n * ink.appendPointToStroke(inkPoint, this.currentStrokeId);\n * }\n *\n * canvas.addEventListener(\"pointerdown\", this.handlePointerDown);\n * canvas.addEventListener(\"pointermove\", this.handlePointerMotion);\n * canvas.addEventListener(\"pointerup\", this.handlePointerMotion);\n * ```\n *\n * You can also clear all the ink with `clear`:\n *\n * ```typescript\n * ink.clear();\n * ```\n *\n * To observe and react to changes to the ink from both your own modifications as well as remote participants,\n * you can listen to the `\"createStroke\"`, `\"stylus\"` and `\"clear\"` events. Since you don't need to render anything\n * yet when a stroke is first created, registering for `\"createStroke\"` may not be necessary.\n *\n * ```typescript\n * ink.on(\"stylus\", this.renderStylusUpdate.bind(this));\n * ink.on(\"clear\", this.renderClear.bind(this));\n * ```\n * @sealed\n * @internal\n */\nexport class Ink extends SharedObject<IInkEvents> implements IInk {\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - Data Store runtime the new Ink belongs to\n\t * @param id - Optional name of the Ink; will be assigned a unique ID if not provided\n\t * @returns Newly create Ink object (but not attached yet)\n\t */\n\tpublic static create(runtime: IFluidDataStoreRuntime, id?: string) {\n\t\treturn runtime.createChannel(id, InkFactory.Type) as Ink;\n\t}\n\n\t/**\n\t * Get a factory for Ink to register with the data store.\n\t * @returns A factory that creates and loads Ink\n\t */\n\tpublic static getFactory() {\n\t\treturn new InkFactory();\n\t}\n\n\t/**\n\t * The current ink snapshot.\n\t */\n\tprivate inkData: InkData = new InkData();\n\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - The runtime the Ink will be associated with\n\t * @param id - Unique ID for the Ink\n\t */\n\tconstructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes) {\n\t\tsuper(id, runtime, attributes, \"fluid_ink_\");\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.createStroke}\n\t */\n\tpublic createStroke(pen: IPen): IInkStroke {\n\t\tconst createStrokeOperation: ICreateStrokeOperation = {\n\t\t\tid: uuid(),\n\t\t\tpen,\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"createStroke\",\n\t\t};\n\t\tthis.submitLocalMessage(createStrokeOperation, undefined);\n\t\treturn this.executeCreateStrokeOperation(createStrokeOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.appendPointToStroke}\n\t */\n\tpublic appendPointToStroke(point: IInkPoint, id: string): IInkStroke {\n\t\tconst stylusOperation: IStylusOperation = {\n\t\t\tid,\n\t\t\tpoint,\n\t\t\ttype: \"stylus\",\n\t\t};\n\t\tthis.submitLocalMessage(stylusOperation, undefined);\n\t\treturn this.executeStylusOperation(stylusOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.clear}\n\t */\n\tpublic clear(): void {\n\t\tconst clearOperation: IClearOperation = {\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitLocalMessage(clearOperation, undefined);\n\t\tthis.executeClearOperation(clearOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.inkData.getStrokes();\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.inkData.getStroke(key);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst blobContent = JSON.stringify(this.inkData.getSerializable());\n\t\treturn createSingleBlobSummary(snapshotFileName, blobContent);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst content = await readAndParse<ISerializableInk>(storage, snapshotFileName);\n\t\tthis.inkData = new InkData(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tif (message.type === MessageType.Operation && !local) {\n\t\t\tconst operation = message.contents as IInkOperation;\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase \"clear\": {\n\t\t\t\t\tthis.executeClearOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"createStroke\": {\n\t\t\t\t\tthis.executeCreateStrokeOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"stylus\": {\n\t\t\t\t\tthis.executeStylusOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\treturn;\n\t}\n\n\t/**\n\t * Update the model for a clear operation.\n\t * @param operation - The operation object\n\t */\n\tprivate executeClearOperation(operation: IClearOperation): void {\n\t\tthis.inkData.clear();\n\t\tthis.emit(\"clear\", operation);\n\t}\n\n\t/**\n\t * Update the model for a create stroke operation.\n\t * @param operation - The operation object\n\t * @returns The stroke that was created\n\t */\n\tprivate executeCreateStrokeOperation(operation: ICreateStrokeOperation): IInkStroke {\n\t\tconst stroke: IInkStroke = {\n\t\t\tid: operation.id,\n\t\t\tpoints: [],\n\t\t\tpen: operation.pen,\n\t\t};\n\t\tthis.inkData.addStroke(stroke);\n\t\tthis.emit(\"createStroke\", operation);\n\t\treturn stroke;\n\t}\n\n\t/**\n\t * Update the model for a stylus operation. These represent updates to an existing stroke.\n\t * @param operation - The operation object\n\t * @returns The stroke that was updated\n\t */\n\tprivate executeStylusOperation(operation: IStylusOperation): IInkStroke {\n\t\t// Need to make sure the stroke is still there (hasn't been cleared) before appending the down/move/up.\n\t\tconst stroke = this.getStroke(operation.id);\n\t\tif (stroke !== undefined) {\n\t\t\tstroke.points.push(operation.point);\n\t\t\tthis.emit(\"stylus\", operation);\n\t\t}\n\t\treturn stroke;\n\t}\n\n\tprotected applyStashedOp(): void {\n\t\tthrow new Error(\"not implemented\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"ink.js","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tIFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { ISerializableInk, InkData } from \"./snapshot.js\";\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = \"header\";\n\n/**\n * `Ink` is a shared object which holds a collection of ink strokes.\n *\n * @remarks\n * ### Creation and setup\n *\n * To create an `Ink` object, call the static `create` method:\n *\n * ```typescript\n * const ink = Ink.create(this.runtime, id);\n * ```\n *\n * You'll also need an `IPen` that will describe the style of your stroke:\n *\n * ```typescript\n * this.currentPen = {\n * color: { r: 0, g: 161 / 255, b: 241 / 255, a: 0 },\n * thickness: 7,\n * };\n * ```\n *\n * ### Usage\n *\n * Once the `Ink` object is created, you can add and update ink strokes using `createStroke` and\n * `appendPointToStroke`. Most likely you'll want to do this in response to incoming Pointer Events:\n *\n * ```typescript\n * private handlePointerDown(e: PointerEvent) {\n * const newStroke = ink.createStroke(this.currentPen);\n * this.currentStrokeId = newStroke.id;\n * handlePointerMotion(e);\n * }\n *\n * private handlePointerMotion(e: PointerEvent) {\n * const inkPoint = {\n * x: e.clientX,\n * y: e.clientY,\n * time: Date.now(),\n * pressure: e.pressure,\n * };\n * ink.appendPointToStroke(inkPoint, this.currentStrokeId);\n * }\n *\n * canvas.addEventListener(\"pointerdown\", this.handlePointerDown);\n * canvas.addEventListener(\"pointermove\", this.handlePointerMotion);\n * canvas.addEventListener(\"pointerup\", this.handlePointerMotion);\n * ```\n *\n * You can also clear all the ink with `clear`:\n *\n * ```typescript\n * ink.clear();\n * ```\n *\n * To observe and react to changes to the ink from both your own modifications as well as remote participants,\n * you can listen to the `\"createStroke\"`, `\"stylus\"` and `\"clear\"` events. Since you don't need to render anything\n * yet when a stroke is first created, registering for `\"createStroke\"` may not be necessary.\n *\n * ```typescript\n * ink.on(\"stylus\", this.renderStylusUpdate.bind(this));\n * ink.on(\"clear\", this.renderClear.bind(this));\n * ```\n * @sealed\n * @internal\n */\nexport class Ink extends SharedObject<IInkEvents> implements IInk {\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - Data Store runtime the new Ink belongs to\n\t * @param id - Optional name of the Ink; will be assigned a unique ID if not provided\n\t * @returns Newly create Ink object (but not attached yet)\n\t */\n\tpublic static create(runtime: IFluidDataStoreRuntime, id?: string): Ink {\n\t\treturn runtime.createChannel(id, InkFactory.Type) as Ink;\n\t}\n\n\t/**\n\t * Get a factory for Ink to register with the data store.\n\t * @returns A factory that creates and loads Ink\n\t */\n\tpublic static getFactory(): InkFactory {\n\t\treturn new InkFactory();\n\t}\n\n\t/**\n\t * The current ink snapshot.\n\t */\n\tprivate inkData: InkData = new InkData();\n\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - The runtime the Ink will be associated with\n\t * @param id - Unique ID for the Ink\n\t */\n\tconstructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes) {\n\t\tsuper(id, runtime, attributes, \"fluid_ink_\");\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.createStroke}\n\t */\n\tpublic createStroke(pen: IPen): IInkStroke {\n\t\tconst createStrokeOperation: ICreateStrokeOperation = {\n\t\t\tid: uuid(),\n\t\t\tpen,\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"createStroke\",\n\t\t};\n\t\tthis.submitLocalMessage(createStrokeOperation, undefined);\n\t\treturn this.executeCreateStrokeOperation(createStrokeOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.appendPointToStroke}\n\t */\n\tpublic appendPointToStroke(point: IInkPoint, id: string): IInkStroke {\n\t\tconst stylusOperation: IStylusOperation = {\n\t\t\tid,\n\t\t\tpoint,\n\t\t\ttype: \"stylus\",\n\t\t};\n\t\tthis.submitLocalMessage(stylusOperation, undefined);\n\t\treturn this.executeStylusOperation(stylusOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.clear}\n\t */\n\tpublic clear(): void {\n\t\tconst clearOperation: IClearOperation = {\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitLocalMessage(clearOperation, undefined);\n\t\tthis.executeClearOperation(clearOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.inkData.getStrokes();\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.inkData.getStroke(key);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst blobContent = JSON.stringify(this.inkData.getSerializable());\n\t\treturn createSingleBlobSummary(snapshotFileName, blobContent);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst content = await readAndParse<ISerializableInk>(storage, snapshotFileName);\n\t\tthis.inkData = new InkData(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tif (message.type === MessageType.Operation && !local) {\n\t\t\tconst operation = message.contents as IInkOperation;\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase \"clear\": {\n\t\t\t\t\tthis.executeClearOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"createStroke\": {\n\t\t\t\t\tthis.executeCreateStrokeOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"stylus\": {\n\t\t\t\t\tthis.executeStylusOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\treturn;\n\t}\n\n\t/**\n\t * Update the model for a clear operation.\n\t * @param operation - The operation object\n\t */\n\tprivate executeClearOperation(operation: IClearOperation): void {\n\t\tthis.inkData.clear();\n\t\tthis.emit(\"clear\", operation);\n\t}\n\n\t/**\n\t * Update the model for a create stroke operation.\n\t * @param operation - The operation object\n\t * @returns The stroke that was created\n\t */\n\tprivate executeCreateStrokeOperation(operation: ICreateStrokeOperation): IInkStroke {\n\t\tconst stroke: IInkStroke = {\n\t\t\tid: operation.id,\n\t\t\tpoints: [],\n\t\t\tpen: operation.pen,\n\t\t};\n\t\tthis.inkData.addStroke(stroke);\n\t\tthis.emit(\"createStroke\", operation);\n\t\treturn stroke;\n\t}\n\n\t/**\n\t * Update the model for a stylus operation. These represent updates to an existing stroke.\n\t * @param operation - The operation object\n\t * @returns The stroke that was updated\n\t */\n\tprivate executeStylusOperation(operation: IStylusOperation): IInkStroke {\n\t\t// Need to make sure the stroke is still there (hasn't been cleared) before appending the down/move/up.\n\t\tconst stroke = this.getStroke(operation.id);\n\t\tif (stroke !== undefined) {\n\t\t\tstroke.points.push(operation.point);\n\t\t\tthis.emit(\"stylus\", operation);\n\t\t}\n\t\treturn stroke;\n\t}\n\n\tprotected applyStashedOp(): void {\n\t\tthrow new Error(\"not implemented\");\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inkCanvas.d.ts","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAiD,MAAM,iBAAiB,CAAC;AAyG9F;;GAEG;AACH,qBAAa,SAAS;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IANvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAkC;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;gBAGhB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,IAAI;IAwBtB,WAAW,CAAC,KAAK,EAAE,MAAM;IAIzB,MAAM;IAYN,KAAK;IAKL,sBAAsB;IAa7B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;CASpB"}
1
+ {"version":3,"file":"inkCanvas.d.ts","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAiD,MAAM,iBAAiB,CAAC;AAyG9F;;GAEG;AACH,qBAAa,SAAS;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IANvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAkC;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;gBAGhB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,IAAI;IAwBtB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIhC,MAAM,IAAI,IAAI;IAYd,KAAK,IAAI,IAAI;IAKb,sBAAsB,IAAI,IAAI;IAarC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;CASpB"}
package/dist/inkCanvas.js CHANGED
@@ -24,7 +24,7 @@ class Vector {
24
24
  this.y = y;
25
25
  }
26
26
  length() {
27
- return Math.sqrt(this.x * this.x + this.y * this.y);
27
+ return Math.hypot(this.x, this.y);
28
28
  }
29
29
  }
30
30
  function drawPolygon(context, points) {
@@ -143,8 +143,10 @@ class InkCanvas {
143
143
  }
144
144
  handlePointerMove(evt) {
145
145
  if (this.localActiveStrokeMap.has(evt.pointerId)) {
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
146
147
  const evts = evt?.getCoalescedEvents() ?? [evt];
147
148
  for (const e of evts) {
149
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
148
150
  this.appendPointerEventToStroke(e);
149
151
  }
150
152
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inkCanvas.js","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IColor, IInk, IInkPoint, IInkStroke, IPen, IStylusOperation } from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.sqrt(this.x * this.x + this.y * this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]) {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number) {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor) {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay() {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear() {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore() {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent) {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent) {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent) {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent) {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number) {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas() {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw() {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint) {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation) {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
1
+ {"version":3,"file":"inkCanvas.js","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IColor, IInk, IInkPoint, IInkStroke, IPen, IStylusOperation } from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.hypot(this.x, this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]): void {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number): void {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor): void {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear(): void {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore(): void {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent): void {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent): void {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number): void {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas(): void {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint): void {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation): void {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inkFactory.d.ts","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAK5E;;;;GAIG;AACH,qBAAa,UAAW,YAAW,eAAe;IACjD;;OAEG;IACH,OAAc,IAAI,SAA2C;IAE7D;;OAEG;IACH,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF;;OAEG;IACH,IAAW,IAAI,WAEd;IAED;;OAEG;IACH,IAAW,UAAU,uBAEpB;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAOzB;;OAEG;IACI,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa;CAMzE"}
1
+ {"version":3,"file":"inkFactory.d.ts","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAK5E;;;;GAIG;AACH,qBAAa,UAAW,YAAW,eAAe;IACjD;;OAEG;IACH,OAAc,IAAI,SAA2C;IAE7D;;OAEG;IACH,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAOzB;;OAEG;IACI,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa;CAMzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"inkFactory.js","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,qCAA+B;AAC/B,2DAAiD;AAEjD;;;;GAIG;AACH,MAAa,UAAU;IAetB;;OAEG;IACH,IAAW,IAAI;QACd,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACpB,OAAO,UAAU,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,YAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,OAA+B,EAAE,EAAU;QACxD,MAAM,GAAG,GAAG,IAAI,YAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;QACxD,GAAG,CAAC,eAAe,EAAE,CAAC;QAEtB,OAAO,GAAG,CAAC;IACZ,CAAC;;AApDF,gCAqDC;AApDA;;GAEG;AACW,eAAI,GAAG,uCAAuC,CAAC;AAE7D;;GAEG;AACoB,qBAAU,GAAuB;IACvD,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,8BAAU;CAC1B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport { Ink } from \"./ink.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Factory for Ink.\n * @sealed\n * @internal\n */\nexport class InkFactory implements IChannelFactory {\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic static Type = \"https://graph.microsoft.com/types/ink\";\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: InkFactory.Type,\n\t\tsnapshotFormatVersion: \"0.2\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic get type() {\n\t\treturn InkFactory.Type;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic get attributes() {\n\t\treturn InkFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedObject> {\n\t\tconst ink = new Ink(runtime, id, attributes);\n\t\tawait ink.load(services);\n\n\t\treturn ink;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n\t */\n\tpublic create(runtime: IFluidDataStoreRuntime, id: string): ISharedObject {\n\t\tconst ink = new Ink(runtime, id, InkFactory.Attributes);\n\t\tink.initializeLocal();\n\n\t\treturn ink;\n\t}\n}\n"]}
1
+ {"version":3,"file":"inkFactory.js","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,qCAA+B;AAC/B,2DAAiD;AAEjD;;;;GAIG;AACH,MAAa,UAAU;IAetB;;OAEG;IACH,IAAW,IAAI;QACd,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACpB,OAAO,UAAU,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,YAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,OAA+B,EAAE,EAAU;QACxD,MAAM,GAAG,GAAG,IAAI,YAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;QACxD,GAAG,CAAC,eAAe,EAAE,CAAC;QAEtB,OAAO,GAAG,CAAC;IACZ,CAAC;;AApDF,gCAqDC;AApDA;;GAEG;AACW,eAAI,GAAG,uCAAuC,CAAC;AAE7D;;GAEG;AACoB,qBAAU,GAAuB;IACvD,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,8BAAU;CAC1B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport { Ink } from \"./ink.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Factory for Ink.\n * @sealed\n * @internal\n */\nexport class InkFactory implements IChannelFactory {\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic static Type = \"https://graph.microsoft.com/types/ink\";\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: InkFactory.Type,\n\t\tsnapshotFormatVersion: \"0.2\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic get type(): string {\n\t\treturn InkFactory.Type;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn InkFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedObject> {\n\t\tconst ink = new Ink(runtime, id, attributes);\n\t\tawait ink.load(services);\n\n\t\treturn ink;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n\t */\n\tpublic create(runtime: IFluidDataStoreRuntime, id: string): ISharedObject {\n\t\tconst ink = new Ink(runtime, id, InkFactory.Attributes);\n\t\tink.initializeLocal();\n\n\t\treturn ink;\n\t}\n}\n"]}
package/dist/package.json CHANGED
@@ -1,3 +1,4 @@
1
1
  {
2
- "type": "commonjs"
2
+ "type": "commonjs",
3
+ "sideEffects": false
3
4
  }
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluid-experimental/ink";
8
- export declare const pkgVersion = "2.12.0";
8
+ export declare const pkgVersion = "2.20.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluid-experimental/ink";
11
- exports.pkgVersion = "2.12.0";
11
+ exports.pkgVersion = "2.20.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,yBAAyB,CAAC;AACpC,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluid-experimental/ink\";\nexport const pkgVersion = \"2.12.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,yBAAyB,CAAC;AACpC,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluid-experimental/ink\";\nexport const pkgVersion = \"2.20.0\";\n"]}
package/lib/ink.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EACN,gBAAgB,EAChB,YAAY,EAEZ,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAGN,IAAI,EACJ,UAAU,EAEV,SAAS,EACT,UAAU,EACV,IAAI,EAEJ,MAAM,iBAAiB,CAAC;AAQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,qBAAa,GAAI,SAAQ,YAAY,CAAC,UAAU,CAAE,YAAW,IAAI;IAChE;;;;;OAKG;WACW,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM;IAIjE;;;OAGG;WACW,UAAU;IAIxB;;OAEG;IACH,OAAO,CAAC,OAAO,CAA0B;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB;IAIvF;;OAEG;IACI,YAAY,CAAC,GAAG,EAAE,IAAI,GAAG,UAAU;IAW1C;;OAEG;IACI,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAUpE;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACI,UAAU,IAAI,UAAU,EAAE;IAIjC;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU;IAIzC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,qBAAqB;IAK5E;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,SAAS,CAAC,WAAW,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,GACtB,IAAI;IAuBP;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IAWpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAU9B,SAAS,CAAC,cAAc,IAAI,IAAI;CAGhC"}
1
+ {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EACN,gBAAgB,EAChB,YAAY,EAEZ,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAGN,IAAI,EACJ,UAAU,EAEV,SAAS,EACT,UAAU,EACV,IAAI,EAEJ,MAAM,iBAAiB,CAAC;AAQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,qBAAa,GAAI,SAAQ,YAAY,CAAC,UAAU,CAAE,YAAW,IAAI;IAChE;;;;;OAKG;WACW,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG;IAIvE;;;OAGG;WACW,UAAU,IAAI,UAAU;IAItC;;OAEG;IACH,OAAO,CAAC,OAAO,CAA0B;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB;IAIvF;;OAEG;IACI,YAAY,CAAC,GAAG,EAAE,IAAI,GAAG,UAAU;IAW1C;;OAEG;IACI,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAUpE;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACI,UAAU,IAAI,UAAU,EAAE;IAIjC;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU;IAIzC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,qBAAqB;IAK5E;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,SAAS,CAAC,WAAW,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,GACtB,IAAI;IAuBP;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IAWpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAU9B,SAAS,CAAC,cAAc,IAAI,IAAI;CAGhC"}
package/lib/ink.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ink.js","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tIFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { ISerializableInk, InkData } from \"./snapshot.js\";\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = \"header\";\n\n/**\n * `Ink` is a shared object which holds a collection of ink strokes.\n *\n * @remarks\n * ### Creation and setup\n *\n * To create an `Ink` object, call the static `create` method:\n *\n * ```typescript\n * const ink = Ink.create(this.runtime, id);\n * ```\n *\n * You'll also need an `IPen` that will describe the style of your stroke:\n *\n * ```typescript\n * this.currentPen = {\n * color: { r: 0, g: 161 / 255, b: 241 / 255, a: 0 },\n * thickness: 7,\n * };\n * ```\n *\n * ### Usage\n *\n * Once the `Ink` object is created, you can add and update ink strokes using `createStroke` and\n * `appendPointToStroke`. Most likely you'll want to do this in response to incoming Pointer Events:\n *\n * ```typescript\n * private handlePointerDown(e: PointerEvent) {\n * const newStroke = ink.createStroke(this.currentPen);\n * this.currentStrokeId = newStroke.id;\n * handlePointerMotion(e);\n * }\n *\n * private handlePointerMotion(e: PointerEvent) {\n * const inkPoint = {\n * x: e.clientX,\n * y: e.clientY,\n * time: Date.now(),\n * pressure: e.pressure,\n * };\n * ink.appendPointToStroke(inkPoint, this.currentStrokeId);\n * }\n *\n * canvas.addEventListener(\"pointerdown\", this.handlePointerDown);\n * canvas.addEventListener(\"pointermove\", this.handlePointerMotion);\n * canvas.addEventListener(\"pointerup\", this.handlePointerMotion);\n * ```\n *\n * You can also clear all the ink with `clear`:\n *\n * ```typescript\n * ink.clear();\n * ```\n *\n * To observe and react to changes to the ink from both your own modifications as well as remote participants,\n * you can listen to the `\"createStroke\"`, `\"stylus\"` and `\"clear\"` events. Since you don't need to render anything\n * yet when a stroke is first created, registering for `\"createStroke\"` may not be necessary.\n *\n * ```typescript\n * ink.on(\"stylus\", this.renderStylusUpdate.bind(this));\n * ink.on(\"clear\", this.renderClear.bind(this));\n * ```\n * @sealed\n * @internal\n */\nexport class Ink extends SharedObject<IInkEvents> implements IInk {\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - Data Store runtime the new Ink belongs to\n\t * @param id - Optional name of the Ink; will be assigned a unique ID if not provided\n\t * @returns Newly create Ink object (but not attached yet)\n\t */\n\tpublic static create(runtime: IFluidDataStoreRuntime, id?: string) {\n\t\treturn runtime.createChannel(id, InkFactory.Type) as Ink;\n\t}\n\n\t/**\n\t * Get a factory for Ink to register with the data store.\n\t * @returns A factory that creates and loads Ink\n\t */\n\tpublic static getFactory() {\n\t\treturn new InkFactory();\n\t}\n\n\t/**\n\t * The current ink snapshot.\n\t */\n\tprivate inkData: InkData = new InkData();\n\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - The runtime the Ink will be associated with\n\t * @param id - Unique ID for the Ink\n\t */\n\tconstructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes) {\n\t\tsuper(id, runtime, attributes, \"fluid_ink_\");\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.createStroke}\n\t */\n\tpublic createStroke(pen: IPen): IInkStroke {\n\t\tconst createStrokeOperation: ICreateStrokeOperation = {\n\t\t\tid: uuid(),\n\t\t\tpen,\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"createStroke\",\n\t\t};\n\t\tthis.submitLocalMessage(createStrokeOperation, undefined);\n\t\treturn this.executeCreateStrokeOperation(createStrokeOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.appendPointToStroke}\n\t */\n\tpublic appendPointToStroke(point: IInkPoint, id: string): IInkStroke {\n\t\tconst stylusOperation: IStylusOperation = {\n\t\t\tid,\n\t\t\tpoint,\n\t\t\ttype: \"stylus\",\n\t\t};\n\t\tthis.submitLocalMessage(stylusOperation, undefined);\n\t\treturn this.executeStylusOperation(stylusOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.clear}\n\t */\n\tpublic clear(): void {\n\t\tconst clearOperation: IClearOperation = {\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitLocalMessage(clearOperation, undefined);\n\t\tthis.executeClearOperation(clearOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.inkData.getStrokes();\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.inkData.getStroke(key);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst blobContent = JSON.stringify(this.inkData.getSerializable());\n\t\treturn createSingleBlobSummary(snapshotFileName, blobContent);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst content = await readAndParse<ISerializableInk>(storage, snapshotFileName);\n\t\tthis.inkData = new InkData(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tif (message.type === MessageType.Operation && !local) {\n\t\t\tconst operation = message.contents as IInkOperation;\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase \"clear\": {\n\t\t\t\t\tthis.executeClearOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"createStroke\": {\n\t\t\t\t\tthis.executeCreateStrokeOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"stylus\": {\n\t\t\t\t\tthis.executeStylusOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\treturn;\n\t}\n\n\t/**\n\t * Update the model for a clear operation.\n\t * @param operation - The operation object\n\t */\n\tprivate executeClearOperation(operation: IClearOperation): void {\n\t\tthis.inkData.clear();\n\t\tthis.emit(\"clear\", operation);\n\t}\n\n\t/**\n\t * Update the model for a create stroke operation.\n\t * @param operation - The operation object\n\t * @returns The stroke that was created\n\t */\n\tprivate executeCreateStrokeOperation(operation: ICreateStrokeOperation): IInkStroke {\n\t\tconst stroke: IInkStroke = {\n\t\t\tid: operation.id,\n\t\t\tpoints: [],\n\t\t\tpen: operation.pen,\n\t\t};\n\t\tthis.inkData.addStroke(stroke);\n\t\tthis.emit(\"createStroke\", operation);\n\t\treturn stroke;\n\t}\n\n\t/**\n\t * Update the model for a stylus operation. These represent updates to an existing stroke.\n\t * @param operation - The operation object\n\t * @returns The stroke that was updated\n\t */\n\tprivate executeStylusOperation(operation: IStylusOperation): IInkStroke {\n\t\t// Need to make sure the stroke is still there (hasn't been cleared) before appending the down/move/up.\n\t\tconst stroke = this.getStroke(operation.id);\n\t\tif (stroke !== undefined) {\n\t\t\tstroke.points.push(operation.point);\n\t\t\tthis.emit(\"stylus\", operation);\n\t\t}\n\t\treturn stroke;\n\t}\n\n\tprotected applyStashedOp(): void {\n\t\tthrow new Error(\"not implemented\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"ink.js","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tIFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { ISerializableInk, InkData } from \"./snapshot.js\";\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = \"header\";\n\n/**\n * `Ink` is a shared object which holds a collection of ink strokes.\n *\n * @remarks\n * ### Creation and setup\n *\n * To create an `Ink` object, call the static `create` method:\n *\n * ```typescript\n * const ink = Ink.create(this.runtime, id);\n * ```\n *\n * You'll also need an `IPen` that will describe the style of your stroke:\n *\n * ```typescript\n * this.currentPen = {\n * color: { r: 0, g: 161 / 255, b: 241 / 255, a: 0 },\n * thickness: 7,\n * };\n * ```\n *\n * ### Usage\n *\n * Once the `Ink` object is created, you can add and update ink strokes using `createStroke` and\n * `appendPointToStroke`. Most likely you'll want to do this in response to incoming Pointer Events:\n *\n * ```typescript\n * private handlePointerDown(e: PointerEvent) {\n * const newStroke = ink.createStroke(this.currentPen);\n * this.currentStrokeId = newStroke.id;\n * handlePointerMotion(e);\n * }\n *\n * private handlePointerMotion(e: PointerEvent) {\n * const inkPoint = {\n * x: e.clientX,\n * y: e.clientY,\n * time: Date.now(),\n * pressure: e.pressure,\n * };\n * ink.appendPointToStroke(inkPoint, this.currentStrokeId);\n * }\n *\n * canvas.addEventListener(\"pointerdown\", this.handlePointerDown);\n * canvas.addEventListener(\"pointermove\", this.handlePointerMotion);\n * canvas.addEventListener(\"pointerup\", this.handlePointerMotion);\n * ```\n *\n * You can also clear all the ink with `clear`:\n *\n * ```typescript\n * ink.clear();\n * ```\n *\n * To observe and react to changes to the ink from both your own modifications as well as remote participants,\n * you can listen to the `\"createStroke\"`, `\"stylus\"` and `\"clear\"` events. Since you don't need to render anything\n * yet when a stroke is first created, registering for `\"createStroke\"` may not be necessary.\n *\n * ```typescript\n * ink.on(\"stylus\", this.renderStylusUpdate.bind(this));\n * ink.on(\"clear\", this.renderClear.bind(this));\n * ```\n * @sealed\n * @internal\n */\nexport class Ink extends SharedObject<IInkEvents> implements IInk {\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - Data Store runtime the new Ink belongs to\n\t * @param id - Optional name of the Ink; will be assigned a unique ID if not provided\n\t * @returns Newly create Ink object (but not attached yet)\n\t */\n\tpublic static create(runtime: IFluidDataStoreRuntime, id?: string): Ink {\n\t\treturn runtime.createChannel(id, InkFactory.Type) as Ink;\n\t}\n\n\t/**\n\t * Get a factory for Ink to register with the data store.\n\t * @returns A factory that creates and loads Ink\n\t */\n\tpublic static getFactory(): InkFactory {\n\t\treturn new InkFactory();\n\t}\n\n\t/**\n\t * The current ink snapshot.\n\t */\n\tprivate inkData: InkData = new InkData();\n\n\t/**\n\t * Create a new Ink.\n\t * @param runtime - The runtime the Ink will be associated with\n\t * @param id - Unique ID for the Ink\n\t */\n\tconstructor(runtime: IFluidDataStoreRuntime, id: string, attributes: IChannelAttributes) {\n\t\tsuper(id, runtime, attributes, \"fluid_ink_\");\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.createStroke}\n\t */\n\tpublic createStroke(pen: IPen): IInkStroke {\n\t\tconst createStrokeOperation: ICreateStrokeOperation = {\n\t\t\tid: uuid(),\n\t\t\tpen,\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"createStroke\",\n\t\t};\n\t\tthis.submitLocalMessage(createStrokeOperation, undefined);\n\t\treturn this.executeCreateStrokeOperation(createStrokeOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.appendPointToStroke}\n\t */\n\tpublic appendPointToStroke(point: IInkPoint, id: string): IInkStroke {\n\t\tconst stylusOperation: IStylusOperation = {\n\t\t\tid,\n\t\t\tpoint,\n\t\t\ttype: \"stylus\",\n\t\t};\n\t\tthis.submitLocalMessage(stylusOperation, undefined);\n\t\treturn this.executeStylusOperation(stylusOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.clear}\n\t */\n\tpublic clear(): void {\n\t\tconst clearOperation: IClearOperation = {\n\t\t\ttime: Date.now(),\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitLocalMessage(clearOperation, undefined);\n\t\tthis.executeClearOperation(clearOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.inkData.getStrokes();\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.inkData.getStroke(key);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\tconst blobContent = JSON.stringify(this.inkData.getSerializable());\n\t\treturn createSingleBlobSummary(snapshotFileName, blobContent);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst content = await readAndParse<ISerializableInk>(storage, snapshotFileName);\n\t\tthis.inkData = new InkData(content);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tif (message.type === MessageType.Operation && !local) {\n\t\t\tconst operation = message.contents as IInkOperation;\n\t\t\tswitch (operation.type) {\n\t\t\t\tcase \"clear\": {\n\t\t\t\t\tthis.executeClearOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"createStroke\": {\n\t\t\t\t\tthis.executeCreateStrokeOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"stylus\": {\n\t\t\t\t\tthis.executeStylusOperation(operation);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\treturn;\n\t}\n\n\t/**\n\t * Update the model for a clear operation.\n\t * @param operation - The operation object\n\t */\n\tprivate executeClearOperation(operation: IClearOperation): void {\n\t\tthis.inkData.clear();\n\t\tthis.emit(\"clear\", operation);\n\t}\n\n\t/**\n\t * Update the model for a create stroke operation.\n\t * @param operation - The operation object\n\t * @returns The stroke that was created\n\t */\n\tprivate executeCreateStrokeOperation(operation: ICreateStrokeOperation): IInkStroke {\n\t\tconst stroke: IInkStroke = {\n\t\t\tid: operation.id,\n\t\t\tpoints: [],\n\t\t\tpen: operation.pen,\n\t\t};\n\t\tthis.inkData.addStroke(stroke);\n\t\tthis.emit(\"createStroke\", operation);\n\t\treturn stroke;\n\t}\n\n\t/**\n\t * Update the model for a stylus operation. These represent updates to an existing stroke.\n\t * @param operation - The operation object\n\t * @returns The stroke that was updated\n\t */\n\tprivate executeStylusOperation(operation: IStylusOperation): IInkStroke {\n\t\t// Need to make sure the stroke is still there (hasn't been cleared) before appending the down/move/up.\n\t\tconst stroke = this.getStroke(operation.id);\n\t\tif (stroke !== undefined) {\n\t\t\tstroke.points.push(operation.point);\n\t\t\tthis.emit(\"stylus\", operation);\n\t\t}\n\t\treturn stroke;\n\t}\n\n\tprotected applyStashedOp(): void {\n\t\tthrow new Error(\"not implemented\");\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inkCanvas.d.ts","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAiD,MAAM,iBAAiB,CAAC;AAyG9F;;GAEG;AACH,qBAAa,SAAS;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IANvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAkC;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;gBAGhB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,IAAI;IAwBtB,WAAW,CAAC,KAAK,EAAE,MAAM;IAIzB,MAAM;IAYN,KAAK;IAKL,sBAAsB;IAa7B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;CASpB"}
1
+ {"version":3,"file":"inkCanvas.d.ts","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAiD,MAAM,iBAAiB,CAAC;AAyG9F;;GAEG;AACH,qBAAa,SAAS;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IANvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAkC;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;gBAGhB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,IAAI;IAwBtB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIhC,MAAM,IAAI,IAAI;IAYd,KAAK,IAAI,IAAI;IAKb,sBAAsB,IAAI,IAAI;IAarC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;CASpB"}
package/lib/inkCanvas.js CHANGED
@@ -21,7 +21,7 @@ class Vector {
21
21
  this.y = y;
22
22
  }
23
23
  length() {
24
- return Math.sqrt(this.x * this.x + this.y * this.y);
24
+ return Math.hypot(this.x, this.y);
25
25
  }
26
26
  }
27
27
  function drawPolygon(context, points) {
@@ -140,8 +140,10 @@ export class InkCanvas {
140
140
  }
141
141
  handlePointerMove(evt) {
142
142
  if (this.localActiveStrokeMap.has(evt.pointerId)) {
143
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
143
144
  const evts = evt?.getCoalescedEvents() ?? [evt];
144
145
  for (const e of evts) {
146
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
145
147
  this.appendPointerEventToStroke(e);
146
148
  }
147
149
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inkCanvas.js","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,MAAM;IACX;;OAEG;IACI,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,KAAa;QACjD,OAAO,IAAI,MAAM,CAChB,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EACvD,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,MAAc;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/B,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,YACQ,CAAS,EACT,CAAS;QADT,MAAC,GAAD,CAAC,CAAQ;QACT,MAAC,GAAD,CAAC,CAAQ;IACd,CAAC;IAEG,MAAM;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;CACD;AAED,SAAS,WAAW,CAAC,OAAiC,EAAE,MAAgB;IACvE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;IACR,CAAC;IAED,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzC,gCAAgC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,OAAiC,EAAE,MAAc,EAAE,MAAc;IACpF,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAClB,OAAiC,EACjC,UAAqB,EACrB,QAAmB,EACnB,GAAS;IAET,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAE/B,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC;IACzD,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAErD,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC;QACnF,qDAAqD;QACrD,MAAM,uBAAuB,GAAG,IAAI,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,EAAE,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAElF,MAAM,WAAW,GAAG;YACnB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,YAAY,GAAG,uBAAuB,CAAC,CAAC;YAC1D,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,YAAY,GAAG,uBAAuB,CAAC,CAAC;SAC1D,CAAC;QACF,MAAM,WAAW,GAAG;YACnB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,YAAY,GAAG,uBAAuB,CAAC,CAAC;YAC1D,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,YAAY,GAAG,uBAAuB,CAAC,CAAC;SAC1D,CAAC;QACF,MAAM,WAAW,GAAG;YACnB,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,UAAU,GAAG,uBAAuB,CAAC,CAAC;YACtD,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,UAAU,GAAG,uBAAuB,CAAC,CAAC;SACtD,CAAC;QACF,MAAM,WAAW,GAAG;YACnB,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,UAAU,GAAG,uBAAuB,CAAC,CAAC;YACtD,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,UAAU,GAAG,uBAAuB,CAAC,CAAC;SACtD,CAAC;QAEF,WAAW,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,aAAa;IACb,8FAA8F;IAC9F,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,SAAS;IAKrB,YACkB,MAAyB,EACzB,KAAW;QADX,WAAM,GAAN,MAAM,CAAmB;QACzB,UAAK,GAAL,KAAK,CAAM;QALZ,yBAAoB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAOtE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;QAEvC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE3E,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,IAAI,CAAC,UAAU,GAAG;YACjB,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE;YACrC,SAAS,EAAE,CAAC;SACZ,CAAC;QAEF,IAAI,CAAC,sBAAsB,EAAE,CAAC;IAC/B,CAAC;IAEM,WAAW,CAAC,KAAa;QAC/B,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC;IAC/B,CAAC;IAEM,MAAM;QACZ,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAExC,+DAA+D;QAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;IAEM,KAAK;QACX,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAEM,sBAAsB;QAC5B,MAAM,wBAAwB,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACrE,wEAAwE;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QACzE,kEAAkE;QAClE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAEO,iBAAiB,CAAC,GAAiB;QAC1C,uEAAuE;QACvE,IAAI,GAAG,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,WAAW,KAAK,OAAO,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YACpF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAEvD,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAErC,GAAG,CAAC,cAAc,EAAE,CAAC;QACtB,CAAC;IACF,CAAC;IAEO,iBAAiB,CAAC,GAAiB;QAC1C,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,GAAI,GAAW,EAAE,kBAAkB,EAAE,IAAK,CAAC,GAAG,CAAoB,CAAC;YAC7E,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;YACpC,CAAC;QACF,CAAC;IACF,CAAC;IAEO,eAAe,CAAC,GAAiB;QACxC,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IAEO,0BAA0B,CAAC,GAAiB;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,KAAK,GAAG;YACb,CAAC,EAAE,GAAG,CAAC,OAAO;YACd,CAAC,EAAE,GAAG,CAAC,OAAO;YACd,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACtB,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;IAEO,aAAa,CAAC,MAAkB,EAAE,cAAsB,EAAE,SAAiB;QAClF,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5C,OAAO;QACR,CAAC;QAED,4BAA4B;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,MAAM,IAAI,GACT,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAEhF,UAAU,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YACtD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;QAC3D,CAAC,EAAE,IAAI,CAAC,CAAC;IACV,CAAC;IAED;;OAEG;IACK,WAAW;QAClB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrE,CAAC;IAEO,MAAM;QACb,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACxC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAChC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACrC,8DAA8D;gBAC9D,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACtD,QAAQ,GAAG,OAAO,CAAC;YACpB,CAAC;QACF,CAAC;IACF,CAAC;IAEO,iBAAiB,CAAC,GAAS,EAAE,OAAkB,EAAE,QAAmB;QAC3E,qCAAqC;QACrC,kCAAkC;QAClC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;QAC/E,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IAEO,YAAY,CAAC,SAA2B;QAC/C,0BAA0B;QAC1B,MAAM,aAAa,GAAG,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACnD,kGAAkG;QAClG,MAAM,SAAS,GACd,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IColor, IInk, IInkPoint, IInkStroke, IPen, IStylusOperation } from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.sqrt(this.x * this.x + this.y * this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]) {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number) {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor) {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay() {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear() {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore() {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent) {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent) {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent) {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent) {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number) {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas() {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw() {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint) {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation) {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
1
+ {"version":3,"file":"inkCanvas.js","sourceRoot":"","sources":["../src/inkCanvas.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IColor, IInk, IInkPoint, IInkStroke, IPen, IStylusOperation } from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.hypot(this.x, this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]): void {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number): void {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor): void {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear(): void {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore(): void {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent): void {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent): void {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number): void {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas(): void {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint): void {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation): void {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inkFactory.d.ts","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAK5E;;;;GAIG;AACH,qBAAa,UAAW,YAAW,eAAe;IACjD;;OAEG;IACH,OAAc,IAAI,SAA2C;IAE7D;;OAEG;IACH,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF;;OAEG;IACH,IAAW,IAAI,WAEd;IAED;;OAEG;IACH,IAAW,UAAU,uBAEpB;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAOzB;;OAEG;IACI,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa;CAMzE"}
1
+ {"version":3,"file":"inkFactory.d.ts","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAK5E;;;;GAIG;AACH,qBAAa,UAAW,YAAW,eAAe;IACjD;;OAEG;IACH,OAAc,IAAI,SAA2C;IAE7D;;OAEG;IACH,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAOzB;;OAEG;IACI,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa;CAMzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"inkFactory.js","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAetB;;OAEG;IACH,IAAW,IAAI;QACd,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACpB,OAAO,UAAU,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,OAA+B,EAAE,EAAU;QACxD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;QACxD,GAAG,CAAC,eAAe,EAAE,CAAC;QAEtB,OAAO,GAAG,CAAC;IACZ,CAAC;;AAnDD;;GAEG;AACW,eAAI,GAAG,uCAAuC,CAAC;AAE7D;;GAEG;AACoB,qBAAU,GAAuB;IACvD,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport { Ink } from \"./ink.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Factory for Ink.\n * @sealed\n * @internal\n */\nexport class InkFactory implements IChannelFactory {\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic static Type = \"https://graph.microsoft.com/types/ink\";\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: InkFactory.Type,\n\t\tsnapshotFormatVersion: \"0.2\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic get type() {\n\t\treturn InkFactory.Type;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic get attributes() {\n\t\treturn InkFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedObject> {\n\t\tconst ink = new Ink(runtime, id, attributes);\n\t\tawait ink.load(services);\n\n\t\treturn ink;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n\t */\n\tpublic create(runtime: IFluidDataStoreRuntime, id: string): ISharedObject {\n\t\tconst ink = new Ink(runtime, id, InkFactory.Attributes);\n\t\tink.initializeLocal();\n\n\t\treturn ink;\n\t}\n}\n"]}
1
+ {"version":3,"file":"inkFactory.js","sourceRoot":"","sources":["../src/inkFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAetB;;OAEG;IACH,IAAW,IAAI;QACd,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACpB,OAAO,UAAU,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,OAA+B,EAAE,EAAU;QACxD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;QACxD,GAAG,CAAC,eAAe,EAAE,CAAC;QAEtB,OAAO,GAAG,CAAC;IACZ,CAAC;;AAnDD;;GAEG;AACW,eAAI,GAAG,uCAAuC,CAAC;AAE7D;;GAEG;AACoB,qBAAU,GAAuB;IACvD,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport { Ink } from \"./ink.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Factory for Ink.\n * @sealed\n * @internal\n */\nexport class InkFactory implements IChannelFactory {\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic static Type = \"https://graph.microsoft.com/types/ink\";\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: InkFactory.Type,\n\t\tsnapshotFormatVersion: \"0.2\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n\t */\n\tpublic get type(): string {\n\t\treturn InkFactory.Type;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n\t */\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn InkFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedObject> {\n\t\tconst ink = new Ink(runtime, id, attributes);\n\t\tawait ink.load(services);\n\n\t\treturn ink;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n\t */\n\tpublic create(runtime: IFluidDataStoreRuntime, id: string): ISharedObject {\n\t\tconst ink = new Ink(runtime, id, InkFactory.Attributes);\n\t\tink.initializeLocal();\n\n\t\treturn ink;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluid-experimental/ink";
8
- export declare const pkgVersion = "2.12.0";
8
+ export declare const pkgVersion = "2.20.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluid-experimental/ink";
8
- export const pkgVersion = "2.12.0";
8
+ export const pkgVersion = "2.20.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,yBAAyB,CAAC;AACjD,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluid-experimental/ink\";\nexport const pkgVersion = \"2.12.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,yBAAyB,CAAC;AACjD,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluid-experimental/ink\";\nexport const pkgVersion = \"2.20.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-experimental/ink",
3
- "version": "2.12.0",
3
+ "version": "2.20.0",
4
4
  "description": "Ink DDS",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -49,26 +49,26 @@
49
49
  "temp-directory": "nyc/.nyc_output"
50
50
  },
51
51
  "dependencies": {
52
- "@fluidframework/core-interfaces": "~2.12.0",
53
- "@fluidframework/datastore-definitions": "~2.12.0",
54
- "@fluidframework/driver-definitions": "~2.12.0",
55
- "@fluidframework/driver-utils": "~2.12.0",
56
- "@fluidframework/runtime-definitions": "~2.12.0",
57
- "@fluidframework/shared-object-base": "~2.12.0",
52
+ "@fluidframework/core-interfaces": "~2.20.0",
53
+ "@fluidframework/datastore-definitions": "~2.20.0",
54
+ "@fluidframework/driver-definitions": "~2.20.0",
55
+ "@fluidframework/driver-utils": "~2.20.0",
56
+ "@fluidframework/runtime-definitions": "~2.20.0",
57
+ "@fluidframework/shared-object-base": "~2.20.0",
58
58
  "uuid": "^9.0.0"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@arethetypeswrong/cli": "^0.17.1",
62
62
  "@biomejs/biome": "~1.9.3",
63
- "@fluid-internal/mocha-test-setup": "~2.12.0",
63
+ "@fluid-internal/mocha-test-setup": "~2.20.0",
64
64
  "@fluid-tools/build-cli": "^0.51.0",
65
65
  "@fluidframework/build-common": "^2.0.3",
66
66
  "@fluidframework/build-tools": "^0.51.0",
67
- "@fluidframework/container-definitions": "~2.12.0",
67
+ "@fluidframework/container-definitions": "~2.20.0",
68
68
  "@fluidframework/eslint-config-fluid": "^5.6.0",
69
- "@fluidframework/test-runtime-utils": "~2.12.0",
69
+ "@fluidframework/test-runtime-utils": "~2.20.0",
70
70
  "@microsoft/api-extractor": "7.47.8",
71
- "@types/mocha": "^9.1.1",
71
+ "@types/mocha": "^10.0.10",
72
72
  "@types/node": "^18.19.0",
73
73
  "@types/uuid": "^9.0.2",
74
74
  "c8": "^8.0.1",
package/src/ink.ts CHANGED
@@ -112,7 +112,7 @@ export class Ink extends SharedObject<IInkEvents> implements IInk {
112
112
  * @param id - Optional name of the Ink; will be assigned a unique ID if not provided
113
113
  * @returns Newly create Ink object (but not attached yet)
114
114
  */
115
- public static create(runtime: IFluidDataStoreRuntime, id?: string) {
115
+ public static create(runtime: IFluidDataStoreRuntime, id?: string): Ink {
116
116
  return runtime.createChannel(id, InkFactory.Type) as Ink;
117
117
  }
118
118
 
@@ -120,7 +120,7 @@ export class Ink extends SharedObject<IInkEvents> implements IInk {
120
120
  * Get a factory for Ink to register with the data store.
121
121
  * @returns A factory that creates and loads Ink
122
122
  */
123
- public static getFactory() {
123
+ public static getFactory(): InkFactory {
124
124
  return new InkFactory();
125
125
  }
126
126
 
package/src/inkCanvas.ts CHANGED
@@ -35,11 +35,11 @@ class Vector {
35
35
  ) {}
36
36
 
37
37
  public length(): number {
38
- return Math.sqrt(this.x * this.x + this.y * this.y);
38
+ return Math.hypot(this.x, this.y);
39
39
  }
40
40
  }
41
41
 
42
- function drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]) {
42
+ function drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]): void {
43
43
  if (points.length === 0) {
44
44
  return;
45
45
  }
@@ -59,7 +59,7 @@ function drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]) {
59
59
  context.fill();
60
60
  }
61
61
 
62
- function drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number) {
62
+ function drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number): void {
63
63
  context.beginPath();
64
64
  context.moveTo(center.x, center.y);
65
65
  context.arc(center.x, center.y, radius, 0, Math.PI * 2);
@@ -142,11 +142,11 @@ export class InkCanvas {
142
142
  this.sizeCanvasBackingStore();
143
143
  }
144
144
 
145
- public setPenColor(color: IColor) {
145
+ public setPenColor(color: IColor): void {
146
146
  this.currentPen.color = color;
147
147
  }
148
148
 
149
- public replay() {
149
+ public replay(): void {
150
150
  this.clearCanvas();
151
151
 
152
152
  const strokes = this.model.getStrokes();
@@ -158,12 +158,12 @@ export class InkCanvas {
158
158
  }
159
159
  }
160
160
 
161
- public clear() {
161
+ public clear(): void {
162
162
  this.model.clear();
163
163
  this.redraw();
164
164
  }
165
165
 
166
- public sizeCanvasBackingStore() {
166
+ public sizeCanvasBackingStore(): void {
167
167
  const canvasBoundingClientRect = this.canvas.getBoundingClientRect();
168
168
  // Scale the canvas size to match the physical pixel to avoid blurriness
169
169
  const scale = window.devicePixelRatio;
@@ -176,7 +176,7 @@ export class InkCanvas {
176
176
  this.redraw();
177
177
  }
178
178
 
179
- private handlePointerDown(evt: PointerEvent) {
179
+ private handlePointerDown(evt: PointerEvent): void {
180
180
  // We will accept pen down or mouse left down as the start of a stroke.
181
181
  if (evt.pointerType === "pen" || (evt.pointerType === "mouse" && evt.button === 0)) {
182
182
  const strokeId = this.model.createStroke(this.currentPen).id;
@@ -188,23 +188,25 @@ export class InkCanvas {
188
188
  }
189
189
  }
190
190
 
191
- private handlePointerMove(evt: PointerEvent) {
191
+ private handlePointerMove(evt: PointerEvent): void {
192
192
  if (this.localActiveStrokeMap.has(evt.pointerId)) {
193
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
193
194
  const evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);
194
195
  for (const e of evts) {
196
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
195
197
  this.appendPointerEventToStroke(e);
196
198
  }
197
199
  }
198
200
  }
199
201
 
200
- private handlePointerUp(evt: PointerEvent) {
202
+ private handlePointerUp(evt: PointerEvent): void {
201
203
  if (this.localActiveStrokeMap.has(evt.pointerId)) {
202
204
  this.appendPointerEventToStroke(evt);
203
205
  this.localActiveStrokeMap.delete(evt.pointerId);
204
206
  }
205
207
  }
206
208
 
207
- private appendPointerEventToStroke(evt: PointerEvent) {
209
+ private appendPointerEventToStroke(evt: PointerEvent): void {
208
210
  const strokeId = this.localActiveStrokeMap.get(evt.pointerId);
209
211
  if (strokeId === undefined) {
210
212
  throw new Error("Unexpected pointer ID trying to append to stroke");
@@ -218,7 +220,7 @@ export class InkCanvas {
218
220
  this.model.appendPointToStroke(inkPt, strokeId);
219
221
  }
220
222
 
221
- private animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number) {
223
+ private animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number): void {
222
224
  if (operationIndex >= stroke.points.length) {
223
225
  return;
224
226
  }
@@ -238,11 +240,11 @@ export class InkCanvas {
238
240
  /**
239
241
  * Clears the canvas
240
242
  */
241
- private clearCanvas() {
243
+ private clearCanvas(): void {
242
244
  this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
243
245
  }
244
246
 
245
- private redraw() {
247
+ private redraw(): void {
246
248
  this.clearCanvas();
247
249
 
248
250
  const strokes = this.model.getStrokes();
@@ -256,14 +258,14 @@ export class InkCanvas {
256
258
  }
257
259
  }
258
260
 
259
- private drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint) {
261
+ private drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint): void {
260
262
  // TODO Consider save/restore context
261
263
  // TODO Consider half-pixel offset
262
264
  this.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;
263
265
  drawShapes(this.context, previous, current, pen);
264
266
  }
265
267
 
266
- private handleStylus(operation: IStylusOperation) {
268
+ private handleStylus(operation: IStylusOperation): void {
267
269
  // Render the dirty stroke
268
270
  const dirtyStrokeId = operation.id;
269
271
  const stroke = this.model.getStroke(dirtyStrokeId);
package/src/inkFactory.ts CHANGED
@@ -37,14 +37,14 @@ export class InkFactory implements IChannelFactory {
37
37
  /**
38
38
  * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
39
39
  */
40
- public get type() {
40
+ public get type(): string {
41
41
  return InkFactory.Type;
42
42
  }
43
43
 
44
44
  /**
45
45
  * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
46
46
  */
47
- public get attributes() {
47
+ public get attributes(): IChannelAttributes {
48
48
  return InkFactory.Attributes;
49
49
  }
50
50
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluid-experimental/ink";
9
- export const pkgVersion = "2.12.0";
9
+ export const pkgVersion = "2.20.0";