@fluid-experimental/ink 2.13.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 +1 -4
- package/CHANGELOG.md +4 -0
- package/dist/ink.d.ts.map +1 -1
- package/dist/ink.js.map +1 -1
- package/dist/inkCanvas.d.ts.map +1 -1
- package/dist/inkCanvas.js +3 -1
- package/dist/inkCanvas.js.map +1 -1
- package/dist/inkFactory.d.ts.map +1 -1
- package/dist/inkFactory.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/ink.d.ts.map +1 -1
- package/lib/ink.js.map +1 -1
- package/lib/inkCanvas.d.ts.map +1 -1
- package/lib/inkCanvas.js +3 -1
- package/lib/inkCanvas.js.map +1 -1
- package/lib/inkFactory.d.ts.map +1 -1
- package/lib/inkFactory.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +10 -10
- package/src/ink.ts +2 -2
- package/src/inkCanvas.ts +18 -16
- package/src/inkFactory.ts +2 -2
- package/src/packageVersion.ts +1 -1
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
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;
|
|
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"]}
|
package/dist/inkCanvas.d.ts.map
CHANGED
|
@@ -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;
|
|
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.
|
|
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
|
}
|
package/dist/inkCanvas.js.map
CHANGED
|
@@ -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"]}
|
package/dist/inkFactory.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/inkFactory.js.map
CHANGED
|
@@ -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
package/dist/packageVersion.d.ts
CHANGED
package/dist/packageVersion.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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;
|
|
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":"AAAA;;;GAGG;AAOH,OAAO,EACN,WAAW,GAEX,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAErE,OAAO,EAEN,YAAY,EACZ,uBAAuB,GACvB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAY7C,OAAO,EAAoB,OAAO,EAAE,MAAM,eAAe,CAAC;AAE1D;;GAEG;AACH,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,MAAM,OAAO,GAAI,SAAQ,YAAwB;IAChD;;;;;OAKG;IACI,MAAM,CAAC,MAAM,CAAC,OAA+B,EAAE,EAAW;QAChE,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,CAAQ,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,UAAU;QACvB,OAAO,IAAI,UAAU,EAAE,CAAC;IACzB,CAAC;IAOD;;;;OAIG;IACH,YAAY,OAA+B,EAAE,EAAU,EAAE,UAA8B;QACtF,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAX9C;;WAEG;QACK,YAAO,GAAY,IAAI,OAAO,EAAE,CAAC;IASzC,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,GAAS;QAC5B,MAAM,qBAAqB,GAA2B;YACrD,EAAE,EAAE,IAAI,EAAE;YACV,GAAG;YACH,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,IAAI,EAAE,cAAc;SACpB,CAAC;QACF,IAAI,CAAC,kBAAkB,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,4BAA4B,CAAC,qBAAqB,CAAC,CAAC;IACjE,CAAC;IAED;;OAEG;IACI,mBAAmB,CAAC,KAAgB,EAAE,EAAU;QACtD,MAAM,eAAe,GAAqB;YACzC,EAAE;YACF,KAAK;YACL,IAAI,EAAE,QAAQ;SACd,CAAC;QACF,IAAI,CAAC,kBAAkB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACI,KAAK;QACX,MAAM,cAAc,GAAoB;YACvC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,IAAI,EAAE,OAAO;SACb,CAAC;QACF,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACI,UAAU;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACO,aAAa,CAAC,UAA4B;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;QACnE,OAAO,uBAAuB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,QAAQ,CAAC,OAA+B;QACvD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAmB,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAChF,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACO,WAAW,CACpB,OAAkC,EAClC,KAAc,EACd,eAAwB;QAExB,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC;YACtD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAyB,CAAC;YACpD,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;gBACxB,KAAK,OAAO,CAAC,CAAC,CAAC;oBACd,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;oBACtC,MAAM;gBACP,CAAC;gBACD,KAAK,cAAc,CAAC,CAAC,CAAC;oBACrB,IAAI,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;oBAC7C,MAAM;gBACP,CAAC;gBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACf,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;oBACvC,MAAM;gBACP,CAAC;gBACD,OAAO,CAAC,CAAC,CAAC;oBACT,MAAM;gBACP,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACO,YAAY;QACrB,OAAO;IACR,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,SAA0B;QACvD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACK,4BAA4B,CAAC,SAAiC;QACrE,MAAM,MAAM,GAAe;YAC1B,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,MAAM,EAAE,EAAE;YACV,GAAG,EAAE,SAAS,CAAC,GAAG;SAClB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;OAIG;IACK,sBAAsB,CAAC,SAA2B;QACzD,uGAAuG;QACvG,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAES,cAAc;QACvB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACpC,CAAC;CACD","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"]}
|
package/lib/inkCanvas.d.ts.map
CHANGED
|
@@ -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;
|
|
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.
|
|
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
|
}
|
package/lib/inkCanvas.js.map
CHANGED
|
@@ -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"]}
|
package/lib/inkFactory.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/lib/inkFactory.js.map
CHANGED
|
@@ -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"]}
|
package/lib/packageVersion.d.ts
CHANGED
package/lib/packageVersion.js
CHANGED
|
@@ -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.
|
|
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.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "Ink DDS",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -49,24 +49,24 @@
|
|
|
49
49
|
"temp-directory": "nyc/.nyc_output"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@fluidframework/core-interfaces": "~2.
|
|
53
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
54
|
-
"@fluidframework/driver-definitions": "~2.
|
|
55
|
-
"@fluidframework/driver-utils": "~2.
|
|
56
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
57
|
-
"@fluidframework/shared-object-base": "~2.
|
|
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.
|
|
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.
|
|
67
|
+
"@fluidframework/container-definitions": "~2.20.0",
|
|
68
68
|
"@fluidframework/eslint-config-fluid": "^5.6.0",
|
|
69
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
69
|
+
"@fluidframework/test-runtime-utils": "~2.20.0",
|
|
70
70
|
"@microsoft/api-extractor": "7.47.8",
|
|
71
71
|
"@types/mocha": "^10.0.10",
|
|
72
72
|
"@types/node": "^18.19.0",
|
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.
|
|
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
|
|
package/src/packageVersion.ts
CHANGED