@fluid-experimental/ink 2.118.0 → 3.0.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/CHANGELOG.md +22 -4
- package/README.md +52 -48
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/api-extractor/api-extractor-report.json +5 -0
- package/dist/ink.js +4 -4
- package/dist/ink.js.map +1 -1
- package/dist/inkCanvas.js +7 -1
- package/dist/inkCanvas.js.map +1 -1
- package/dist/inkFactory.js +15 -15
- package/dist/inkFactory.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/snapshot.js +8 -0
- package/dist/snapshot.js.map +1 -1
- package/lib/ink.js +4 -4
- package/lib/ink.js.map +1 -1
- package/lib/inkCanvas.js +7 -1
- package/lib/inkCanvas.js.map +1 -1
- package/lib/inkFactory.js +15 -15
- package/lib/inkFactory.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/snapshot.js +8 -0
- package/lib/snapshot.js.map +1 -1
- package/package.json +21 -27
- package/src/packageVersion.ts +1 -1
- package/tsconfig.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
# @fluid-experimental/ink
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 3.0.0
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Minor Changes
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Removal of direct CommonJS support ([#28124](https://github.com/microsoft/FluidFramework/pull/28124)) [0f84e3b8878](https://github.com/microsoft/FluidFramework/commit/0f84e3b8878a5e75b2253976d98fd963bbd9db88)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Direct `require()` import is no longer directly supported.
|
|
10
|
+
Package is transpiled as ECMAScript Module.
|
|
11
|
+
|
|
12
|
+
See [Removal of direct CommonJS support in v3.0](https://github.com/microsoft/FluidFramework/issues/27444) for more information.
|
|
13
|
+
|
|
14
|
+
- Client packages now target ES2022 ([#27846](https://github.com/microsoft/FluidFramework/pull/27846)) [91c78541bdd](https://github.com/microsoft/FluidFramework/commit/91c78541bddcbca5d6c5f357b023eeaee617d885)
|
|
15
|
+
|
|
16
|
+
The TypeScript compilation `target` and `lib` for the Fluid Framework client packages have been raised from ES2021/ES2020 to **ES2022**.
|
|
17
|
+
The published JavaScript now uses ES2022 language features (with correspondingly less down-leveling), so consuming these packages requires a runtime that supports ES2022.
|
|
18
|
+
All actively supported Node.js versions and evergreen browsers already meet this requirement.
|
|
19
|
+
|
|
20
|
+
Note that Fluid Framework has not officially supported targets older than ES2022 since before 2.0: this is documented in [ClientRequirements.md](https://github.com/microsoft/FluidFramework/blob/main/ClientRequirements.md) as well as the README for every client package.
|
|
21
|
+
|
|
22
|
+
It is possible this change could impact users of less up to date JavaScript runtimes.
|
|
23
|
+
Impacted users can use a tool like [babel](https://babeljs.io/) to transpile out unsupported language features.
|
|
24
|
+
|
|
25
|
+
- Build with TypeScript 6 ([#28052](https://github.com/microsoft/FluidFramework/pull/28052)) [7ab015c49de](https://github.com/microsoft/FluidFramework/commit/7ab015c49deec84833cdfe1fb5e1606b901f6e81)
|
|
26
|
+
|
|
27
|
+
FluidFramework Client SDK is now built using TypeScript 6. Consumers should build with TypeScript v6 or v7 or compatible tooling.
|
|
10
28
|
|
|
11
29
|
## 2.116.0
|
|
12
30
|
|
package/README.md
CHANGED
|
@@ -8,21 +8,22 @@ Contains a [Distributed Data Structure](https://fluidframework.com/docs/build/dd
|
|
|
8
8
|
<!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
|
|
9
9
|
|
|
10
10
|
**IMPORTANT: This package is experimental.**
|
|
11
|
-
**
|
|
11
|
+
**The APIs can change without notice.**
|
|
12
12
|
|
|
13
|
-
**Do not use in production scenarios.**
|
|
13
|
+
**Do not use it as a dependency in production scenarios.**
|
|
14
|
+
**We do not guarantee the stability of this package or its APIs.**
|
|
14
15
|
|
|
15
16
|
## Using Fluid Framework libraries
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
library consumers should always prefer `^`.
|
|
18
|
+
For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
|
|
19
|
+
For example, use `^1.3.4`.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
|
|
22
|
+
For example, use a `~` version range.
|
|
22
23
|
|
|
23
24
|
## Installation
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
Run this command to install the package:
|
|
26
27
|
|
|
27
28
|
```bash
|
|
28
29
|
npm i @fluid-experimental/ink
|
|
@@ -30,7 +31,7 @@ npm i @fluid-experimental/ink
|
|
|
30
31
|
|
|
31
32
|
## API Documentation
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
Read the **@fluid-experimental/ink** API documentation at <https://fluidframework.com/docs/apis/ink>.
|
|
34
35
|
|
|
35
36
|
<!-- prettier-ignore-end -->
|
|
36
37
|
|
|
@@ -43,62 +44,69 @@ API documentation for **@fluid-experimental/ink** is available at <https://fluid
|
|
|
43
44
|
|
|
44
45
|
## Minimum Client Requirements
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
These requirements
|
|
48
|
-
|
|
47
|
+
Fluid Framework client libraries support the platforms in this document.
|
|
48
|
+
These requirements are intentionally restrictive.
|
|
49
|
+
Within a major version series, we can relax these requirements, but we cannot make them stricter.
|
|
50
|
+
For a Long Term Support (LTS) version, we might need to support these platforms for several years.
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
If
|
|
52
|
-
|
|
52
|
+
Other configurations can work, but Fluid Framework does not support them.
|
|
53
|
+
If an unsupported configuration stops working, we do not classify this as a bug.
|
|
54
|
+
To request support for a configuration that is not listed, file an issue.
|
|
55
|
+
The product team will evaluate your request.
|
|
56
|
+
In the issue, specify the current status of the configuration:
|
|
57
|
+
|
|
58
|
+
- The configuration works but needs official support.
|
|
59
|
+
- The configuration does not work and requires changes.
|
|
53
60
|
|
|
54
61
|
### Supported Runtimes
|
|
55
62
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
63
|
+
- Fluid Framework supports Node.js versions 22 and 24 while they receive [upstream support](https://nodejs.org/en/about/previous-releases).
|
|
64
|
+
- Fluid Framework will stop support for version 22 [when upstream support ends on 2027-04-30](https://github.com/nodejs/release#release-schedule).
|
|
65
|
+
- Fluid Framework does not support Node.js with the `--no-experimental-fetch` flag.
|
|
66
|
+
- Fluid Framework supports modern browsers that support the ES2022 standard library.
|
|
59
67
|
|
|
60
68
|
### Supported Tools
|
|
61
69
|
|
|
62
|
-
- TypeScript
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
- [
|
|
66
|
-
-
|
|
67
|
-
|
|
70
|
+
- [TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0):
|
|
71
|
+
- Fluid Framework supports all [`strict`](https://www.typescriptlang.org/tsconfig) options.
|
|
72
|
+
- Set the build targets (`lib`, `target`) to `ES2022` or later.
|
|
73
|
+
- Enable [`strictNullChecks`](https://www.typescriptlang.org/tsconfig).
|
|
74
|
+
- Fluid Framework does not support [configuration options deprecated in TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0#breaking-changes-and-deprecations-in-typescript-6-0).
|
|
75
|
+
- Fluid Framework does not fully support `exactOptionalPropertyTypes`.
|
|
76
|
+
If you enable this option, do not use `in`, `Reflect.has`, `Object.hasOwn`, or `Object.prototype.hasOwnProperty` to narrow members of Fluid Framework types.
|
|
77
|
+
These methods can incorrectly exclude `undefined` from the possible values.
|
|
68
78
|
- [webpack](https://webpack.js.org/) 5
|
|
69
|
-
- We
|
|
70
|
-
Other bundlers
|
|
79
|
+
- We do not require a specific bundler.
|
|
80
|
+
Other bundlers that handle ES Modules can work, but we actively test only webpack.
|
|
71
81
|
|
|
72
82
|
### Module Resolution
|
|
73
83
|
|
|
74
|
-
[`Node16`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution)
|
|
75
|
-
|
|
84
|
+
In TypeScript `compilerOptions`, use [`Node16`, `Node20`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) module resolution.
|
|
85
|
+
These settings follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
|
|
86
|
+
|
|
87
|
+
Do not use `Node10` module resolution.
|
|
76
88
|
|
|
77
89
|
### Module Formats
|
|
78
90
|
|
|
79
91
|
- ES Modules:
|
|
80
|
-
ES Modules
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
This is done to accommodate some workflows without good ES Module support.
|
|
84
|
-
If you have a workflow you would like included in this list, file an issue.
|
|
85
|
-
Once this list of workflows motivating CommonJS support is empty, we may drop support for CommonJS one year after notice of the change is posted here.
|
|
86
|
-
|
|
87
|
-
- Testing with Jest (which lacks [stable ESM support](https://jestjs.io/docs/ecmascript-modules) due to [unstable APIs in NodeJs](https://github.com/nodejs/node/issues/37648))
|
|
92
|
+
Use ES Modules to consume Fluid Framework client packages, including in Node.js.
|
|
93
|
+
- CommonJS:
|
|
94
|
+
Fluid Framework does not officially support CommonJS in version 3.0 or later.
|
|
88
95
|
|
|
89
96
|
## Contribution Guidelines
|
|
90
97
|
|
|
91
|
-
|
|
98
|
+
You can [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid Framework in these ways:
|
|
92
99
|
|
|
93
|
-
-
|
|
94
|
-
- [Submit
|
|
95
|
-
- Review
|
|
100
|
+
- Answer questions in [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
|
|
101
|
+
- [Submit bug reports](https://github.com/microsoft/FluidFramework/issues) and help verify fixes.
|
|
102
|
+
- Review [source code changes](https://github.com/microsoft/FluidFramework/pulls).
|
|
96
103
|
- [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
For detailed instructions, read the [repo documentation](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
|
|
99
106
|
|
|
100
|
-
This project
|
|
101
|
-
For more information
|
|
107
|
+
This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
108
|
+
For more information, read the [Code of Conduct frequently asked questions](https://opensource.microsoft.com/codeofconduct/faq/).
|
|
109
|
+
For questions or comments, contact [opencode@microsoft.com](mailto:opencode@microsoft.com).
|
|
102
110
|
|
|
103
111
|
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
104
112
|
Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
|
|
@@ -106,13 +114,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
|
|
|
106
114
|
|
|
107
115
|
## Help
|
|
108
116
|
|
|
109
|
-
|
|
110
|
-
Check out [fluidframework.com](https://fluidframework.com/docs/).
|
|
111
|
-
|
|
112
|
-
Still not finding what you're looking for?
|
|
113
|
-
Please [file an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
|
|
117
|
+
Read the [Fluid Framework documentation](https://fluidframework.com/docs/) for information about Fluid Framework concepts and APIs.
|
|
114
118
|
|
|
115
|
-
|
|
119
|
+
To request information that the documentation does not contain, [create an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
|
|
116
120
|
|
|
117
121
|
## Trademark
|
|
118
122
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
-
"extends": "
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-model.esm.json"
|
|
4
4
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-report-base.esm.json",
|
|
4
|
+
"mainEntryPointFilePath": "<projectFolder>/lib/index.d.ts"
|
|
5
|
+
}
|
package/dist/ink.js
CHANGED
|
@@ -97,6 +97,10 @@ class Ink extends internal_3.SharedObject {
|
|
|
97
97
|
static getFactory() {
|
|
98
98
|
return new inkFactory_js_1.InkFactory();
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* The current ink snapshot.
|
|
102
|
+
*/
|
|
103
|
+
inkData = new snapshot_js_1.InkData();
|
|
100
104
|
/**
|
|
101
105
|
* Create a new Ink.
|
|
102
106
|
* @param runtime - The runtime the Ink will be associated with
|
|
@@ -104,10 +108,6 @@ class Ink extends internal_3.SharedObject {
|
|
|
104
108
|
*/
|
|
105
109
|
constructor(runtime, id, attributes) {
|
|
106
110
|
super(id, runtime, attributes, "fluid_ink_");
|
|
107
|
-
/**
|
|
108
|
-
* The current ink snapshot.
|
|
109
|
-
*/
|
|
110
|
-
this.inkData = new snapshot_js_1.InkData();
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
113
|
* {@inheritDoc IInk.createStroke}
|
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 type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype IFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport type {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { type 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\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\t/**\n\t * Process an ink operation message.\n\t *\n\t * @param messageEnvelope - The message envelope.\n\t * @param messageContent - The runtime message content containing the contents, i.e., payload and the\n\t * local op metadata. For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be `undefined`.\n\t * @param local - Whether or not the message was sent by the local client.\n\t */\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation && !local) {\n\t\t\tconst operation = messageContent.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 type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype IFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport type {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { type 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\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\t/**\n\t * Process an ink operation message.\n\t *\n\t * @param messageEnvelope - The message envelope.\n\t * @param messageContent - The runtime message content containing the contents, i.e., payload and the\n\t * local op metadata. For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be `undefined`.\n\t * @param local - Whether or not the message was sent by the local client.\n\t */\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation && !local) {\n\t\t\tconst operation = messageContent.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.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.InkCanvas = void 0;
|
|
8
8
|
class Vector {
|
|
9
|
+
x;
|
|
10
|
+
y;
|
|
9
11
|
/**
|
|
10
12
|
* Returns the vector resulting from rotating vector by angle
|
|
11
13
|
*/
|
|
@@ -84,10 +86,14 @@ function drawShapes(context, startPoint, endPoint, pen) {
|
|
|
84
86
|
* @internal
|
|
85
87
|
*/
|
|
86
88
|
class InkCanvas {
|
|
89
|
+
canvas;
|
|
90
|
+
model;
|
|
91
|
+
context;
|
|
92
|
+
localActiveStrokeMap = new Map();
|
|
93
|
+
currentPen;
|
|
87
94
|
constructor(canvas, model) {
|
|
88
95
|
this.canvas = canvas;
|
|
89
96
|
this.model = model;
|
|
90
|
-
this.localActiveStrokeMap = new Map();
|
|
91
97
|
this.model.on("clear", this.redraw.bind(this));
|
|
92
98
|
this.model.on("stylus", this.handleStylus.bind(this));
|
|
93
99
|
this.canvas.style.touchAction = "none";
|
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 type {\n\tIColor,\n\tIInk,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.hypot(this.x, this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]): void {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number): void {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor): void {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear(): void {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore(): void {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent): void {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent): void {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number): void {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas(): void {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint): void {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation): void {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
|
|
1
|
+
{"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 type {\n\tIColor,\n\tIInk,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} 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.js
CHANGED
|
@@ -13,6 +13,21 @@ const packageVersion_js_1 = require("./packageVersion.js");
|
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
class InkFactory {
|
|
16
|
+
/**
|
|
17
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
18
|
+
*/
|
|
19
|
+
// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
|
|
20
|
+
// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
|
|
21
|
+
// public static Type = "ink";
|
|
22
|
+
static Type = "https://graph.microsoft.com/types/ink";
|
|
23
|
+
/**
|
|
24
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
25
|
+
*/
|
|
26
|
+
static Attributes = {
|
|
27
|
+
type: InkFactory.Type,
|
|
28
|
+
snapshotFormatVersion: "0.2",
|
|
29
|
+
packageVersion: packageVersion_js_1.pkgVersion,
|
|
30
|
+
};
|
|
16
31
|
/**
|
|
17
32
|
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
18
33
|
*/
|
|
@@ -43,19 +58,4 @@ class InkFactory {
|
|
|
43
58
|
}
|
|
44
59
|
}
|
|
45
60
|
exports.InkFactory = InkFactory;
|
|
46
|
-
/**
|
|
47
|
-
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
48
|
-
*/
|
|
49
|
-
// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
|
|
50
|
-
// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
|
|
51
|
-
// public static Type = "ink";
|
|
52
|
-
InkFactory.Type = "https://graph.microsoft.com/types/ink";
|
|
53
|
-
/**
|
|
54
|
-
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
55
|
-
*/
|
|
56
|
-
InkFactory.Attributes = {
|
|
57
|
-
type: InkFactory.Type,
|
|
58
|
-
snapshotFormatVersion: "0.2",
|
|
59
|
-
packageVersion: packageVersion_js_1.pkgVersion,
|
|
60
|
-
};
|
|
61
61
|
//# sourceMappingURL=inkFactory.js.map
|
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;
|
|
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;IACtB;;OAEG;IACH,uGAAuG;IACvG,qFAAqF;IACrF,8BAA8B;IACvB,MAAM,CAAC,IAAI,GAAG,uCAAuC,CAAC;IAE7D;;OAEG;IACI,MAAM,CAAU,UAAU,GAAuB;QACvD,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,8BAAU;KAC1B,CAAC;IAEF;;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;;AAvDF,gCAwDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type { 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\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"ink\";\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/packageVersion.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,4BAA4B,CAAC;AACjD,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,4BAA4B,CAAC;AACjD,eAAO,MAAM,UAAU,UAAU,CAAC"}
|
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 = "
|
|
11
|
+
exports.pkgVersion = "3.0.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,
|
|
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,OAAO,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 = \"3.0.0\";\n"]}
|
package/dist/snapshot.js
CHANGED
|
@@ -9,6 +9,14 @@ exports.InkData = void 0;
|
|
|
9
9
|
* Maintains a live record of the data that can be used for snapshotting.
|
|
10
10
|
*/
|
|
11
11
|
class InkData {
|
|
12
|
+
/**
|
|
13
|
+
* {@inheritDoc ISerializableInk.strokes}
|
|
14
|
+
*/
|
|
15
|
+
strokes;
|
|
16
|
+
/**
|
|
17
|
+
* {@inheritDoc ISerializableInk.strokeIndex}
|
|
18
|
+
*/
|
|
19
|
+
strokeIndex;
|
|
12
20
|
/**
|
|
13
21
|
* Construct a new InkData.
|
|
14
22
|
* @param snapshot - Existing data to initialize with
|
package/dist/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAoBH;;GAEG;AACH,MAAa,OAAO;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAoBH;;GAEG;AACH,MAAa,OAAO;IACnB;;OAEG;IACK,OAAO,CAAe;IAE9B;;OAEG;IACK,WAAW,CAA4B;IAE/C;;;OAGG;IACH,YAAY,QAA2B;QACtC,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE,WAAW,IAAI,EAAE,CAAC;IAChD,CAAC;IAED;;OAEG;IACI,UAAU;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACI,KAAK;QACX,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAkB;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACI,eAAe;QACrB,OAAO;YACN,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC;IACH,CAAC;CACD;AA7DD,0BA6DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IInkStroke } from \"./interfaces.js\";\n\n/**\n * Ink snapshot interface.\n */\nexport interface ISerializableInk {\n\t/**\n\t * Collection of ink strokes.\n\t */\n\tstrokes: IInkStroke[];\n\n\t/**\n\t * Stores a mapping from the provided key to its index in strokes. Since\n\t * ISerializableInk is serialized we need to use an index.\n\t */\n\tstrokeIndex: { [key: string]: number };\n}\n\n/**\n * Maintains a live record of the data that can be used for snapshotting.\n */\nexport class InkData {\n\t/**\n\t * {@inheritDoc ISerializableInk.strokes}\n\t */\n\tprivate strokes: IInkStroke[];\n\n\t/**\n\t * {@inheritDoc ISerializableInk.strokeIndex}\n\t */\n\tprivate strokeIndex: { [key: string]: number };\n\n\t/**\n\t * Construct a new InkData.\n\t * @param snapshot - Existing data to initialize with\n\t */\n\tconstructor(snapshot?: ISerializableInk) {\n\t\tthis.strokes = snapshot?.strokes ?? [];\n\t\tthis.strokeIndex = snapshot?.strokeIndex ?? {};\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.strokes;\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.strokes[this.strokeIndex[key]];\n\t}\n\n\t/**\n\t * Clear all stored data.\n\t */\n\tpublic clear(): void {\n\t\tthis.strokes = [];\n\t\tthis.strokeIndex = {};\n\t}\n\n\t/**\n\t * Add the given stroke to the stored data.\n\t * @param stroke - The stroke to add\n\t */\n\tpublic addStroke(stroke: IInkStroke): void {\n\t\tthis.strokes.push(stroke);\n\t\tthis.strokeIndex[stroke.id] = this.strokes.length - 1;\n\t}\n\n\t/**\n\t * Get a JSON-compatible representation of the stored data.\n\t * @returns The JSON-compatible object\n\t */\n\tpublic getSerializable(): ISerializableInk {\n\t\treturn {\n\t\t\tstrokes: this.strokes,\n\t\t\tstrokeIndex: this.strokeIndex,\n\t\t};\n\t}\n}\n"]}
|
package/lib/ink.js
CHANGED
|
@@ -94,6 +94,10 @@ export class Ink extends SharedObject {
|
|
|
94
94
|
static getFactory() {
|
|
95
95
|
return new InkFactory();
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* The current ink snapshot.
|
|
99
|
+
*/
|
|
100
|
+
inkData = new InkData();
|
|
97
101
|
/**
|
|
98
102
|
* Create a new Ink.
|
|
99
103
|
* @param runtime - The runtime the Ink will be associated with
|
|
@@ -101,10 +105,6 @@ export class Ink extends SharedObject {
|
|
|
101
105
|
*/
|
|
102
106
|
constructor(runtime, id, attributes) {
|
|
103
107
|
super(id, runtime, attributes, "fluid_ink_");
|
|
104
|
-
/**
|
|
105
|
-
* The current ink snapshot.
|
|
106
|
-
*/
|
|
107
|
-
this.inkData = new InkData();
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* {@inheritDoc IInk.createStroke}
|
package/lib/ink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ink.js","sourceRoot":"","sources":["../src/ink.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype IFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport type {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { type 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\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\t/**\n\t * Process an ink operation message.\n\t *\n\t * @param messageEnvelope - The message envelope.\n\t * @param messageContent - The runtime message content containing the contents, i.e., payload and the\n\t * local op metadata. For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be `undefined`.\n\t * @param local - Whether or not the message was sent by the local client.\n\t */\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation && !local) {\n\t\t\tconst operation = messageContent.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 type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\ttype IFluidSerializer,\n\tSharedObject,\n\tcreateSingleBlobSummary,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { InkFactory } from \"./inkFactory.js\";\nimport type {\n\tIClearOperation,\n\tICreateStrokeOperation,\n\tIInk,\n\tIInkEvents,\n\tIInkOperation,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\nimport { type 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\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\t/**\n\t * Process an ink operation message.\n\t *\n\t * @param messageEnvelope - The message envelope.\n\t * @param messageContent - The runtime message content containing the contents, i.e., payload and the\n\t * local op metadata. For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be `undefined`.\n\t * @param local - Whether or not the message was sent by the local client.\n\t */\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\tif (messageEnvelope.type === MessageType.Operation && !local) {\n\t\t\tconst operation = messageContent.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.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
class Vector {
|
|
6
|
+
x;
|
|
7
|
+
y;
|
|
6
8
|
/**
|
|
7
9
|
* Returns the vector resulting from rotating vector by angle
|
|
8
10
|
*/
|
|
@@ -81,10 +83,14 @@ function drawShapes(context, startPoint, endPoint, pen) {
|
|
|
81
83
|
* @internal
|
|
82
84
|
*/
|
|
83
85
|
export class InkCanvas {
|
|
86
|
+
canvas;
|
|
87
|
+
model;
|
|
88
|
+
context;
|
|
89
|
+
localActiveStrokeMap = new Map();
|
|
90
|
+
currentPen;
|
|
84
91
|
constructor(canvas, model) {
|
|
85
92
|
this.canvas = canvas;
|
|
86
93
|
this.model = model;
|
|
87
|
-
this.localActiveStrokeMap = new Map();
|
|
88
94
|
this.model.on("clear", this.redraw.bind(this));
|
|
89
95
|
this.model.on("stylus", this.handleStylus.bind(this));
|
|
90
96
|
this.canvas.style.touchAction = "none";
|
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 type {\n\tIColor,\n\tIInk,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} from \"./interfaces.js\";\n\ninterface IPoint {\n\tx: number;\n\ty: number;\n}\n\nclass Vector {\n\t/**\n\t * Returns the vector resulting from rotating vector by angle\n\t */\n\tpublic static rotate(vector: Vector, angle: number): Vector {\n\t\treturn new Vector(\n\t\t\tvector.x * Math.cos(angle) - vector.y * Math.sin(angle),\n\t\t\tvector.x * Math.sin(angle) + vector.y * Math.cos(angle),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the normalized form of the given vector\n\t */\n\tpublic static normalize(vector: Vector): Vector {\n\t\tconst length = vector.length();\n\t\treturn new Vector(vector.x / length, vector.y / length);\n\t}\n\n\tconstructor(\n\t\tpublic x: number,\n\t\tpublic y: number,\n\t) {}\n\n\tpublic length(): number {\n\t\treturn Math.hypot(this.x, this.y);\n\t}\n}\n\nfunction drawPolygon(context: CanvasRenderingContext2D, points: IPoint[]): void {\n\tif (points.length === 0) {\n\t\treturn;\n\t}\n\n\tcontext.beginPath();\n\t// Move to the first point\n\tcontext.moveTo(points[0].x, points[0].y);\n\n\t// Draw the rest of the segments\n\tfor (let i = 1; i < points.length; i++) {\n\t\tcontext.lineTo(points[i].x, points[i].y);\n\t}\n\n\t// And then close the shape\n\tcontext.lineTo(points[0].x, points[0].y);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawCircle(context: CanvasRenderingContext2D, center: IPoint, radius: number): void {\n\tcontext.beginPath();\n\tcontext.moveTo(center.x, center.y);\n\tcontext.arc(center.x, center.y, radius, 0, Math.PI * 2);\n\tcontext.closePath();\n\tcontext.fill();\n}\n\nfunction drawShapes(\n\tcontext: CanvasRenderingContext2D,\n\tstartPoint: IInkPoint,\n\tendPoint: IInkPoint,\n\tpen: IPen,\n): void {\n\tconst dirVector = new Vector(endPoint.x - startPoint.x, endPoint.y - startPoint.y);\n\tconst len = dirVector.length();\n\n\tconst widthAtStart = pen.thickness * startPoint.pressure;\n\tconst widthAtEnd = pen.thickness * endPoint.pressure;\n\n\tif (len + Math.min(widthAtStart, widthAtEnd) > Math.max(widthAtStart, widthAtEnd)) {\n\t\t// Circles don't completely overlap, need a trapezoid\n\t\tconst normalizedLateralVector = new Vector(-dirVector.y / len, dirVector.x / len);\n\n\t\tconst trapezoidP0 = {\n\t\t\tx: startPoint.x + widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y + widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP1 = {\n\t\t\tx: startPoint.x - widthAtStart * normalizedLateralVector.x,\n\t\t\ty: startPoint.y - widthAtStart * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP2 = {\n\t\t\tx: endPoint.x - widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y - widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\t\tconst trapezoidP3 = {\n\t\t\tx: endPoint.x + widthAtEnd * normalizedLateralVector.x,\n\t\t\ty: endPoint.y + widthAtEnd * normalizedLateralVector.y,\n\t\t};\n\n\t\tdrawPolygon(context, [trapezoidP0, trapezoidP1, trapezoidP2, trapezoidP3]);\n\t}\n\n\t// End circle\n\t// TODO should only draw if not eclipsed by the previous circle, be careful about single-point\n\tdrawCircle(context, { x: endPoint.x, y: endPoint.y }, widthAtEnd);\n}\n\n/**\n * @internal\n */\nexport class InkCanvas {\n\tprivate readonly context: CanvasRenderingContext2D;\n\tprivate readonly localActiveStrokeMap: Map<number, string> = new Map();\n\tprivate readonly currentPen: IPen;\n\n\tconstructor(\n\t\tprivate readonly canvas: HTMLCanvasElement,\n\t\tprivate readonly model: IInk,\n\t) {\n\t\tthis.model.on(\"clear\", this.redraw.bind(this));\n\t\tthis.model.on(\"stylus\", this.handleStylus.bind(this));\n\t\tthis.canvas.style.touchAction = \"none\";\n\n\t\tthis.canvas.addEventListener(\"pointerdown\", this.handlePointerDown.bind(this));\n\t\tthis.canvas.addEventListener(\"pointermove\", this.handlePointerMove.bind(this));\n\t\tthis.canvas.addEventListener(\"pointerup\", this.handlePointerUp.bind(this));\n\n\t\tconst context = this.canvas.getContext(\"2d\");\n\t\tif (context === null) {\n\t\t\tthrow new Error(\"InkCanvas requires a canvas with 2d rendering context\");\n\t\t}\n\t\tthis.context = context;\n\n\t\tthis.currentPen = {\n\t\t\tcolor: { r: 0, g: 161, b: 241, a: 0 },\n\t\t\tthickness: 7,\n\t\t};\n\n\t\tthis.sizeCanvasBackingStore();\n\t}\n\n\tpublic setPenColor(color: IColor): void {\n\t\tthis.currentPen.color = color;\n\t}\n\n\tpublic replay(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\n\t\t// Time of the first operation in stroke 0 is our starting time\n\t\tconst startTime = strokes[0].points[0].time;\n\t\tfor (const stroke of strokes) {\n\t\t\tthis.animateStroke(stroke, 0, startTime);\n\t\t}\n\t}\n\n\tpublic clear(): void {\n\t\tthis.model.clear();\n\t\tthis.redraw();\n\t}\n\n\tpublic sizeCanvasBackingStore(): void {\n\t\tconst canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t\t// Scale the canvas size to match the physical pixel to avoid blurriness\n\t\tconst scale = window.devicePixelRatio;\n\t\tthis.canvas.width = Math.floor(canvasBoundingClientRect.width * scale);\n\t\tthis.canvas.height = Math.floor(canvasBoundingClientRect.height * scale);\n\t\t// Scale the context to bring back coordinate system in CSS pixels\n\t\tthis.context.setTransform(1, 0, 0, 1, 0, 0);\n\t\tthis.context.scale(scale, scale);\n\n\t\tthis.redraw();\n\t}\n\n\tprivate handlePointerDown(evt: PointerEvent): void {\n\t\t// We will accept pen down or mouse left down as the start of a stroke.\n\t\tif (evt.pointerType === \"pen\" || (evt.pointerType === \"mouse\" && evt.button === 0)) {\n\t\t\tconst strokeId = this.model.createStroke(this.currentPen).id;\n\t\t\tthis.localActiveStrokeMap.set(evt.pointerId, strokeId);\n\n\t\t\tthis.appendPointerEventToStroke(evt);\n\n\t\t\tevt.preventDefault();\n\t\t}\n\t}\n\n\tprivate handlePointerMove(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\t\tconst evts = (evt as any)?.getCoalescedEvents() ?? ([evt] as PointerEvent[]);\n\t\t\tfor (const e of evts) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tthis.appendPointerEventToStroke(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePointerUp(evt: PointerEvent): void {\n\t\tif (this.localActiveStrokeMap.has(evt.pointerId)) {\n\t\t\tthis.appendPointerEventToStroke(evt);\n\t\t\tthis.localActiveStrokeMap.delete(evt.pointerId);\n\t\t}\n\t}\n\n\tprivate appendPointerEventToStroke(evt: PointerEvent): void {\n\t\tconst strokeId = this.localActiveStrokeMap.get(evt.pointerId);\n\t\tif (strokeId === undefined) {\n\t\t\tthrow new Error(\"Unexpected pointer ID trying to append to stroke\");\n\t\t}\n\t\tconst inkPt = {\n\t\t\tx: evt.offsetX,\n\t\t\ty: evt.offsetY,\n\t\t\ttime: Date.now(),\n\t\t\tpressure: evt.pressure,\n\t\t};\n\t\tthis.model.appendPointToStroke(inkPt, strokeId);\n\t}\n\n\tprivate animateStroke(stroke: IInkStroke, operationIndex: number, startTime: number): void {\n\t\tif (operationIndex >= stroke.points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Draw the requested stroke\n\t\tconst current = stroke.points[operationIndex];\n\t\tconst previous = stroke.points[Math.max(0, operationIndex - 1)];\n\t\tconst time =\n\t\t\toperationIndex === 0 ? current.time - startTime : current.time - previous.time;\n\n\t\tsetTimeout(() => {\n\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\tthis.animateStroke(stroke, operationIndex + 1, startTime);\n\t\t}, time);\n\t}\n\n\t/**\n\t * Clears the canvas\n\t */\n\tprivate clearCanvas(): void {\n\t\tthis.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\t}\n\n\tprivate redraw(): void {\n\t\tthis.clearCanvas();\n\n\t\tconst strokes = this.model.getStrokes();\n\t\tfor (const stroke of strokes) {\n\t\t\tlet previous = stroke.points[0];\n\t\t\tfor (const current of stroke.points) {\n\t\t\t\t// For the down, current === previous === stroke.operations[0]\n\t\t\t\tthis.drawStrokeSegment(stroke.pen, current, previous);\n\t\t\t\tprevious = current;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate drawStrokeSegment(pen: IPen, current: IInkPoint, previous: IInkPoint): void {\n\t\t// TODO Consider save/restore context\n\t\t// TODO Consider half-pixel offset\n\t\tthis.context.fillStyle = `rgb(${pen.color.r}, ${pen.color.g}, ${pen.color.b})`;\n\t\tdrawShapes(this.context, previous, current, pen);\n\t}\n\n\tprivate handleStylus(operation: IStylusOperation): void {\n\t\t// Render the dirty stroke\n\t\tconst dirtyStrokeId = operation.id;\n\t\tconst stroke = this.model.getStroke(dirtyStrokeId);\n\t\t// If this is the only point in the stroke, we'll use it for both the start and end of the segment\n\t\tconst prevPoint =\n\t\t\tstroke.points[stroke.points.length - (stroke.points.length >= 2 ? 2 : 1)];\n\t\tthis.drawStrokeSegment(stroke.pen, prevPoint, operation.point);\n\t}\n}\n"]}
|
|
1
|
+
{"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 type {\n\tIColor,\n\tIInk,\n\tIInkPoint,\n\tIInkStroke,\n\tIPen,\n\tIStylusOperation,\n} 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.js
CHANGED
|
@@ -10,6 +10,21 @@ import { pkgVersion } from "./packageVersion.js";
|
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
12
|
export class InkFactory {
|
|
13
|
+
/**
|
|
14
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
15
|
+
*/
|
|
16
|
+
// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
|
|
17
|
+
// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
|
|
18
|
+
// public static Type = "ink";
|
|
19
|
+
static Type = "https://graph.microsoft.com/types/ink";
|
|
20
|
+
/**
|
|
21
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
22
|
+
*/
|
|
23
|
+
static Attributes = {
|
|
24
|
+
type: InkFactory.Type,
|
|
25
|
+
snapshotFormatVersion: "0.2",
|
|
26
|
+
packageVersion: pkgVersion,
|
|
27
|
+
};
|
|
13
28
|
/**
|
|
14
29
|
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
15
30
|
*/
|
|
@@ -39,19 +54,4 @@ export class InkFactory {
|
|
|
39
54
|
return ink;
|
|
40
55
|
}
|
|
41
56
|
}
|
|
42
|
-
/**
|
|
43
|
-
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
|
|
44
|
-
*/
|
|
45
|
-
// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.
|
|
46
|
-
// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.
|
|
47
|
-
// public static Type = "ink";
|
|
48
|
-
InkFactory.Type = "https://graph.microsoft.com/types/ink";
|
|
49
|
-
/**
|
|
50
|
-
* {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
|
|
51
|
-
*/
|
|
52
|
-
InkFactory.Attributes = {
|
|
53
|
-
type: InkFactory.Type,
|
|
54
|
-
snapshotFormatVersion: "0.2",
|
|
55
|
-
packageVersion: pkgVersion,
|
|
56
|
-
};
|
|
57
57
|
//# sourceMappingURL=inkFactory.js.map
|
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;
|
|
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;IACtB;;OAEG;IACH,uGAAuG;IACvG,qFAAqF;IACrF,8BAA8B;IACvB,MAAM,CAAC,IAAI,GAAG,uCAAuC,CAAC;IAE7D;;OAEG;IACI,MAAM,CAAU,UAAU,GAAuB;QACvD,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,UAAU;KAC1B,CAAC;IAEF;;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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type { 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\t// New type string, to be activated once the migration has been fully shipped dark and is safe to flip.\n\t// See LegacyTypeAwareRegistry in packages/runtime/datastore/src/dataStoreRuntime.ts.\n\t// public static Type = \"ink\";\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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,4BAA4B,CAAC;AACjD,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,4BAA4B,CAAC;AACjD,eAAO,MAAM,UAAU,UAAU,CAAC"}
|
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,
|
|
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,OAAO,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 = \"3.0.0\";\n"]}
|
package/lib/snapshot.js
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
* Maintains a live record of the data that can be used for snapshotting.
|
|
7
7
|
*/
|
|
8
8
|
export class InkData {
|
|
9
|
+
/**
|
|
10
|
+
* {@inheritDoc ISerializableInk.strokes}
|
|
11
|
+
*/
|
|
12
|
+
strokes;
|
|
13
|
+
/**
|
|
14
|
+
* {@inheritDoc ISerializableInk.strokeIndex}
|
|
15
|
+
*/
|
|
16
|
+
strokeIndex;
|
|
9
17
|
/**
|
|
10
18
|
* Construct a new InkData.
|
|
11
19
|
* @param snapshot - Existing data to initialize with
|
package/lib/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH;;GAEG;AACH,MAAM,OAAO,OAAO;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH;;GAEG;AACH,MAAM,OAAO,OAAO;IACnB;;OAEG;IACK,OAAO,CAAe;IAE9B;;OAEG;IACK,WAAW,CAA4B;IAE/C;;;OAGG;IACH,YAAY,QAA2B;QACtC,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE,WAAW,IAAI,EAAE,CAAC;IAChD,CAAC;IAED;;OAEG;IACI,UAAU;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACI,KAAK;QACX,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAkB;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACI,eAAe;QACrB,OAAO;YACN,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC;IACH,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IInkStroke } from \"./interfaces.js\";\n\n/**\n * Ink snapshot interface.\n */\nexport interface ISerializableInk {\n\t/**\n\t * Collection of ink strokes.\n\t */\n\tstrokes: IInkStroke[];\n\n\t/**\n\t * Stores a mapping from the provided key to its index in strokes. Since\n\t * ISerializableInk is serialized we need to use an index.\n\t */\n\tstrokeIndex: { [key: string]: number };\n}\n\n/**\n * Maintains a live record of the data that can be used for snapshotting.\n */\nexport class InkData {\n\t/**\n\t * {@inheritDoc ISerializableInk.strokes}\n\t */\n\tprivate strokes: IInkStroke[];\n\n\t/**\n\t * {@inheritDoc ISerializableInk.strokeIndex}\n\t */\n\tprivate strokeIndex: { [key: string]: number };\n\n\t/**\n\t * Construct a new InkData.\n\t * @param snapshot - Existing data to initialize with\n\t */\n\tconstructor(snapshot?: ISerializableInk) {\n\t\tthis.strokes = snapshot?.strokes ?? [];\n\t\tthis.strokeIndex = snapshot?.strokeIndex ?? {};\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStrokes}\n\t */\n\tpublic getStrokes(): IInkStroke[] {\n\t\treturn this.strokes;\n\t}\n\n\t/**\n\t * {@inheritDoc IInk.getStroke}\n\t */\n\tpublic getStroke(key: string): IInkStroke {\n\t\treturn this.strokes[this.strokeIndex[key]];\n\t}\n\n\t/**\n\t * Clear all stored data.\n\t */\n\tpublic clear(): void {\n\t\tthis.strokes = [];\n\t\tthis.strokeIndex = {};\n\t}\n\n\t/**\n\t * Add the given stroke to the stored data.\n\t * @param stroke - The stroke to add\n\t */\n\tpublic addStroke(stroke: IInkStroke): void {\n\t\tthis.strokes.push(stroke);\n\t\tthis.strokeIndex[stroke.id] = this.strokes.length - 1;\n\t}\n\n\t/**\n\t * Get a JSON-compatible representation of the stored data.\n\t * @returns The JSON-compatible object\n\t */\n\tpublic getSerializable(): ISerializableInk {\n\t\treturn {\n\t\t\tstrokes: this.strokes,\n\t\t\tstrokeIndex: this.strokeIndex,\n\t\t};\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-experimental/ink",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Ink DDS",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -14,18 +14,10 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
"default": "./lib/index.js"
|
|
20
|
-
},
|
|
21
|
-
"require": {
|
|
22
|
-
"types": "./dist/index.d.ts",
|
|
23
|
-
"default": "./dist/index.js"
|
|
24
|
-
}
|
|
17
|
+
"types": "./lib/index.d.ts",
|
|
18
|
+
"default": "./lib/index.js"
|
|
25
19
|
}
|
|
26
20
|
},
|
|
27
|
-
"main": "lib/index.js",
|
|
28
|
-
"types": "lib/index.d.ts",
|
|
29
21
|
"c8": {
|
|
30
22
|
"all": true,
|
|
31
23
|
"cache-dir": "nyc/.cache",
|
|
@@ -49,24 +41,24 @@
|
|
|
49
41
|
"temp-directory": "nyc/.nyc_output"
|
|
50
42
|
},
|
|
51
43
|
"dependencies": {
|
|
52
|
-
"@fluidframework/core-interfaces": "~
|
|
53
|
-
"@fluidframework/datastore-definitions": "~
|
|
54
|
-
"@fluidframework/driver-definitions": "~
|
|
55
|
-
"@fluidframework/driver-utils": "~
|
|
56
|
-
"@fluidframework/runtime-definitions": "~
|
|
57
|
-
"@fluidframework/shared-object-base": "~
|
|
44
|
+
"@fluidframework/core-interfaces": "~3.0.0",
|
|
45
|
+
"@fluidframework/datastore-definitions": "~3.0.0",
|
|
46
|
+
"@fluidframework/driver-definitions": "~3.0.0",
|
|
47
|
+
"@fluidframework/driver-utils": "~3.0.0",
|
|
48
|
+
"@fluidframework/runtime-definitions": "~3.0.0",
|
|
49
|
+
"@fluidframework/shared-object-base": "~3.0.0",
|
|
58
50
|
"uuid": "^11.1.0"
|
|
59
51
|
},
|
|
60
52
|
"devDependencies": {
|
|
61
53
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
62
54
|
"@biomejs/biome": "~2.4.5",
|
|
63
|
-
"@fluid-internal/mocha-test-setup": "~
|
|
55
|
+
"@fluid-internal/mocha-test-setup": "~3.0.0",
|
|
64
56
|
"@fluid-tools/build-cli": "^0.67.0",
|
|
65
57
|
"@fluidframework/build-common": "^2.0.3",
|
|
66
58
|
"@fluidframework/build-tools": "^0.67.0",
|
|
67
|
-
"@fluidframework/container-definitions": "~
|
|
59
|
+
"@fluidframework/container-definitions": "~3.0.0",
|
|
68
60
|
"@fluidframework/eslint-config-fluid": "^14.0.0",
|
|
69
|
-
"@fluidframework/test-runtime-utils": "~
|
|
61
|
+
"@fluidframework/test-runtime-utils": "~3.0.0",
|
|
70
62
|
"@microsoft/api-extractor": "7.58.1",
|
|
71
63
|
"@types/mocha": "^10.0.10",
|
|
72
64
|
"@types/node": "~22.19.17",
|
|
@@ -79,29 +71,32 @@
|
|
|
79
71
|
"mocha": "^11.7.5",
|
|
80
72
|
"mocha-multi-reporters": "^1.5.1",
|
|
81
73
|
"rimraf": "^6.1.3",
|
|
82
|
-
"typescript": "~
|
|
74
|
+
"typescript": "~6.0.3"
|
|
83
75
|
},
|
|
84
76
|
"typeValidation": {
|
|
85
77
|
"disabled": true
|
|
86
78
|
},
|
|
87
79
|
"scripts": {
|
|
88
80
|
"build": "fluid-build . --task build",
|
|
81
|
+
"build:api-reports": "api-extractor run --local --config api-extractor/api-extractor-report.json",
|
|
82
|
+
"build:cjs": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
|
|
89
83
|
"build:commonjs": "fluid-build . --task commonjs",
|
|
90
84
|
"build:compile": "fluid-build . --task compile",
|
|
91
|
-
"build:docs": "api-extractor run --local",
|
|
92
|
-
"build:
|
|
85
|
+
"build:docs": "api-extractor run --local --config api-extractor/api-extractor-model.json",
|
|
86
|
+
"build:esm": "tsc --project ./tsconfig.json",
|
|
93
87
|
"build:genver": "gen-version",
|
|
94
88
|
"build:test": "concurrently npm:build:test:esm npm:build:test:cjs",
|
|
95
89
|
"build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
|
|
96
90
|
"build:test:esm": "tsc --project ./src/test/tsconfig.json",
|
|
97
|
-
"check:are-the-types-wrong": "attw --pack .",
|
|
91
|
+
"check:are-the-types-wrong": "attw --pack . --profile esm-only",
|
|
98
92
|
"check:biome": "biome check .",
|
|
99
93
|
"check:exports": "concurrently \"npm:check:exports:*\"",
|
|
100
94
|
"check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
|
|
101
95
|
"check:exports:cjs:index": "api-extractor run --config api-extractor/api-extractor-lint-index.cjs.json",
|
|
102
96
|
"check:exports:esm:index": "api-extractor run --config api-extractor/api-extractor-lint-index.esm.json",
|
|
103
97
|
"check:format": "npm run check:biome",
|
|
104
|
-
"ci:build:
|
|
98
|
+
"ci:build:api-reports": "api-extractor run --config api-extractor/api-extractor-report.json",
|
|
99
|
+
"ci:build:docs": "api-extractor run --config api-extractor/api-extractor-model.json",
|
|
105
100
|
"clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
|
|
106
101
|
"eslint": "eslint --quiet --format stylish src",
|
|
107
102
|
"eslint:fix": "eslint --quiet --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
@@ -114,7 +109,6 @@
|
|
|
114
109
|
"test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
|
|
115
110
|
"test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS mocha",
|
|
116
111
|
"test:mocha:esm": "mocha",
|
|
117
|
-
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha"
|
|
118
|
-
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist"
|
|
112
|
+
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha"
|
|
119
113
|
}
|
|
120
114
|
}
|
package/src/packageVersion.ts
CHANGED
package/tsconfig.json
CHANGED