mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
Merge pull request #351 from idrawjs/dev-v0.4
refactor: refactor @idraw/renderer and migrate @idraw/board to @idraw/core
This commit is contained in:
commit
342948b9a5
75 changed files with 3615 additions and 6284 deletions
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
|
|
@ -31,9 +31,6 @@ jobs:
|
|||
- run: npm publish --provenance --access public -w ./packages/renderer
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
- run: npm publish --provenance --access public -w ./packages/board
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
- run: npm publish --provenance --access public -w ./packages/core
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
|
|
|||
60
package.json
60
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"private": false,
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
|
|
@ -30,47 +30,47 @@
|
|||
"upgrade:version": "npm run version:reset && pnpm i"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.3",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@babel/core": "^7.26.10",
|
||||
"@babel/preset-env": "^7.26.9",
|
||||
"@babel/preset-typescript": "^7.27.0",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@types/glob": "^8.1.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/koa-compose": "^3.2.8",
|
||||
"@types/node": "^22.1.0",
|
||||
"@types/node": "^22.14.1",
|
||||
"@types/serve-handler": "^6.1.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.29.1",
|
||||
"@typescript-eslint/parser": "^8.29.1",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"babel-jest": "^29.7.0",
|
||||
"chalk": "^5.3.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"chalk": "^5.4.1",
|
||||
"dotenv": "^16.5.0",
|
||||
"enquirer": "^2.4.1",
|
||||
"esbuild": "^0.23.0",
|
||||
"eslint": "^9.8.0",
|
||||
"execa": "^9.3.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"glob": "^11.0.0",
|
||||
"esbuild": "^0.25.2",
|
||||
"eslint": "^9.24.0",
|
||||
"execa": "^9.5.2",
|
||||
"fs-extra": "^11.3.0",
|
||||
"glob": "^11.0.1",
|
||||
"http-server": "^14.1.1",
|
||||
"husky": "^9.1.4",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.7.0",
|
||||
"jest-canvas-mock": "^2.5.2",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jimp": "^0.22.12",
|
||||
"jimp": "^1.6.0",
|
||||
"koa-compose": "^4.1.0",
|
||||
"less": "^4.2.0",
|
||||
"pixelmatch": "^6.0.0",
|
||||
"less": "^4.3.0",
|
||||
"pixelmatch": "^7.1.0",
|
||||
"pngjs": "^7.0.0",
|
||||
"puppeteer": "^22.6.4",
|
||||
"rollup": "^4.20.0",
|
||||
"rollup-plugin-dts": "^6.1.1",
|
||||
"rollup-plugin-esbuild": "^6.1.1",
|
||||
"serve-handler": "^6.1.5",
|
||||
"terser": "^5.31.3",
|
||||
"ts-morph": "^23.0.0",
|
||||
"puppeteer": "^24.6.1",
|
||||
"rollup": "^4.40.0",
|
||||
"rollup-plugin-dts": "^6.2.1",
|
||||
"rollup-plugin-esbuild": "^6.2.1",
|
||||
"serve-handler": "^6.1.6",
|
||||
"terser": "^5.39.0",
|
||||
"ts-morph": "^25.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.3.5"
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.2.6"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# @idraw/board
|
||||
|
||||
[](https://github.com/idrawjs/idraw/actions/workflows/node.js.yml)
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board context 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board context 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 3600,
|
||||
"dWidth": 4000,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="3600"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 3600,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 3600,
|
||||
"dWidth": 4000,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="3600"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 3600,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board getTransform 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board getTransform 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -1,785 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board scale 001 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 001 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 3600,
|
||||
"dWidth": 4000,
|
||||
"dx": 200,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="3600"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 3600,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 3600,
|
||||
"dWidth": 4000,
|
||||
"dx": 200,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="3600"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 3600,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 002 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 002 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 2400,
|
||||
"dWidth": 4800,
|
||||
"dx": 0,
|
||||
"dy": 200,
|
||||
"img": <canvas
|
||||
height="2400"
|
||||
width="4800"
|
||||
/>,
|
||||
"sHeight": 2400,
|
||||
"sWidth": 4800,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 2400,
|
||||
"dWidth": 4800,
|
||||
"dx": 0,
|
||||
"dy": 200,
|
||||
"img": <canvas
|
||||
height="2400"
|
||||
width="4800"
|
||||
/>,
|
||||
"sHeight": 2400,
|
||||
"sWidth": 4800,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 003 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 003 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 2400,
|
||||
"dWidth": 4000,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="2400"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 2400,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 2400,
|
||||
"dWidth": 4000,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="2400"
|
||||
width="4000"
|
||||
/>,
|
||||
"sHeight": 2400,
|
||||
"sWidth": 4000,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scale 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": 600,
|
||||
"dy": 400,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": 600,
|
||||
"dy": 400,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board scroll 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scroll 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -1,737 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board scroll 1`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 40,
|
||||
"y": 40,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 320,
|
||||
"y": 320,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 480,
|
||||
"width": 800,
|
||||
"x": 640,
|
||||
"y": 640,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 400,
|
||||
"width": 800,
|
||||
"x": 1560,
|
||||
"y": 1160,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/board scroll 2`] = `
|
||||
[
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": -2400,
|
||||
"dy": -1600,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 80,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 1520,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"fillRule": "nonzero",
|
||||
"path": [
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "beginPath",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"x": 2220,
|
||||
"y": 1541,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "moveTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2400,
|
||||
"cpx2": 2400,
|
||||
"cpy1": 1541,
|
||||
"cpy2": 1581,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2400,
|
||||
"cpx2": 2200,
|
||||
"cpy1": 1581,
|
||||
"cpy2": 1581,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2200,
|
||||
"cpx2": 2200,
|
||||
"cpy1": 1581,
|
||||
"cpy2": 1541,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2200,
|
||||
"cpx2": 2400,
|
||||
"cpy1": 1541,
|
||||
"cpy2": 1541,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "closePath",
|
||||
},
|
||||
],
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fill",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"path": [
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "beginPath",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"x": 2220,
|
||||
"y": 1541,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "moveTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2400,
|
||||
"cpx2": 2400,
|
||||
"cpy1": 1541,
|
||||
"cpy2": 1581,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2400,
|
||||
"cpx2": 2200,
|
||||
"cpy1": 1581,
|
||||
"cpy2": 1581,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2200,
|
||||
"cpx2": 2200,
|
||||
"cpy1": 1581,
|
||||
"cpy2": 1541,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2200,
|
||||
"cpx2": 2400,
|
||||
"cpy1": 1541,
|
||||
"cpy2": 1541,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "closePath",
|
||||
},
|
||||
],
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "stroke",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"height": 1600,
|
||||
"width": 80,
|
||||
"x": 2320,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fillRect",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"fillRule": "nonzero",
|
||||
"path": [
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "beginPath",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"x": 2361,
|
||||
"y": 1400,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "moveTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2381,
|
||||
"cpx2": 2381,
|
||||
"cpy1": 1400,
|
||||
"cpy2": 1600,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2381,
|
||||
"cpx2": 2341,
|
||||
"cpy1": 1600,
|
||||
"cpy2": 1600,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2341,
|
||||
"cpx2": 2341,
|
||||
"cpy1": 1600,
|
||||
"cpy2": 1400,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2341,
|
||||
"cpx2": 2381,
|
||||
"cpy1": 1400,
|
||||
"cpy2": 1400,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "closePath",
|
||||
},
|
||||
],
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "fill",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"path": [
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "beginPath",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"x": 2361,
|
||||
"y": 1400,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "moveTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2381,
|
||||
"cpx2": 2381,
|
||||
"cpy1": 1400,
|
||||
"cpy2": 1600,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2381,
|
||||
"cpx2": 2341,
|
||||
"cpy1": 1600,
|
||||
"cpy2": 1600,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2341,
|
||||
"cpx2": 2341,
|
||||
"cpy1": 1600,
|
||||
"cpy2": 1400,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {
|
||||
"cpx1": 2341,
|
||||
"cpx2": 2381,
|
||||
"cpy1": 1400,
|
||||
"cpy2": 1400,
|
||||
"radius": 20,
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "arcTo",
|
||||
},
|
||||
{
|
||||
"props": {},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "closePath",
|
||||
},
|
||||
],
|
||||
},
|
||||
"transform": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "stroke",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
export function getData() {
|
||||
const data = {
|
||||
elements: [
|
||||
{
|
||||
x: 10,
|
||||
y: 10,
|
||||
w: 200,
|
||||
h: 120,
|
||||
type: 'rect',
|
||||
detail: {
|
||||
color: '#f0f0f0'
|
||||
}
|
||||
},
|
||||
{
|
||||
x: 80,
|
||||
y: 80,
|
||||
w: 200,
|
||||
h: 120,
|
||||
type: 'rect',
|
||||
detail: {
|
||||
color: '#cccccc'
|
||||
}
|
||||
},
|
||||
{
|
||||
x: 160,
|
||||
y: 160,
|
||||
w: 200,
|
||||
h: 120,
|
||||
type: 'rect',
|
||||
detail: {
|
||||
color: '#c0c0c0'
|
||||
}
|
||||
},
|
||||
{
|
||||
x: 400 - 10,
|
||||
y: 300 - 10,
|
||||
w: 200,
|
||||
h: 100,
|
||||
type: 'rect',
|
||||
detail: {
|
||||
color: '#e0e0e0'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
import Board from './../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
test('context', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 1000,
|
||||
contextHeight: 900,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/board: src/lib/style getStyle 1`] = `
|
||||
{
|
||||
"height": "20px",
|
||||
"margin-top": "123px",
|
||||
"overflow": "auto",
|
||||
"width": "12px",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`@idraw/board: src/lib/style setDomTransform 1`] = `
|
||||
<div
|
||||
style="transform: matrix(1, 2, -1, 1, 80, 90);"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`@idraw/board: src/lib/style setStyle 1`] = `
|
||||
<div
|
||||
style="width:12px;height:20px;overflow:auto;margin-top:123px;"
|
||||
/>
|
||||
`;
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
import { TypePoint } from '@idraw/types';
|
||||
import { BoardEvent } from './../../src/lib/event';
|
||||
|
||||
describe('@idraw/board: src/lib/event', () => {
|
||||
|
||||
// 'doubleClick': TypePoint;
|
||||
// 'hover': TypePoint;
|
||||
// 'leave': void;
|
||||
// 'point': TypePoint;
|
||||
// 'move': TypePoint;
|
||||
// 'moveStart': TypePoint;
|
||||
// 'moveEnd': TypePoint;
|
||||
// 'wheelX': number;
|
||||
// 'wheelY': number;
|
||||
|
||||
test('BoardEvent event:off', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
const callback = (p: TypePoint) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
}
|
||||
event.on('doubleClick', callback);
|
||||
event.trigger('doubleClick', point)
|
||||
event.off('doubleClick', callback);
|
||||
});
|
||||
|
||||
test('BoardEvent event:doubleClick', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('doubleClick', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('doubleClick', point)
|
||||
});
|
||||
|
||||
test('BoardEvent event:hover', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('hover', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('hover', point)
|
||||
});
|
||||
|
||||
test('BoardEvent event:leave', async () => {
|
||||
const event = new BoardEvent();
|
||||
event.on('leave', (e) => {
|
||||
expect(e).toStrictEqual(undefined);
|
||||
});
|
||||
event.trigger('leave', undefined)
|
||||
});
|
||||
|
||||
test('BoardEvent event:point', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('point', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('point', point)
|
||||
});
|
||||
|
||||
test('BoardEvent event:move', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('move', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('move', point)
|
||||
});
|
||||
|
||||
|
||||
test('BoardEvent event:moveStart', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('moveStart', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('moveStart', point)
|
||||
});
|
||||
|
||||
test('BoardEvent event:moveEnd', async () => {
|
||||
const event = new BoardEvent();
|
||||
const point = { x: 123, y: 456 }
|
||||
event.on('moveEnd', (p) => {
|
||||
expect(p).toStrictEqual(point);
|
||||
});
|
||||
event.trigger('moveEnd', point)
|
||||
});
|
||||
|
||||
test('BoardEvent event:wheelX', async () => {
|
||||
const event = new BoardEvent();
|
||||
const num = 123
|
||||
event.on('wheelX', (e) => {
|
||||
expect(e).toStrictEqual(num);
|
||||
});
|
||||
event.trigger('wheelX', num)
|
||||
});
|
||||
|
||||
test('BoardEvent event:wheelY', async () => {
|
||||
const event = new BoardEvent();
|
||||
const num = 123
|
||||
event.on('wheelY', (e) => {
|
||||
expect(e).toStrictEqual(num);
|
||||
});
|
||||
event.trigger('wheelY', num)
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
import {
|
||||
mergeCSS2StyleAttr, setStyle, getStyle, getDomTransform,
|
||||
setDomTransform,
|
||||
} from './../../src/lib/style';
|
||||
|
||||
|
||||
describe('@idraw/board: src/lib/style', () => {
|
||||
test('mergeCSS2StyleAttr', () => {
|
||||
const str = mergeCSS2StyleAttr({
|
||||
'width': '12px',
|
||||
'height': '20px',
|
||||
'overflow': 'auto',
|
||||
'margin-top': '123px',
|
||||
});
|
||||
expect(str).toStrictEqual('width:12px; height:20px; overflow:auto; margin-top:123px;');
|
||||
});
|
||||
|
||||
test('setStyle', () => {
|
||||
const div = document.createElement('div');
|
||||
setStyle(div, {
|
||||
'width': '12px',
|
||||
'height': '20px',
|
||||
'overflow': 'auto',
|
||||
'margin-top': '123px',
|
||||
});
|
||||
expect(div).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('getStyle', () => {
|
||||
const div = document.createElement('div');
|
||||
setStyle(div, {
|
||||
'width': '12px',
|
||||
'height': '20px',
|
||||
'overflow': 'auto',
|
||||
'margin-top': '123px',
|
||||
});
|
||||
expect(getStyle(div)).toMatchSnapshot({
|
||||
'width': '12px',
|
||||
'height': '20px',
|
||||
'overflow': 'auto',
|
||||
'margin-top': '123px',
|
||||
});
|
||||
});
|
||||
|
||||
test('setDomTransform', () => {
|
||||
// transform: matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
|
||||
// matrix(1, 2, -1, 1, 80, 80)
|
||||
const div = document.createElement('div');
|
||||
setDomTransform(div, {
|
||||
scaleX: 1,
|
||||
skewY: 2,
|
||||
skewX: -1,
|
||||
scaleY: 1,
|
||||
translateX: 80,
|
||||
translateY: 90,
|
||||
});
|
||||
expect(div).toMatchSnapshot();
|
||||
})
|
||||
|
||||
test('getDomTransform', () => {
|
||||
// transform: matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
|
||||
// matrix(1, 2, -1, 1, 80, 80)
|
||||
const div = document.createElement('div');
|
||||
setDomTransform(div, {
|
||||
scaleX: 1,
|
||||
skewY: 2,
|
||||
skewX: -1,
|
||||
scaleY: 1,
|
||||
translateX: 80,
|
||||
translateY: 90,
|
||||
});
|
||||
expect(getDomTransform(div)).toStrictEqual({
|
||||
scaleX: 1,
|
||||
skewY: 2,
|
||||
skewX: -1,
|
||||
scaleY: 1,
|
||||
translateX: 80,
|
||||
translateY: 90,
|
||||
});
|
||||
})
|
||||
})
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
import Board from '../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
test('getTransform', async () => {
|
||||
const resultScale = board.scale(2);
|
||||
expect(resultScale).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: 0, right: -600 },
|
||||
size: { x: 0, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultX = board.scrollX(-600);
|
||||
expect(resultX).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: -600, right: 0 },
|
||||
size: { x: -1200, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultY = board.scrollY(-400);
|
||||
expect(resultY).toStrictEqual({
|
||||
position: { top: -400, bottom: 0, left: -600, right: 0 },
|
||||
size: { x: -1200, y: -800, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
|
||||
const transform = board.getTransform();
|
||||
expect(transform).toStrictEqual({ scale: 2, scrollX: -600, scrollY: -400 });
|
||||
});
|
||||
});
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import Board from '../src';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4,
|
||||
canScroll: true
|
||||
};
|
||||
const transform = {
|
||||
scale: 2,
|
||||
scrollX: -200,
|
||||
scrollY: -100
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
board.scale(transform.scale);
|
||||
board.scrollX(transform.scrollX);
|
||||
board.scrollY(transform.scrollY);
|
||||
board.draw();
|
||||
|
||||
const p1 = { x: 400, y: 300 };
|
||||
const p2 = { x: 300, y: 200 };
|
||||
|
||||
test('pointScreenToContext', async () => {
|
||||
expect(board.pointScreenToContext(p1)).toStrictEqual(p2);
|
||||
});
|
||||
|
||||
test('pointContextToScreen', async () => {
|
||||
expect(board.pointContextToScreen(p2)).toStrictEqual(p1);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
import Board from '../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
test('scale', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
const result = board.scale(0.5);
|
||||
expect(result).toStrictEqual({
|
||||
position: { top: 100, bottom: 100, left: 150, right: 150 },
|
||||
size: { x: 75, y: 50, w: 300, h: 200 }
|
||||
});
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('scale 001', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount-001"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 1000,
|
||||
contextHeight: 900,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount-001') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
const result = board.scale(0.5);
|
||||
expect(result).toStrictEqual({
|
||||
position: { top: 0, bottom: -50, left: 50, right: 50 },
|
||||
size: { x: 25, y: 0, w: 500, h: 450 }
|
||||
});
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('scale 002', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount-002"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 1200,
|
||||
contextHeight: 600,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount-002') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
board.scrollX(-600);
|
||||
board.scrollY(-400);
|
||||
const result = board.scale(0.5);
|
||||
expect(result).toStrictEqual({
|
||||
position: { top: 50, bottom: 50, left: 0, right: 0 },
|
||||
size: { x: 0, y: 25, w: 600, h: 300 }
|
||||
});
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('scale 003', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount-003"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 1000,
|
||||
contextHeight: 600,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount-003') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
board.scrollX(400);
|
||||
board.scrollY(400);
|
||||
const result = board.scale(0.8);
|
||||
expect(result).toStrictEqual({
|
||||
position: { top: 0, bottom: -80, left: 0, right: -200 },
|
||||
size: { x: 0, y: 0, w: 800, h: 480 }
|
||||
});
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
import Board from '../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
test('scroll', async () => {
|
||||
const resultScale = board.scale(2);
|
||||
expect(resultScale).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: 0, right: -600 },
|
||||
size: { x: 0, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultX = board.scrollX(-600);
|
||||
expect(resultX).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: -600, right: 0 },
|
||||
size: { x: -1200, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultY = board.scrollY(-400);
|
||||
expect(resultY).toStrictEqual({
|
||||
position: { top: -400, bottom: 0, left: -600, right: 0 },
|
||||
size: { x: -1200, y: -800, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
|
||||
const screenInfo = board.getScreenInfo();
|
||||
expect(screenInfo).toStrictEqual({
|
||||
size: { x: -1200, y: -800, w: 1200, h: 800 },
|
||||
position: { top: -400, bottom: 0, left: -600, right: 0 },
|
||||
deviceSize: { x: -2400, y: -1600, w: 4800, h: 3200 },
|
||||
width: 600,
|
||||
height: 400,
|
||||
devicePixelRatio: 4,
|
||||
canScrollXNext: true,
|
||||
canScrollXPrev: true,
|
||||
canScrollYNext: true,
|
||||
canScrollYPrev: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import Board from '../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe('@idraw/board', () => {
|
||||
test('scroll', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4,
|
||||
canScroll: true,
|
||||
scrollConfig: {
|
||||
width: 20,
|
||||
color: '#666666'
|
||||
}
|
||||
};
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const board = new Board(mount, opts);
|
||||
|
||||
const ctx = board.getContext();
|
||||
const data = getData();
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, opts.width, opts.height);
|
||||
data.elements.forEach((ele) => {
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
|
||||
const resultScale = board.scale(2);
|
||||
expect(resultScale).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: 0, right: -600 },
|
||||
size: { x: 0, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultX = board.scrollX(-600);
|
||||
expect(resultX).toStrictEqual({
|
||||
position: { top: 0, bottom: -400, left: -600, right: 0 },
|
||||
size: { x: -1200, y: 0, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
const resultY = board.scrollY(-400);
|
||||
expect(resultY).toStrictEqual({
|
||||
position: { top: -400, bottom: 0, left: -600, right: 0 },
|
||||
size: { x: -1200, y: -800, w: 1200, h: 800 }
|
||||
});
|
||||
|
||||
board.draw();
|
||||
|
||||
const originCtx = board.getOriginContext2D();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = board.getDisplayContext2D();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
|
||||
const scrollLineWidth = board.getScrollLineWidth();
|
||||
expect(scrollLineWidth).toStrictEqual(opts.scrollConfig.width);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
import type { Data } from '@idraw/types';
|
||||
import { createUUID, parseSVGPath } from '@idraw/util';
|
||||
|
||||
const data: Data = {
|
||||
elements: [
|
||||
// {
|
||||
// uuid: createUUID(),
|
||||
// type: 'image',
|
||||
// x: 100,
|
||||
// y: 100,
|
||||
// w: 100,
|
||||
// h: 100,
|
||||
// angle: 30,
|
||||
// detail: {
|
||||
// // src: '/public/images/lena.png?t=002'
|
||||
// src: '@assets/0ee02fb0-ec43-6b9a-9ab4-55be5816ca4a'
|
||||
// },
|
||||
// operations: {
|
||||
// limitRatio: true
|
||||
// }
|
||||
// },
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 2,
|
||||
y: 2,
|
||||
w: 100,
|
||||
h: 100,
|
||||
type: 'circle',
|
||||
detail: {
|
||||
background: '#f44336'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: createUUID(),
|
||||
type: 'rect',
|
||||
x: 50,
|
||||
y: 50,
|
||||
w: 100,
|
||||
h: 100,
|
||||
detail: {
|
||||
background: '#8bc34a'
|
||||
}
|
||||
},
|
||||
// {
|
||||
// uuid: createUUID(),
|
||||
// type: 'image',
|
||||
// x: 250,
|
||||
// y: 250,
|
||||
// w: 100,
|
||||
// h: 100,
|
||||
// detail: {
|
||||
// // src: '/public/images/github.png?t=003'
|
||||
// src: '@assets/25a0e630-a958-a522-29a4-5dccf04985da'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// uuid: createUUID(),
|
||||
// type: 'group',
|
||||
// x: 250,
|
||||
// y: 250,
|
||||
// w: 100,
|
||||
// h: 100,
|
||||
// detail: {
|
||||
// children: [
|
||||
// {
|
||||
// uuid: createUUID(),
|
||||
// type: 'image',
|
||||
// x: 0,
|
||||
// y: 0,
|
||||
// w: 100,
|
||||
// h: 100,
|
||||
// detail: {
|
||||
// // src: '/public/images/github.png?t=003'
|
||||
// src: '@assets/489c64d2-f642-3855-7bd6-cb40624b62c3'
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// // assets: {
|
||||
// // '@assets/489c64d2-f642-3855-7bd6-cb40624b62c3': {
|
||||
// // type: 'image',
|
||||
// // value: '/public/images/github.png?t=003'
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 0,
|
||||
y: 300,
|
||||
w: 100,
|
||||
h: 100,
|
||||
type: 'circle',
|
||||
detail: {
|
||||
background: '#009688'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 300,
|
||||
y: 300,
|
||||
w: 100,
|
||||
h: 100,
|
||||
type: 'circle',
|
||||
detail: {
|
||||
background: '#673ab7'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 300,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
type: 'circle',
|
||||
detail: {
|
||||
background: '#ffc107'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 150,
|
||||
y: 150,
|
||||
w: 100,
|
||||
h: 100,
|
||||
// angle: 30,
|
||||
type: 'rect',
|
||||
detail: {
|
||||
background: '#4caf50',
|
||||
clipPath: {
|
||||
commands: parseSVGPath(`
|
||||
M 10,30
|
||||
A 20,20 0,0,1 50,30
|
||||
A 20,20 0,0,1 90,30
|
||||
Q 90,60 50,90
|
||||
Q 10,60 10,30 z`),
|
||||
// fill: '#ff0000',
|
||||
originX: 10,
|
||||
originY: 10,
|
||||
originH: 80,
|
||||
originW: 80
|
||||
// background: '#0000002A'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: createUUID(),
|
||||
x: 100,
|
||||
y: 10,
|
||||
w: 80,
|
||||
h: 80,
|
||||
// angle: 30,
|
||||
type: 'path',
|
||||
detail: {
|
||||
commands: parseSVGPath(`
|
||||
M 10,30
|
||||
A 20,20 0,0,1 50,30
|
||||
A 20,20 0,0,1 90,30
|
||||
Q 90,60 50,90
|
||||
Q 10,60 10,30 z`),
|
||||
fill: 'red',
|
||||
originX: 10,
|
||||
originY: 10,
|
||||
originH: 80,
|
||||
originW: 80,
|
||||
background: '#0000002A'
|
||||
|
||||
// clipPath: {
|
||||
// commands: parseSVGPath(`
|
||||
// M 10,30
|
||||
// A 20,20 0,0,1 50,30
|
||||
// A 20,20 0,0,1 90,30
|
||||
// Q 90,60 50,90
|
||||
// Q 10,60 10,30 z`),
|
||||
// fill: '#ff0000',
|
||||
// originX: 10,
|
||||
// originY: 10,
|
||||
// originH: 80,
|
||||
// originW: 80
|
||||
// }
|
||||
}
|
||||
}
|
||||
]
|
||||
// assets: {
|
||||
// '@assets/0ee02fb0-ec43-6b9a-9ab4-55be5816ca4a': {
|
||||
// type: 'image',
|
||||
// value: '/public/images/lena.png?t=003'
|
||||
// },
|
||||
// '@assets/25a0e630-a958-a522-29a4-5dccf04985da': {
|
||||
// type: 'image',
|
||||
// value: '/public/images/github.png?t=002'
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
export default data;
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<style></style>
|
||||
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
background: #f0f0f088;
|
||||
}
|
||||
#mount {
|
||||
/* margin-top: 50px;
|
||||
margin-left: 60px; */
|
||||
}
|
||||
#mount canvas {
|
||||
border-right: 1px solid #aaaaaa40;
|
||||
border-bottom: 1px solid #aaaaaa40;
|
||||
background-image:
|
||||
linear-gradient(#aaaaaa40 1px, transparent 0),
|
||||
linear-gradient(90deg, #aaaaaa40 1px, transparent 0),
|
||||
linear-gradient(#aaa 1px, transparent 0),
|
||||
linear-gradient(90deg, #aaa 1px, transparent 0);
|
||||
background-size: 10px 10px, 10px 10px, 50px 50px, 50px 50px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="mount">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="module" src="./main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import { createBoardContent, deepClone } from '../../util/src';
|
||||
import { Board } from '../src';
|
||||
import { MiddlewareSelector, MiddlewareScroller, MiddlewareScaler } from '../../core/src';
|
||||
import data from './data';
|
||||
|
||||
const devicePixelRatio = window.devicePixelRatio;
|
||||
// const width = window.innerWidth;
|
||||
// const height = window.innerHeight;
|
||||
|
||||
const width = 800;
|
||||
const height = 600;
|
||||
|
||||
const canvas = document.querySelector('#canvas') as HTMLCanvasElement;
|
||||
canvas.width = width * devicePixelRatio;
|
||||
canvas.height = height * devicePixelRatio;
|
||||
canvas.style.width = `${width}px`;
|
||||
canvas.style.height = `${height}px`;
|
||||
// const ctx1 = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const boardContent1 = createBoardContent(canvas, { width, height, devicePixelRatio });
|
||||
const board = new Board({ boardContent: boardContent1 });
|
||||
|
||||
const sharer1 = board.getSharer();
|
||||
sharer1.setActiveViewSizeInfo({
|
||||
devicePixelRatio,
|
||||
width,
|
||||
height,
|
||||
contextWidth: width,
|
||||
contextHeight: height
|
||||
});
|
||||
const data1 = deepClone(data);
|
||||
board.resize(sharer1.getActiveViewSizeInfo());
|
||||
board.setData(data1);
|
||||
board.use(MiddlewareSelector);
|
||||
board.use(MiddlewareScroller);
|
||||
board.use(MiddlewareScaler);
|
||||
// board.scale(2);
|
||||
// board.scrollX(-50);
|
||||
// board.scrollY(-50);
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"name": "@idraw/board",
|
||||
"version": "0.4.0-beta.39",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
"unpkg": "dist/index.global.js",
|
||||
"types": "dist/esm/index.d.ts",
|
||||
"files": [
|
||||
"dist/**/*.ts",
|
||||
"dist/**/*.js"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/idrawjs/idraw.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39"
|
||||
},
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"@idraw/util": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/renderer": "workspace:^0.4.0-beta.39"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"provenance": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/core",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
|
@ -18,16 +18,15 @@
|
|||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/types": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"@idraw/board": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/renderer": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/renderer": "workspace:^0.4.0-beta.40",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Renderer } from '@idraw/renderer';
|
||||
import { Renderer, Calculator } from '@idraw/renderer';
|
||||
import {
|
||||
// throttle,
|
||||
calcElementsContextSize,
|
||||
|
|
@ -16,10 +16,9 @@ import type {
|
|||
UtilEventEmitter,
|
||||
ModifyOptions
|
||||
} from '@idraw/types';
|
||||
import { Calculator } from './lib/calculator';
|
||||
import { BoardWatcher } from './lib/watcher';
|
||||
import { Sharer } from './lib/sharer';
|
||||
import { Viewer } from './lib/viewer';
|
||||
import { BoardWatcher } from './watcher';
|
||||
import { Sharer } from './sharer';
|
||||
import { Viewer } from './viewer';
|
||||
|
||||
// const throttleTime = 10; // ms
|
||||
|
||||
|
|
@ -44,16 +43,17 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
|
|||
constructor(opts: BoardOptions) {
|
||||
const { boardContent } = opts;
|
||||
const sharer = new Sharer();
|
||||
const calculator = new Calculator({ viewContext: boardContent.viewContext });
|
||||
|
||||
const watcher = new BoardWatcher({
|
||||
boardContent,
|
||||
sharer
|
||||
});
|
||||
const renderer = new Renderer({
|
||||
viewContext: boardContent.viewContext,
|
||||
sharer,
|
||||
calculator
|
||||
tempContext: boardContent.tempContext,
|
||||
sharer
|
||||
});
|
||||
const calculator = renderer.getCalculator();
|
||||
|
||||
this.#opts = opts;
|
||||
this.#sharer = sharer;
|
||||
|
|
@ -331,12 +331,12 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
|
|||
extend: true
|
||||
});
|
||||
if (modifiedOptions) {
|
||||
this.#viewer.resetViewVisibleInfoMap(data, {
|
||||
this.#viewer.resetVirtualFlatItemMap(data, {
|
||||
viewSizeInfo,
|
||||
viewScaleInfo
|
||||
});
|
||||
} else {
|
||||
this.#viewer.resetViewVisibleInfoMap(data, {
|
||||
this.#viewer.resetVirtualFlatItemMap(data, {
|
||||
viewSizeInfo,
|
||||
viewScaleInfo
|
||||
});
|
||||
|
|
@ -374,7 +374,10 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
|
|||
const calculator = this.#calculator;
|
||||
const eventHub = this.#eventHub;
|
||||
|
||||
const obj = middleware({ boardContent, sharer, viewer, calculator, eventHub: eventHub as UtilEventEmitter<any>, container }, config);
|
||||
const obj = middleware(
|
||||
{ boardContent, sharer, viewer, calculator, eventHub: eventHub as UtilEventEmitter<any>, container },
|
||||
config
|
||||
);
|
||||
obj.use?.();
|
||||
this.#middlewares.push(middleware);
|
||||
this.#activeMiddlewareObjs.push(obj);
|
||||
|
|
@ -45,7 +45,18 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
const { renderer, boardContent, beforeDrawFrame, afterDrawFrame } = this.#opts;
|
||||
|
||||
if (snapshot) {
|
||||
const { scale, offsetTop, offsetBottom, offsetLeft, offsetRight, width, height, contextHeight, contextWidth, devicePixelRatio } = snapshot.activeStore;
|
||||
const {
|
||||
scale,
|
||||
offsetTop,
|
||||
offsetBottom,
|
||||
offsetLeft,
|
||||
offsetRight,
|
||||
width,
|
||||
height,
|
||||
contextHeight,
|
||||
contextWidth,
|
||||
devicePixelRatio
|
||||
} = snapshot.activeStore;
|
||||
|
||||
const viewScaleInfo: ViewScaleInfo = {
|
||||
scale,
|
||||
|
|
@ -86,7 +97,7 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
}
|
||||
}
|
||||
|
||||
resetViewVisibleInfoMap(
|
||||
resetVirtualFlatItemMap(
|
||||
data: Data,
|
||||
opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
|
|
@ -94,7 +105,7 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
}
|
||||
): void {
|
||||
if (data) {
|
||||
this.#opts.calculator.resetViewVisibleInfoMap(data, opts);
|
||||
this.#opts.calculator.resetVirtualFlatItemMap(data, opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +122,10 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
this.#drawAnimationFrame();
|
||||
}
|
||||
|
||||
scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }): { moveX: number; moveY: number } {
|
||||
scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }): {
|
||||
moveX: number;
|
||||
moveY: number;
|
||||
} {
|
||||
const { scale, point, ignoreUpdateVisibleStatus } = opts;
|
||||
const { sharer } = this.#opts;
|
||||
const { moveX, moveY } = viewScale({
|
||||
|
|
@ -1,4 +1,12 @@
|
|||
import type { Point, BoardWatcherEventMap, Data, Element, ElementType, BoardWatcherOptions, BoardWatcherStore } from '@idraw/types';
|
||||
import type {
|
||||
Point,
|
||||
BoardWatcherEventMap,
|
||||
Data,
|
||||
Element,
|
||||
ElementType,
|
||||
BoardWatcherOptions,
|
||||
BoardWatcherStore
|
||||
} from '@idraw/types';
|
||||
import { EventEmitter, Store } from '@idraw/util';
|
||||
|
||||
function isBoardAvailableNum(num: any): boolean {
|
||||
|
|
@ -11,7 +19,9 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
#hasDestroyed: boolean = false;
|
||||
constructor(opts: BoardWatcherOptions) {
|
||||
super();
|
||||
const store = new Store<BoardWatcherStore>({ defaultStorage: { hasPointDown: false, prevClickPoint: null, inCanvas: true } });
|
||||
const store = new Store<BoardWatcherStore>({
|
||||
defaultStorage: { hasPointDown: false, prevClickPoint: null, inCanvas: true }
|
||||
});
|
||||
this.#store = store;
|
||||
this.#opts = opts;
|
||||
this.#init();
|
||||
|
|
@ -25,25 +35,27 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
if (this.#hasDestroyed) {
|
||||
return;
|
||||
}
|
||||
const canvas = this.#opts.boardContent.boardContext.canvas;
|
||||
const container = window;
|
||||
container.addEventListener('mousemove', this.#onHover);
|
||||
container.addEventListener('mousedown', this.#onPointStart);
|
||||
container.addEventListener('mousemove', this.#onPointMove);
|
||||
container.addEventListener('mouseup', this.#onPointEnd);
|
||||
// container.addEventListener('mouseleave', this.#onPointLeave);
|
||||
container.addEventListener('wheel', this.#onWheel, { passive: false });
|
||||
canvas.addEventListener('wheel', this.#onWheel, { passive: false });
|
||||
container.addEventListener('click', this.#onClick);
|
||||
container.addEventListener('contextmenu', this.#onContextMenu);
|
||||
}
|
||||
|
||||
offEvents() {
|
||||
const container = window;
|
||||
const canvas = this.#opts.boardContent.boardContext.canvas;
|
||||
container.removeEventListener('mousemove', this.#onHover);
|
||||
container.removeEventListener('mousedown', this.#onPointStart);
|
||||
container.removeEventListener('mousemove', this.#onPointMove);
|
||||
container.removeEventListener('mouseup', this.#onPointEnd);
|
||||
container.removeEventListener('mouseleave', this.#onPointLeave);
|
||||
container.removeEventListener('wheel', this.#onWheel);
|
||||
canvas.removeEventListener('wheel', this.#onWheel);
|
||||
container.removeEventListener('click', this.#onClick);
|
||||
container.removeEventListener('contextmenu', this.#onContextMenu);
|
||||
}
|
||||
|
|
@ -101,7 +113,12 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
|
|||
const maxLimitTime = 500;
|
||||
const t = Date.now();
|
||||
const preClickPoint = this.#store.get('prevClickPoint');
|
||||
if (preClickPoint && t - preClickPoint.t <= maxLimitTime && Math.abs(preClickPoint.x - point.x) <= 5 && Math.abs(preClickPoint.y - point.y) <= 5) {
|
||||
if (
|
||||
preClickPoint &&
|
||||
t - preClickPoint.t <= maxLimitTime &&
|
||||
Math.abs(preClickPoint.x - point.x) <= 5 &&
|
||||
Math.abs(preClickPoint.y - point.y) <= 5
|
||||
) {
|
||||
this.trigger('doubleClick', { point });
|
||||
} else {
|
||||
this.#store.set('prevClickPoint', point);
|
||||
|
|
@ -3,6 +3,7 @@ export const EVENT_KEY_CURSOR = 'cursor';
|
|||
export const EVENT_KEY_RULER = 'ruler';
|
||||
export const EVENT_KEY_SCALE = 'scale';
|
||||
export const EVENT_KEY_SELECT = 'select';
|
||||
export const EVENT_KEY_SELECT_LAYOUT = 'selectLayout';
|
||||
export const EVENT_KEY_CLEAR_SELECT = 'clearSelect';
|
||||
export const EVENT_KEY_TEXT_EDIT = 'textEdit';
|
||||
export const EVENT_KEY_TEXT_CHANGE = 'textChange';
|
||||
|
|
@ -16,6 +17,7 @@ export type CoreEventKeys = {
|
|||
RULER: typeof EVENT_KEY_RULER;
|
||||
SCALE: typeof EVENT_KEY_SCALE;
|
||||
SELECT: typeof EVENT_KEY_SELECT;
|
||||
SELECT_LAYOUT: typeof EVENT_KEY_SELECT_LAYOUT;
|
||||
CLEAR_SELECT: typeof EVENT_KEY_CLEAR_SELECT;
|
||||
TEXT_EDIT: typeof EVENT_KEY_TEXT_EDIT;
|
||||
TEXT_CHANGE: typeof EVENT_KEY_TEXT_CHANGE;
|
||||
|
|
@ -29,6 +31,7 @@ const innerEventKeys: CoreEventKeys = {
|
|||
CHANGE: EVENT_KEY_CHANGE,
|
||||
RULER: EVENT_KEY_RULER,
|
||||
SCALE: EVENT_KEY_SCALE,
|
||||
SELECT_LAYOUT: EVENT_KEY_SELECT_LAYOUT,
|
||||
SELECT: EVENT_KEY_SELECT,
|
||||
CLEAR_SELECT: EVENT_KEY_CLEAR_SELECT,
|
||||
TEXT_EDIT: EVENT_KEY_TEXT_EDIT,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,22 @@
|
|||
import type { Data, PointSize, CoreOptions, BoardMiddleware, ViewSizeInfo, CoreEventMap, ViewScaleInfo, LoadItemMap, ModifyOptions } from '@idraw/types';
|
||||
import { Board } from '@idraw/board';
|
||||
import type {
|
||||
Data,
|
||||
PointSize,
|
||||
CoreOptions,
|
||||
BoardMiddleware,
|
||||
ViewSizeInfo,
|
||||
CoreEventMap,
|
||||
ViewScaleInfo,
|
||||
LoadItemMap,
|
||||
ModifyOptions
|
||||
} from '@idraw/types';
|
||||
import { Board, Sharer, Calculator } from './board';
|
||||
import { createBoardContent, validateElements } from '@idraw/util';
|
||||
import { Cursor } from './lib/cursor';
|
||||
export { coreEventKeys } from './config';
|
||||
export type { CoreEventKeys } from './config';
|
||||
|
||||
export { Board, Sharer, Calculator };
|
||||
|
||||
// export { MiddlewareSelector } from './middleware/selector';
|
||||
export { MiddlewareSelector } from './middleware/selector';
|
||||
export { MiddlewareScroller } from './middleware/scroller';
|
||||
|
|
@ -23,7 +35,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
|
|||
#container: HTMLDivElement;
|
||||
|
||||
constructor(container: HTMLDivElement, opts: CoreOptions) {
|
||||
const { devicePixelRatio = 1, width, height, createCustomContext2D } = opts;
|
||||
const { devicePixelRatio = 1, width, height } = opts;
|
||||
|
||||
// this.#opts = opts;
|
||||
this.#container = container;
|
||||
|
|
@ -33,7 +45,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
|
|||
this.#initContainer();
|
||||
container.appendChild(canvas);
|
||||
|
||||
const boardContent = createBoardContent(canvas, { width, height, devicePixelRatio, offscreen: true, createCustomContext2D });
|
||||
const boardContent = createBoardContent(canvas, { width, height, devicePixelRatio });
|
||||
const board = new Board<E>({ boardContent, container });
|
||||
const sharer = board.getSharer();
|
||||
sharer.setActiveViewSizeInfo({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig, CoreEventMap } from '@idraw/types';
|
||||
import { calcLayoutSizeController, isViewPointInVertexes, getViewScaleInfoFromSnapshot, isViewPointInElementSize, calcViewElementSize } from '@idraw/util';
|
||||
import {
|
||||
calcLayoutSizeController,
|
||||
isViewPointInVertexes,
|
||||
getViewScaleInfoFromSnapshot,
|
||||
isViewPointInElementSize,
|
||||
calcViewElementSize
|
||||
} from '@idraw/util';
|
||||
import type { LayoutSelectorSharedStorage, ControlType } from './types';
|
||||
import {
|
||||
keyLayoutActionType,
|
||||
|
|
@ -21,7 +27,11 @@ import { coreEventKeys } from '../../config';
|
|||
|
||||
export { keyLayoutIsSelected, keyLayoutIsBusyMoving };
|
||||
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, CoreEventMap, MiddlewareLayoutSelectorConfig> = (opts, config) => {
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<
|
||||
LayoutSelectorSharedStorage,
|
||||
CoreEventMap,
|
||||
MiddlewareLayoutSelectorConfig
|
||||
> = (opts, config) => {
|
||||
const { sharer, boardContent, calculator, viewer, eventHub } = opts;
|
||||
const { overlayContext } = boardContent;
|
||||
let innerConfig = {
|
||||
|
|
@ -242,6 +252,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
|
||||
if (sharer.getSharedStorage(keyLayoutIsSelected) === true && !prevIsSelected) {
|
||||
viewer.drawFrame();
|
||||
eventHub.trigger(coreEventKeys.SELECT_LAYOUT);
|
||||
}
|
||||
prevIsSelected = sharer.getSharedStorage(keyLayoutIsSelected);
|
||||
|
||||
|
|
@ -349,11 +360,14 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
const data = sharer.getActiveStorage('data');
|
||||
if (data && layoutActionType === 'resize' && layoutControlType) {
|
||||
eventHub.trigger(coreEventKeys.CHANGE, {
|
||||
type: 'changeLayout',
|
||||
type: 'dragLayout',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
sharer.setSharedStorage(keyLayoutActionType, null);
|
||||
sharer.setSharedStorage(keyLayoutControlType, null);
|
||||
|
||||
if (sharer.getSharedStorage(keyLayoutIsHoverController) === true) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
import type { Point, BoardViewerFrameSnapshot, ViewScaleInfo, ViewSizeInfo, ViewContext2D, ElementSize, MiddlewareScrollerStyle } from '@idraw/types';
|
||||
import type {
|
||||
Point,
|
||||
BoardViewerFrameSnapshot,
|
||||
ViewScaleInfo,
|
||||
ViewSizeInfo,
|
||||
ViewContext2D,
|
||||
ElementSize,
|
||||
MiddlewareScrollerStyle
|
||||
} from '@idraw/types';
|
||||
import { getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from '@idraw/util';
|
||||
import { keyActivePoint, keyActiveThumbType, keyPrevPoint, keyXThumbRect, keyYThumbRect, keyHoverXThumbRect, keyHoverYThumbRect } from './config';
|
||||
import {
|
||||
keyActivePoint,
|
||||
keyActiveThumbType,
|
||||
keyPrevPoint,
|
||||
keyXThumbRect,
|
||||
keyYThumbRect,
|
||||
keyHoverXThumbRect,
|
||||
keyHoverYThumbRect
|
||||
} from './config';
|
||||
|
||||
const scrollerLineWidth = 16;
|
||||
const minThumbLength = scrollerLineWidth * 2.5;
|
||||
|
|
@ -153,7 +169,8 @@ function drawScrollerThumb(
|
|||
borderColor: string;
|
||||
}
|
||||
): void {
|
||||
let { x, y, h, w, background, borderColor } = opts;
|
||||
let { x, y, h, w } = opts;
|
||||
const { background, borderColor } = opts;
|
||||
|
||||
ctx.save();
|
||||
ctx.shadowColor = '#FFFFFF';
|
||||
|
|
@ -203,7 +220,12 @@ function drawScrollerThumb(
|
|||
|
||||
function drawScrollerInfo(
|
||||
overlayContext: ViewContext2D,
|
||||
opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo; scrollInfo: ScrollInfo; style: MiddlewareScrollerStyle }
|
||||
opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
scrollInfo: ScrollInfo;
|
||||
style: MiddlewareScrollerStyle;
|
||||
}
|
||||
) {
|
||||
const ctx = overlayContext;
|
||||
const { viewScaleInfo, viewSizeInfo, scrollInfo, style } = opts;
|
||||
|
|
@ -261,7 +283,10 @@ function drawScrollerInfo(
|
|||
};
|
||||
}
|
||||
|
||||
export function drawScroller(ctx: ViewContext2D, opts: { snapshot: BoardViewerFrameSnapshot; style: MiddlewareScrollerStyle }) {
|
||||
export function drawScroller(
|
||||
ctx: ViewContext2D,
|
||||
opts: { snapshot: BoardViewerFrameSnapshot; style: MiddlewareScrollerStyle }
|
||||
) {
|
||||
const { snapshot, style } = opts;
|
||||
const viewSizeInfo = getViewSizeInfoFromSnapshot(snapshot);
|
||||
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
|
||||
|
|
|
|||
|
|
@ -173,7 +173,10 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
sharer.setSharedStorage(keySelectedElementList, list);
|
||||
if (list.length === 1) {
|
||||
updateSelectedElemenetController();
|
||||
sharer.setSharedStorage(keySelectedElementPosition, getElementPositionFromList(list[0].uuid, sharer.getActiveStorage('data')?.elements || []));
|
||||
sharer.setSharedStorage(
|
||||
keySelectedElementPosition,
|
||||
getElementPositionFromList(list[0].uuid, sharer.getActiveStorage('data')?.elements || [])
|
||||
);
|
||||
} else {
|
||||
sharer.setSharedStorage(keySelectedElementController, null);
|
||||
sharer.setSharedStorage(keySelectedElementPosition, []);
|
||||
|
|
@ -183,7 +186,11 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
const uuids = list.map((elem) => elem.uuid);
|
||||
const data = sharer.getActiveStorage('data');
|
||||
const positionMap = getElementPositionMapFromList(uuids, data?.elements || []);
|
||||
eventHub.trigger(coreEventKeys.SELECT, { uuids, positions: list.map((elem) => [...positionMap[elem.uuid]]) });
|
||||
eventHub.trigger(coreEventKeys.SELECT, {
|
||||
type: 'clickCanvas',
|
||||
uuids,
|
||||
positions: list.map((elem) => [...positionMap[elem.uuid]])
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -515,7 +522,14 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
|
||||
eventHub.trigger(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, { show: false });
|
||||
|
||||
if (data && elems?.length === 1 && moveOriginalStartElementSize && originalStart && end && elems[0]?.operations?.locked !== true) {
|
||||
if (
|
||||
data &&
|
||||
elems?.length === 1 &&
|
||||
moveOriginalStartElementSize &&
|
||||
originalStart &&
|
||||
end &&
|
||||
elems[0]?.operations?.locked !== true
|
||||
) {
|
||||
const { moveX, moveY } = calcPointMoveElementInGroup(originalStart, end, groupQueue);
|
||||
|
||||
let totalMoveX = calculator.toGridNum(moveX / scale);
|
||||
|
|
@ -547,7 +561,7 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
elems[0].x = calculator.toGridNum(moveOriginalStartElementSize.x + totalMoveX);
|
||||
elems[0].y = calculator.toGridNum(moveOriginalStartElementSize.y + totalMoveY);
|
||||
updateSelectedElementList([elems[0]]);
|
||||
calculator.modifyViewVisibleInfoMap(data, {
|
||||
calculator.modifyVirtualFlatItemMap(data, {
|
||||
modifyOptions: {
|
||||
type: 'updateElement',
|
||||
content: {
|
||||
|
|
@ -571,7 +585,7 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
elem.x = calculator.toGridNum(elem.x + moveX);
|
||||
elem.y = calculator.toGridNum(elem.y + moveY);
|
||||
|
||||
calculator.modifyViewVisibleInfoMap(data, {
|
||||
calculator.modifyVirtualFlatItemMap(data, {
|
||||
modifyOptions: {
|
||||
type: 'updateElement',
|
||||
content: {
|
||||
|
|
@ -589,7 +603,13 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
}
|
||||
viewer.drawFrame();
|
||||
} else if (actionType === 'resize') {
|
||||
if (data && elems?.length === 1 && originalStart && moveOriginalStartElementSize && resizeType?.startsWith('resize-')) {
|
||||
if (
|
||||
data &&
|
||||
elems?.length === 1 &&
|
||||
originalStart &&
|
||||
moveOriginalStartElementSize &&
|
||||
resizeType?.startsWith('resize-')
|
||||
) {
|
||||
hasChangedData = true;
|
||||
inBusyMode = 'resize';
|
||||
const pointGroupQueue: Element<'group'>[] = [];
|
||||
|
|
@ -612,7 +632,9 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
resizeEnd = rotatePointInGroup(end, pointGroupQueue);
|
||||
}
|
||||
if (resizeType === 'resize-rotate') {
|
||||
const controller: ElementSizeController = sharer.getSharedStorage(keySelectedElementController) as ElementSizeController;
|
||||
const controller: ElementSizeController = sharer.getSharedStorage(
|
||||
keySelectedElementController
|
||||
) as ElementSizeController;
|
||||
const viewVertexes: ViewRectVertexes = [
|
||||
controller.topLeft.center,
|
||||
controller.topRight.center,
|
||||
|
|
@ -633,7 +655,10 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
|
||||
elems[0].angle = calculator.toGridNum(resizedElemSize.angle || 0);
|
||||
} else {
|
||||
const resizedElemSize = resizeElement(moveOriginalStartElementSize, { scale, start: resizeStart, end: resizeEnd, resizeType, sharer });
|
||||
const resizedElemSize = resizeElement(
|
||||
{ ...moveOriginalStartElementSize, operations: elems[0].operations },
|
||||
{ scale, start: resizeStart, end: resizeEnd, resizeType, sharer }
|
||||
);
|
||||
const calcOpts = { ignore: !!moveOriginalStartElementSize.angle };
|
||||
elems[0].x = calculator.toGridNum(resizedElemSize.x, calcOpts);
|
||||
elems[0].y = calculator.toGridNum(resizedElemSize.y, calcOpts);
|
||||
|
|
@ -649,7 +674,7 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
}
|
||||
|
||||
updateSelectedElementList([elems[0]]);
|
||||
calculator.modifyViewVisibleInfoMap(data, {
|
||||
calculator.modifyVirtualFlatItemMap(data, {
|
||||
modifyOptions: {
|
||||
type: 'updateElement',
|
||||
content: {
|
||||
|
|
@ -788,11 +813,18 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
viewer.drawFrame();
|
||||
return;
|
||||
}
|
||||
} else if (target.elements.length === 1 && target.elements[0]?.type === 'text' && !target.elements[0]?.operations?.invisible) {
|
||||
} else if (
|
||||
target.elements.length === 1 &&
|
||||
target.elements[0]?.type === 'text' &&
|
||||
!target.elements[0]?.operations?.invisible
|
||||
) {
|
||||
eventHub.trigger(coreEventKeys.TEXT_EDIT, {
|
||||
element: target.elements[0] as Element<'text'>,
|
||||
groupQueue: sharer.getSharedStorage(keyGroupQueue) || [],
|
||||
position: getElementPositionFromList(target.elements[0]?.uuid, sharer.getActiveStorage('data')?.elements || []),
|
||||
position: getElementPositionFromList(
|
||||
target.elements[0]?.uuid,
|
||||
sharer.getActiveStorage('data')?.elements || []
|
||||
),
|
||||
viewScaleInfo: sharer.getActiveViewScaleInfo()
|
||||
});
|
||||
}
|
||||
|
|
@ -858,7 +890,18 @@ export const MiddlewareSelector: BoardMiddleware<
|
|||
const style = { activeColor, activeAreaColor, lockedColor, referenceColor };
|
||||
|
||||
const { activeStore, sharedStore } = snapshot;
|
||||
const { scale, offsetLeft, offsetTop, offsetRight, offsetBottom, width, height, contextHeight, contextWidth, devicePixelRatio } = activeStore;
|
||||
const {
|
||||
scale,
|
||||
offsetLeft,
|
||||
offsetTop,
|
||||
offsetRight,
|
||||
offsetBottom,
|
||||
width,
|
||||
height,
|
||||
contextHeight,
|
||||
contextWidth,
|
||||
devicePixelRatio
|
||||
} = activeStore;
|
||||
if (rotateControllerPattern.fill !== activeColor) {
|
||||
rotateControllerPattern = createRotateControllerPattern({
|
||||
fill: innerConfig.activeColor,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,14 @@ import {
|
|||
limitAngle,
|
||||
calcRadian
|
||||
} from '@idraw/util';
|
||||
import type { ViewRectVertexes, ElementSizeController, StoreSharer, ViewScaleInfo, ViewSizeInfo } from '@idraw/types';
|
||||
import type {
|
||||
ViewRectVertexes,
|
||||
ElementSizeController,
|
||||
StoreSharer,
|
||||
ViewScaleInfo,
|
||||
ViewSizeInfo,
|
||||
ElementOperations
|
||||
} from '@idraw/types';
|
||||
import type {
|
||||
Data,
|
||||
Element,
|
||||
|
|
@ -65,7 +72,12 @@ export function isPointInViewActiveVertexes(
|
|||
|
||||
export function isPointInViewActiveGroup(
|
||||
p: PointSize,
|
||||
opts: { ctx: ViewContext2D; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo; groupQueue: Element<'group'>[] | null }
|
||||
opts: {
|
||||
ctx: ViewContext2D;
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
groupQueue: Element<'group'>[] | null;
|
||||
}
|
||||
): boolean {
|
||||
const { ctx, viewScaleInfo, viewSizeInfo, groupQueue } = opts;
|
||||
if (!groupQueue || !(groupQueue?.length > 0)) {
|
||||
|
|
@ -100,7 +112,17 @@ export function getPointTarget(
|
|||
groupQueue: [],
|
||||
groupQueueVertexesList: []
|
||||
};
|
||||
const { ctx, data, calculator, selectedElements, viewScaleInfo, viewSizeInfo, areaSize, groupQueue, selectedElementController } = opts;
|
||||
const {
|
||||
ctx,
|
||||
data,
|
||||
calculator,
|
||||
selectedElements,
|
||||
viewScaleInfo,
|
||||
viewSizeInfo,
|
||||
areaSize,
|
||||
groupQueue,
|
||||
selectedElementController
|
||||
} = opts;
|
||||
|
||||
// resize
|
||||
if (selectedElementController) {
|
||||
|
|
@ -174,7 +196,7 @@ export function getPointTarget(
|
|||
}
|
||||
|
||||
export function resizeElement(
|
||||
elem: ElementSize,
|
||||
elem: ElementSize & { operations?: ElementOperations },
|
||||
opts: {
|
||||
start: PointSize;
|
||||
end: PointSize;
|
||||
|
|
@ -260,7 +282,9 @@ export function resizeElement(
|
|||
const maxHorizontalDist = Math.max(Math.abs(moveHorizontalX), Math.abs(moveHorizontalY));
|
||||
moveHorizontalX = (moveHorizontalX >= 0 ? 1 : -1) * maxHorizontalDist;
|
||||
moveHorizontalY = (((moveHorizontalY >= 0 ? 1 : -1) * maxHorizontalDist) / elem.w) * elem.h;
|
||||
} else if (['resize-top-left', 'resize-top-right', 'resize-bottom-left', 'resize-bottom-right'].includes(resizeType)) {
|
||||
} else if (
|
||||
['resize-top-left', 'resize-top-right', 'resize-bottom-left', 'resize-bottom-right'].includes(resizeType)
|
||||
) {
|
||||
{
|
||||
// const maxDist = Math.max(Math.abs(moveX), Math.abs(moveY));
|
||||
const maxDist = Math.abs(moveX);
|
||||
|
|
@ -533,7 +557,8 @@ export function resizeElement(
|
|||
|
||||
if (angle < 90) {
|
||||
moveVerticalDist = 0 - changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = 0 - changeMoveDistDirect(moveHorizontalDist, limitRatio ? 0 - moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist =
|
||||
0 - changeMoveDistDirect(moveHorizontalDist, limitRatio ? 0 - moveVerticalDist : moveHorizontalX);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
centerX = centerX + centerMoveVerticalDist * Math.sin(radian);
|
||||
|
|
@ -544,7 +569,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 180) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalX
|
||||
);
|
||||
const radian = parseRadian(angle - 90);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -556,7 +584,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveDist * Math.cos(radian);
|
||||
} else if (angle < 270) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 180);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -568,7 +599,10 @@ export function resizeElement(
|
|||
centerY = centerY + centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 360) {
|
||||
moveVerticalDist = 0 - changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 270);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -604,7 +638,10 @@ export function resizeElement(
|
|||
let centerY = elemCenter.y;
|
||||
if (angle < 90) {
|
||||
moveVerticalDist = 0 - changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -616,7 +653,10 @@ export function resizeElement(
|
|||
centerY = centerY + centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 180) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 90);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -629,7 +669,10 @@ export function resizeElement(
|
|||
} else if (angle < 270) {
|
||||
const radian = parseRadian(angle - 180);
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : 0 - moveHorizontalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : 0 - moveHorizontalX
|
||||
);
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
centerX = centerX - centerMoveVerticalDist * Math.sin(radian);
|
||||
centerY = centerY + centerMoveVerticalDist * Math.cos(radian);
|
||||
|
|
@ -639,7 +682,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 360) {
|
||||
moveVerticalDist = 0 - changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalX
|
||||
);
|
||||
const radian = parseRadian(angle - 270);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -675,7 +721,8 @@ export function resizeElement(
|
|||
let centerY = elemCenter.y;
|
||||
if (angle < 90) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = 0 - changeMoveDistDirect(moveHorizontalDist, limitRatio ? 0 - moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist =
|
||||
0 - changeMoveDistDirect(moveHorizontalDist, limitRatio ? 0 - moveVerticalDist : moveHorizontalX);
|
||||
const radian = parseRadian(angle);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -687,7 +734,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 180) {
|
||||
moveVerticalDist = 0 - changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalX
|
||||
);
|
||||
const radian = parseRadian(angle - 90);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -699,7 +749,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveDist * Math.cos(radian);
|
||||
} else if (angle < 270) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 180);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -711,7 +764,10 @@ export function resizeElement(
|
|||
centerY = centerY + centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 360) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 270);
|
||||
const centerMoveDist = moveVerticalDist / 2;
|
||||
centerX = centerX + centerMoveDist * Math.cos(radian);
|
||||
|
|
@ -745,7 +801,10 @@ export function resizeElement(
|
|||
let centerY = elemCenter.y;
|
||||
if (angle < 90) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -769,7 +828,10 @@ export function resizeElement(
|
|||
centerY = centerY + centerMoveHorizontalDist * Math.cos(radian);
|
||||
} else if (angle < 270) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : 0 - moveHorizontalY);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : 0 - moveHorizontalY
|
||||
);
|
||||
const radian = parseRadian(angle - 180);
|
||||
|
||||
const centerMoveVerticalDist = moveVerticalDist / 2;
|
||||
|
|
@ -781,7 +843,10 @@ export function resizeElement(
|
|||
centerY = centerY - centerMoveHorizontalDist * Math.sin(radian);
|
||||
} else if (angle < 360) {
|
||||
moveVerticalDist = changeMoveDistDirect(moveVerticalDist, moveVerticalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(moveHorizontalDist, limitRatio ? moveVerticalDist : moveHorizontalX);
|
||||
moveHorizontalDist = changeMoveDistDirect(
|
||||
moveHorizontalDist,
|
||||
limitRatio ? moveVerticalDist : moveHorizontalX
|
||||
);
|
||||
const radian = parseRadian(angle - 270);
|
||||
|
||||
const centerMoveDist = moveVerticalDist / 2;
|
||||
|
|
@ -865,7 +930,7 @@ export function getSelectedListArea(
|
|||
const indexes: number[] = [];
|
||||
const uuids: string[] = [];
|
||||
const elements: Element<ElementType>[] = [];
|
||||
const { viewScaleInfo, viewSizeInfo, start, end } = opts;
|
||||
const { viewScaleInfo, start, end } = opts;
|
||||
|
||||
if (!(Array.isArray(data.elements) && start && end)) {
|
||||
return { indexes, uuids, elements };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/figma",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
"dist/**/*.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/types": "workspace:^0.4.0-beta.40",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.40",
|
||||
"kiwi-schema": "^0.5.0",
|
||||
"matrix-inverse": "^2.0.0",
|
||||
"pako": "^2.1.0",
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/pako": "^2.0.3",
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/types": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "idraw",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
|
@ -18,15 +18,14 @@
|
|||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"@idraw/board": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/core": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/renderer": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/core": "workspace:^0.4.0-beta.40",
|
||||
"@idraw/renderer": "workspace:^0.4.0-beta.40",
|
||||
"@idraw/types": "workspace:^0.4.0-beta.40",
|
||||
"@idraw/util": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Renderer } from '@idraw/renderer';
|
||||
import { Calculator } from '@idraw/board';
|
||||
import { createOffscreenContext2D } from '@idraw/util';
|
||||
import type { Data, LoadItemMap, ViewContext2D, ViewScaleInfo, ViewSizeInfo } from '@idraw/types';
|
||||
|
||||
|
|
@ -26,10 +25,9 @@ export type ExportImageFileResult = {
|
|||
export async function exportImageFileBlobURL(opts: ExportImageFileOptions): Promise<ExportImageFileResult> {
|
||||
const { data, width, height, devicePixelRatio, viewScaleInfo, viewSizeInfo, loadItemMap } = opts;
|
||||
let viewContext: ViewContext2D | null = createOffscreenContext2D({ width, height, devicePixelRatio });
|
||||
let calculator: Calculator | null = new Calculator({ viewContext });
|
||||
// let calculator: Calculator | null = new Calculator({ viewContext });
|
||||
let renderer: Renderer | null = new Renderer({
|
||||
viewContext,
|
||||
calculator
|
||||
viewContext
|
||||
});
|
||||
renderer.setLoadItemMap(loadItemMap);
|
||||
renderer.drawData(data, {
|
||||
|
|
@ -46,7 +44,6 @@ export async function exportImageFileBlobURL(opts: ExportImageFileOptions): Prom
|
|||
|
||||
offScreenCanvas = null;
|
||||
viewContext = null;
|
||||
calculator = null;
|
||||
renderer = null;
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import type {
|
|||
Element,
|
||||
RecursivePartial,
|
||||
ElementPosition,
|
||||
IDrawStorage
|
||||
IDrawStorage,
|
||||
DataLayout
|
||||
} from '@idraw/types';
|
||||
import {
|
||||
createElement,
|
||||
|
|
@ -25,9 +26,17 @@ import {
|
|||
filterCompactData,
|
||||
calcViewCenterContent,
|
||||
calcViewCenter,
|
||||
Store
|
||||
Store,
|
||||
merge
|
||||
} from '@idraw/util';
|
||||
import { defaultSettings, getDefaultStorage, defaultMode, parseStyles, parseSettings } from './setting/config';
|
||||
import {
|
||||
defaultSettings,
|
||||
defaultOptions,
|
||||
getDefaultStorage,
|
||||
defaultMode,
|
||||
parseStyles,
|
||||
parseSettings
|
||||
} from './setting/config';
|
||||
import { exportImageFileBlobURL } from './file';
|
||||
import type { ExportImageFileBaseOptions, ExportImageFileResult } from './file';
|
||||
import type { IDrawEvent } from './event';
|
||||
|
|
@ -42,10 +51,10 @@ export class iDraw {
|
|||
});
|
||||
|
||||
constructor(mount: HTMLDivElement, options: IDrawOptions) {
|
||||
const opts = { ...defaultSettings, ...options };
|
||||
const opts = { ...defaultSettings, ...defaultOptions, ...options };
|
||||
this.#store.set('middlewareStyles', parseStyles(opts));
|
||||
const { width, height, devicePixelRatio, createCustomContext2D } = opts;
|
||||
const core = new Core<IDrawEvent>(mount, { width, height, devicePixelRatio, createCustomContext2D });
|
||||
const { width, height, devicePixelRatio } = opts;
|
||||
const core = new Core<IDrawEvent>(mount, { width, height, devicePixelRatio });
|
||||
this.#core = core;
|
||||
this.#opts = opts;
|
||||
this.#init();
|
||||
|
|
@ -85,7 +94,7 @@ export class iDraw {
|
|||
const store = this.#store;
|
||||
const { mode, styles } = parseSettings(opts);
|
||||
let needFresh = false;
|
||||
let newOpts: IDrawSettings = {};
|
||||
const newOpts: IDrawSettings = {};
|
||||
store.clear();
|
||||
if (mode) {
|
||||
changeMode(mode, core, store);
|
||||
|
|
@ -181,20 +190,20 @@ export class iDraw {
|
|||
this.#core.trigger(name, e as IDrawEvent[T]);
|
||||
}
|
||||
|
||||
selectElement(uuid: string) {
|
||||
this.selectElements([uuid]);
|
||||
selectElement(uuid: string, opts?: { type?: string }) {
|
||||
this.trigger(coreEventKeys.SELECT, { uuids: [uuid], type: opts?.type || 'selectElement' });
|
||||
}
|
||||
|
||||
selectElements(uuids: string[]) {
|
||||
this.trigger(coreEventKeys.SELECT, { uuids });
|
||||
selectElements(uuids: string[], opts?: { type?: string }) {
|
||||
this.trigger(coreEventKeys.SELECT, { uuids, type: opts?.type || 'selectElements' });
|
||||
}
|
||||
|
||||
selectElementByPosition(position: ElementPosition) {
|
||||
this.selectElementsByPositions([position]);
|
||||
selectElementByPosition(position: ElementPosition, opts?: { type?: string }) {
|
||||
this.trigger(coreEventKeys.SELECT, { positions: [position], type: opts?.type || 'selectElementByPosition' });
|
||||
}
|
||||
|
||||
selectElementsByPositions(positions: ElementPosition[]) {
|
||||
this.trigger(coreEventKeys.SELECT, { positions });
|
||||
selectElementsByPositions(positions: ElementPosition[], opts?: { type?: string }) {
|
||||
this.trigger(coreEventKeys.SELECT, { positions, type: opts?.type || 'selectElementsByPositions' });
|
||||
}
|
||||
|
||||
cancelElements() {
|
||||
|
|
@ -230,6 +239,14 @@ export class iDraw {
|
|||
core.trigger(coreEventKeys.CHANGE, { data, type: 'updateElement' });
|
||||
}
|
||||
|
||||
updateElementName(uuid: string, name: string) {
|
||||
const core = this.#core;
|
||||
const data: Data = core.getData() || { elements: [] };
|
||||
updateElementInList(uuid, { name }, data.elements);
|
||||
core.setData(data);
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'updateElementName' });
|
||||
}
|
||||
|
||||
addElement(
|
||||
element: Element,
|
||||
opts?: {
|
||||
|
|
@ -241,7 +258,7 @@ export class iDraw {
|
|||
if (!opts || !opts?.position?.length) {
|
||||
data.elements.push(element);
|
||||
} else if (opts?.position) {
|
||||
const position = [...opts?.position];
|
||||
const position = [...(opts?.position || [])];
|
||||
insertElementToListByPosition(element, position, data.elements);
|
||||
}
|
||||
core.setData(data);
|
||||
|
|
@ -270,6 +287,15 @@ export class iDraw {
|
|||
core.trigger(coreEventKeys.CHANGE, { data, type: 'moveElement' });
|
||||
}
|
||||
|
||||
updateLayout(layout: Partial<DataLayout>) {
|
||||
const core = this.#core;
|
||||
const data: Data = core.getData() || { elements: [] };
|
||||
data.layout = merge(data.layout || {}, layout) as DataLayout;
|
||||
core.setData(data);
|
||||
core.refresh();
|
||||
core.trigger(coreEventKeys.CHANGE, { data, type: 'updateLayout' });
|
||||
}
|
||||
|
||||
async getImageBlobURL(opts?: ExportImageFileBaseOptions): Promise<ExportImageFileResult> {
|
||||
const data = this.getData() || { elements: [] };
|
||||
const { devicePixelRatio } = opts || { devicePixelRatio: 1 };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
export type * from '@idraw/types';
|
||||
export { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler, MiddlewareRuler, MiddlewareTextEditor, coreEventKeys } from '@idraw/core';
|
||||
export { Sharer, Calculator } from '@idraw/board';
|
||||
export {
|
||||
Sharer,
|
||||
Calculator,
|
||||
Core,
|
||||
MiddlewareSelector,
|
||||
MiddlewareScroller,
|
||||
MiddlewareScaler,
|
||||
MiddlewareRuler,
|
||||
MiddlewareTextEditor,
|
||||
coreEventKeys
|
||||
} from '@idraw/core';
|
||||
export { Renderer } from '@idraw/renderer';
|
||||
export {
|
||||
delay,
|
||||
|
|
@ -23,6 +32,7 @@ export {
|
|||
isAssetId,
|
||||
createAssetId,
|
||||
deepClone,
|
||||
deepCloneData,
|
||||
sortDataAsserts,
|
||||
istype,
|
||||
loadImage,
|
||||
|
|
@ -111,10 +121,10 @@ export {
|
|||
modifyElement,
|
||||
calcElementViewRectInfo,
|
||||
calcElementOriginRectInfo,
|
||||
calcElementViewRectInfoMap,
|
||||
sortElementsViewVisiableInfoMap,
|
||||
flatElementList,
|
||||
calcPointMoveElementInGroup
|
||||
calcPointMoveElementInGroup,
|
||||
merge,
|
||||
omit
|
||||
} from '@idraw/util';
|
||||
export { iDraw } from './idraw';
|
||||
export { eventKeys } from './event';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { IDrawSettings, IDrawStorage, IDrawMode } from '@idraw/types';
|
||||
import type { IDrawSettings, IDrawOptions, IDrawStorage, IDrawMode } from '@idraw/types';
|
||||
import { istype } from '@idraw/util';
|
||||
|
||||
export const defaultMode: IDrawMode = 'select';
|
||||
|
|
@ -7,6 +7,10 @@ export const defaultSettings: Required<Pick<IDrawSettings, 'mode'>> = {
|
|||
mode: defaultMode
|
||||
};
|
||||
|
||||
export const defaultOptions: Required<Pick<IDrawOptions, 'devicePixelRatio'>> = {
|
||||
devicePixelRatio: window.devicePixelRatio
|
||||
};
|
||||
|
||||
export function getDefaultStorage(): IDrawStorage {
|
||||
const storage: IDrawStorage = {
|
||||
mode: defaultMode,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/renderer",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
|
@ -18,14 +18,14 @@
|
|||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@idraw/types": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/types": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"@idraw/util": "workspace:^0.4.0-beta.39"
|
||||
"@idraw/util": "workspace:^0.4.0-beta.40"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
|
|
@ -7,34 +7,34 @@ import type {
|
|||
ViewCalculatorOptions,
|
||||
ViewScaleInfo,
|
||||
ViewSizeInfo,
|
||||
ViewCalculatorStorage,
|
||||
VirtualFlatStorage,
|
||||
ViewRectInfo,
|
||||
ModifyOptions,
|
||||
ViewVisibleInfo
|
||||
VirtualFlatItem
|
||||
} from '@idraw/types';
|
||||
import {
|
||||
is,
|
||||
isViewPointInElement,
|
||||
getViewPointAtElement,
|
||||
Store,
|
||||
sortElementsViewVisiableInfoMap,
|
||||
updateViewVisibleInfoMapStatus,
|
||||
calcViewPointSize,
|
||||
findElementFromListByPosition,
|
||||
getGroupQueueByElementPosition,
|
||||
calcElementOriginRectInfo,
|
||||
originRectInfoToRangeRectInfo
|
||||
// elementToBoxInfo
|
||||
} from '@idraw/util';
|
||||
import { sortElementsViewVisiableInfoMap, updateVirtualFlatItemMapStatus } from './view-visible';
|
||||
import { calcVirtualFlatDetail } from './virtual-flat';
|
||||
|
||||
export class Calculator implements ViewCalculator {
|
||||
#opts: ViewCalculatorOptions;
|
||||
#store: Store<ViewCalculatorStorage>;
|
||||
#store: Store<VirtualFlatStorage>;
|
||||
|
||||
constructor(opts: ViewCalculatorOptions) {
|
||||
this.#opts = opts;
|
||||
this.#store = new Store<ViewCalculatorStorage>({
|
||||
this.#store = new Store<VirtualFlatStorage>({
|
||||
defaultStorage: {
|
||||
viewVisibleInfoMap: {},
|
||||
virtualFlatItemMap: {},
|
||||
visibleCount: 0,
|
||||
invisibleCount: 0
|
||||
}
|
||||
|
|
@ -55,36 +55,23 @@ export class Calculator implements ViewCalculator {
|
|||
}
|
||||
|
||||
needRender(elem: Element<ElementType>): boolean {
|
||||
const viewVisibleInfoMap = this.#store.get('viewVisibleInfoMap');
|
||||
const info = viewVisibleInfoMap[elem.uuid];
|
||||
const virtualFlatItemMap = this.#store.get('virtualFlatItemMap');
|
||||
const info = virtualFlatItemMap[elem.uuid];
|
||||
if (!info) {
|
||||
return true;
|
||||
}
|
||||
return info.isVisibleInView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
isPointInElement(p: Point, elem: Element<ElementType>, viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo): boolean {
|
||||
const context2d = this.#opts.viewContext;
|
||||
return isViewPointInElement(p, {
|
||||
context2d,
|
||||
element: elem,
|
||||
viewScaleInfo,
|
||||
viewSizeInfo
|
||||
});
|
||||
}
|
||||
|
||||
getPointElement(
|
||||
p: Point,
|
||||
opts: { data: Data; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }
|
||||
): { index: number; element: null | Element<ElementType>; groupQueueIndex: number } {
|
||||
const context2d = this.#opts.viewContext;
|
||||
const context2d = this.#opts.tempContext;
|
||||
return getViewPointAtElement(p, { ...opts, ...{ context2d } });
|
||||
}
|
||||
|
||||
resetViewVisibleInfoMap(
|
||||
resetVirtualFlatItemMap(
|
||||
data: Data,
|
||||
opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
|
|
@ -92,16 +79,24 @@ export class Calculator implements ViewCalculator {
|
|||
}
|
||||
): void {
|
||||
if (data) {
|
||||
const { viewVisibleInfoMap, invisibleCount, visibleCount } = sortElementsViewVisiableInfoMap(data.elements, opts);
|
||||
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
|
||||
const { virtualFlatItemMap, invisibleCount, visibleCount } = sortElementsViewVisiableInfoMap(data.elements, {
|
||||
...opts,
|
||||
...{
|
||||
tempContext: this.#opts.tempContext
|
||||
}
|
||||
});
|
||||
this.#store.set('virtualFlatItemMap', virtualFlatItemMap);
|
||||
this.#store.set('invisibleCount', invisibleCount);
|
||||
this.#store.set('visibleCount', visibleCount);
|
||||
}
|
||||
}
|
||||
|
||||
updateVisiableStatus(opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }) {
|
||||
const { viewVisibleInfoMap, invisibleCount, visibleCount } = updateViewVisibleInfoMapStatus(this.#store.get('viewVisibleInfoMap'), opts);
|
||||
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
|
||||
const { virtualFlatItemMap, invisibleCount, visibleCount } = updateVirtualFlatItemMapStatus(
|
||||
this.#store.get('virtualFlatItemMap'),
|
||||
opts
|
||||
);
|
||||
this.#store.set('virtualFlatItemMap', virtualFlatItemMap);
|
||||
this.#store.set('invisibleCount', invisibleCount);
|
||||
this.#store.set('visibleCount', visibleCount);
|
||||
}
|
||||
|
|
@ -114,7 +109,7 @@ export class Calculator implements ViewCalculator {
|
|||
viewSizeInfo: ViewSizeInfo;
|
||||
}
|
||||
): ViewRectInfo | null {
|
||||
const infoData = this.#store.get('viewVisibleInfoMap')[uuid];
|
||||
const infoData = this.#store.get('virtualFlatItemMap')[uuid];
|
||||
if (!infoData?.originRectInfo) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -148,7 +143,7 @@ export class Calculator implements ViewCalculator {
|
|||
viewSizeInfo: ViewSizeInfo;
|
||||
}
|
||||
): ViewRectInfo | null {
|
||||
const infoData = this.#store.get('viewVisibleInfoMap')[uuid];
|
||||
const infoData = this.#store.get('virtualFlatItemMap')[uuid];
|
||||
if (!infoData?.originRectInfo) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -174,7 +169,7 @@ export class Calculator implements ViewCalculator {
|
|||
return viewRectInfo;
|
||||
}
|
||||
|
||||
modifyViewVisibleInfoMap(
|
||||
modifyVirtualFlatItemMap(
|
||||
data: Data,
|
||||
opts: {
|
||||
modifyOptions: ModifyOptions; // TODO
|
||||
|
|
@ -185,7 +180,7 @@ export class Calculator implements ViewCalculator {
|
|||
const { modifyOptions, viewScaleInfo, viewSizeInfo } = opts;
|
||||
const { type, content } = modifyOptions;
|
||||
const list = data.elements;
|
||||
const viewVisibleInfoMap = this.#store.get('viewVisibleInfoMap');
|
||||
const virtualFlatItemMap = this.#store.get('virtualFlatItemMap');
|
||||
if (type === 'deleteElement') {
|
||||
const { element } = content as ModifyOptions<'deleteElement'>['content'];
|
||||
const uuids: string[] = [];
|
||||
|
|
@ -199,13 +194,13 @@ export class Calculator implements ViewCalculator {
|
|||
};
|
||||
_walk(element);
|
||||
uuids.forEach((uuid) => {
|
||||
delete viewVisibleInfoMap[uuid];
|
||||
delete virtualFlatItemMap[uuid];
|
||||
});
|
||||
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
|
||||
this.#store.set('virtualFlatItemMap', virtualFlatItemMap);
|
||||
}
|
||||
// else if (type === 'updateElement') {
|
||||
// // TODO
|
||||
// this.resetViewVisibleInfoMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
// this.resetVirtualFlatItemMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
// }
|
||||
else if (type === 'addElement' || type === 'updateElement') {
|
||||
const { position } = content as ModifyOptions<'addElement'>['content'];
|
||||
|
|
@ -214,27 +209,35 @@ export class Calculator implements ViewCalculator {
|
|||
if (element) {
|
||||
if (type === 'updateElement' && element.type === 'group') {
|
||||
// TODO
|
||||
this.resetViewVisibleInfoMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
this.resetVirtualFlatItemMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
} else {
|
||||
const originRectInfo = calcElementOriginRectInfo(element, {
|
||||
groupQueue: groupQueue || []
|
||||
});
|
||||
const newViewVisibleInfo: ViewVisibleInfo = {
|
||||
const newVirtualFlatItem: VirtualFlatItem = {
|
||||
type: element.type,
|
||||
originRectInfo,
|
||||
rangeRectInfo: is.angle(element.angle) ? originRectInfoToRangeRectInfo(originRectInfo) : originRectInfo,
|
||||
isVisibleInView: true,
|
||||
isGroup: element?.type === 'group',
|
||||
position: [...position]
|
||||
position: [...position],
|
||||
...calcVirtualFlatDetail(element, {
|
||||
tempContext: this.#opts.tempContext
|
||||
})
|
||||
};
|
||||
viewVisibleInfoMap[element.uuid] = newViewVisibleInfo;
|
||||
this.#store.set('viewVisibleInfoMap', viewVisibleInfoMap);
|
||||
virtualFlatItemMap[element.uuid] = newVirtualFlatItem;
|
||||
this.#store.set('virtualFlatItemMap', virtualFlatItemMap);
|
||||
if (type === 'updateElement') {
|
||||
this.updateVisiableStatus({ viewScaleInfo, viewSizeInfo });
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type === 'moveElement') {
|
||||
this.resetViewVisibleInfoMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
this.resetVirtualFlatItemMap(data, { viewScaleInfo, viewSizeInfo });
|
||||
}
|
||||
}
|
||||
|
||||
getVirtualFlatItem(uuid: string): VirtualFlatItem | null {
|
||||
const itemMap = this.#store.get('virtualFlatItemMap');
|
||||
return itemMap[uuid] || null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,25 @@
|
|||
import { ViewContext2D, Element, ElementType, ElementSize, ViewScaleInfo, ViewSizeInfo, TransformAction } from '@idraw/types';
|
||||
import { istype, isColorStr, generateSVGPath, rotateElement, is, getDefaultElementDetailConfig, calcViewBoxSize } from '@idraw/util';
|
||||
import {
|
||||
ViewContext2D,
|
||||
Element,
|
||||
ElementType,
|
||||
ElementSize,
|
||||
ViewScaleInfo,
|
||||
ViewSizeInfo,
|
||||
TransformAction
|
||||
// PointSize
|
||||
} from '@idraw/types';
|
||||
import {
|
||||
istype,
|
||||
isColorStr,
|
||||
generateSVGPath,
|
||||
rotateElement,
|
||||
is,
|
||||
getDefaultElementDetailConfig,
|
||||
calcViewBoxSize
|
||||
// elementToBoxInfo,
|
||||
// calcViewPointSize
|
||||
} from '@idraw/util';
|
||||
import { Calculator } from '../calculator';
|
||||
import { createColorStyle } from './color';
|
||||
|
||||
const defaultElemConfig = getDefaultElementDetailConfig();
|
||||
|
|
@ -35,7 +55,7 @@ export function drawBox(
|
|||
ctx.globalAlpha = opacity;
|
||||
drawBoxBackground(ctx, viewElem, { pattern, viewScaleInfo, viewSizeInfo });
|
||||
renderContent?.();
|
||||
drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
|
||||
drawBoxBorder(ctx, viewElem, { originElem, viewScaleInfo, viewSizeInfo });
|
||||
ctx.globalAlpha = parentOpacity;
|
||||
};
|
||||
if (clipPath) {
|
||||
|
|
@ -122,7 +142,14 @@ function drawClipPathStroke(
|
|||
const { renderContent, originElem, calcElemSize, viewSizeInfo, parentOpacity } = opts;
|
||||
const totalScale = viewSizeInfo.devicePixelRatio;
|
||||
const { clipPath, clipPathStrokeColor, clipPathStrokeWidth } = originElem?.detail || {};
|
||||
if (clipPath && calcElemSize && clipPath.commands && typeof clipPathStrokeWidth === 'number' && clipPathStrokeWidth > 0 && clipPathStrokeColor) {
|
||||
if (
|
||||
clipPath &&
|
||||
calcElemSize &&
|
||||
clipPath.commands &&
|
||||
typeof clipPathStrokeWidth === 'number' &&
|
||||
clipPathStrokeWidth > 0 &&
|
||||
clipPathStrokeColor
|
||||
) {
|
||||
const { x, y, w, h } = calcElemSize;
|
||||
const { originW, originH, originX, originY } = clipPath;
|
||||
const scaleW = w / originW;
|
||||
|
|
@ -217,7 +244,11 @@ export function drawBoxBackground(
|
|||
}
|
||||
}
|
||||
|
||||
export function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): void {
|
||||
export function drawBoxBorder(
|
||||
ctx: ViewContext2D,
|
||||
viewElem: Element<ElementType>,
|
||||
opts: { originElem: Element; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo; calculator?: Calculator }
|
||||
): void {
|
||||
if (viewElem.detail.borderWidth === 0) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -230,12 +261,18 @@ export function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>
|
|||
if (isColorStr(viewElem.detail.borderColor) === true) {
|
||||
borderColor = viewElem.detail.borderColor as string;
|
||||
}
|
||||
const { borderWidth, borderRadius, borderDash, boxSizing = defaultElemConfig.boxSizing } = viewElem.detail;
|
||||
let bw: number = 0;
|
||||
if (typeof borderWidth === 'number') {
|
||||
bw = borderWidth || 1;
|
||||
|
||||
const { borderDash, borderWidth, borderRadius, boxSizing = defaultElemConfig.boxSizing } = viewElem.detail;
|
||||
let viewBorderDash: number[] = [];
|
||||
if (Array.isArray(borderDash) && borderDash.length > 0) {
|
||||
viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
|
||||
}
|
||||
bw = bw * scale;
|
||||
if (viewBorderDash.length > 0) {
|
||||
ctx.lineCap = 'butt';
|
||||
} else {
|
||||
ctx.lineCap = 'square';
|
||||
}
|
||||
|
||||
let radiusList: [number, number, number, number] = [0, 0, 0, 0];
|
||||
if (typeof borderRadius === 'number') {
|
||||
const br = borderRadius * scale;
|
||||
|
|
@ -243,11 +280,75 @@ export function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>
|
|||
} else if (Array.isArray(borderRadius) && borderRadius?.length === 4) {
|
||||
radiusList = [borderRadius[0] * scale, borderRadius[1] * scale, borderRadius[2] * scale, borderRadius[3] * scale];
|
||||
}
|
||||
ctx.strokeStyle = borderColor;
|
||||
let viewBorderDash: number[] = [];
|
||||
if (Array.isArray(borderDash) && borderDash.length > 0) {
|
||||
viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
|
||||
|
||||
// // TODO
|
||||
// const boxInfo = elementToBoxInfo(opts.originElem);
|
||||
// const calcViewOpts = { viewScaleInfo, viewSizeInfo: opts.viewSizeInfo };
|
||||
// const op0: PointSize = calcViewPointSize(boxInfo.op0, calcViewOpts);
|
||||
// const op1: PointSize = calcViewPointSize(boxInfo.op1, calcViewOpts);
|
||||
// const op2: PointSize = calcViewPointSize(boxInfo.op2, calcViewOpts);
|
||||
// const op3: PointSize = calcViewPointSize(boxInfo.op3, calcViewOpts);
|
||||
// const op0s: PointSize = calcViewPointSize(boxInfo.op0s, calcViewOpts);
|
||||
// const op0e: PointSize = calcViewPointSize(boxInfo.op0e, calcViewOpts);
|
||||
// const op1s: PointSize = calcViewPointSize(boxInfo.op1s, calcViewOpts);
|
||||
// const op1e: PointSize = calcViewPointSize(boxInfo.op1e, calcViewOpts);
|
||||
// const op2s: PointSize = calcViewPointSize(boxInfo.op2s, calcViewOpts);
|
||||
// const op2e: PointSize = calcViewPointSize(boxInfo.op2e, calcViewOpts);
|
||||
// const op3s: PointSize = calcViewPointSize(boxInfo.op3s, calcViewOpts);
|
||||
// const op3e: PointSize = calcViewPointSize(boxInfo.op3e, calcViewOpts);
|
||||
|
||||
// const ip0: PointSize = calcViewPointSize(boxInfo.ip0, calcViewOpts);
|
||||
// const ip1: PointSize = calcViewPointSize(boxInfo.ip1, calcViewOpts);
|
||||
// const ip2: PointSize = calcViewPointSize(boxInfo.ip2, calcViewOpts);
|
||||
// const ip3: PointSize = calcViewPointSize(boxInfo.ip3, calcViewOpts);
|
||||
// const ip0s: PointSize = calcViewPointSize(boxInfo.ip0s, calcViewOpts);
|
||||
// const ip0e: PointSize = calcViewPointSize(boxInfo.ip0e, calcViewOpts);
|
||||
// const ip1s: PointSize = calcViewPointSize(boxInfo.ip1s, calcViewOpts);
|
||||
// const ip1e: PointSize = calcViewPointSize(boxInfo.ip1e, calcViewOpts);
|
||||
// const ip2s: PointSize = calcViewPointSize(boxInfo.ip2s, calcViewOpts);
|
||||
// const ip2e: PointSize = calcViewPointSize(boxInfo.ip2e, calcViewOpts);
|
||||
// const ip3s: PointSize = calcViewPointSize(boxInfo.ip3s, calcViewOpts);
|
||||
// const ip3e: PointSize = calcViewPointSize(boxInfo.ip3e, calcViewOpts);
|
||||
|
||||
// ctx.fillStyle = borderColor;
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(op0s.x, op0s.y);
|
||||
// ctx.quadraticCurveTo(op0.x, op0.y, op0e.x, op0e.y);
|
||||
// ctx.lineTo(op1s.x, op1s.y);
|
||||
// ctx.quadraticCurveTo(op1.x, op1.y, op1e.x, op1e.y);
|
||||
// ctx.lineTo(op2s.x, op2s.y);
|
||||
// ctx.quadraticCurveTo(op2.x, op2.y, op2e.x, op2e.y);
|
||||
// ctx.lineTo(op3s.x, op3s.y);
|
||||
// ctx.quadraticCurveTo(op3.x, op3.y, op3e.x, op3e.y);
|
||||
// ctx.lineTo(op0s.x, op0s.y);
|
||||
// ctx.closePath();
|
||||
// ctx.fill();
|
||||
|
||||
// ctx.fillStyle = '#000000';
|
||||
// ctx.globalCompositeOperation = 'destination-out';
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(ip0s.x, ip0s.y);
|
||||
// ctx.quadraticCurveTo(ip0.x, ip0.y, ip0e.x, ip0e.y);
|
||||
// ctx.lineTo(ip1s.x, ip1s.y);
|
||||
// ctx.quadraticCurveTo(ip1.x, ip1.y, ip1e.x, ip1e.y);
|
||||
// ctx.lineTo(ip2s.x, ip2s.y);
|
||||
// ctx.quadraticCurveTo(ip2.x, ip2.y, ip2e.x, ip2e.y);
|
||||
// ctx.lineTo(ip3s.x, ip3s.y);
|
||||
// ctx.quadraticCurveTo(ip3.x, ip3.y, ip3e.x, ip3e.y);
|
||||
// ctx.lineTo(ip0s.x, ip0s.y);
|
||||
// ctx.closePath();
|
||||
// ctx.fill();
|
||||
// ctx.globalCompositeOperation = 'source-over';
|
||||
// return;
|
||||
// // TODO
|
||||
|
||||
let bw: number = 0;
|
||||
if (typeof borderWidth === 'number') {
|
||||
bw = borderWidth || 1;
|
||||
}
|
||||
bw = bw * scale;
|
||||
|
||||
ctx.strokeStyle = borderColor;
|
||||
|
||||
let borderTop = 0;
|
||||
let borderRight = 0;
|
||||
|
|
@ -338,11 +439,6 @@ export function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>
|
|||
// if (r < w / 2 && r < h / 2) {
|
||||
// r = r + bw / 2;
|
||||
// }
|
||||
if (viewBorderDash.length > 0) {
|
||||
ctx.lineCap = 'butt';
|
||||
} else {
|
||||
ctx.lineCap = 'square';
|
||||
}
|
||||
|
||||
// TODO
|
||||
w = Math.max(w, 1);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re
|
|||
const radiusB = b;
|
||||
if (bw > 0) {
|
||||
if (boxSizing === 'content-box') {
|
||||
a = a;
|
||||
b = b;
|
||||
// a = a;
|
||||
// b = b;
|
||||
} else if (boxSizing === 'center-line') {
|
||||
a = a - bw / 2;
|
||||
b = b - bw / 2;
|
||||
|
|
|
|||
|
|
@ -72,13 +72,15 @@ export function drawElement(ctx: ViewContext2D, elem: Element<ElementType>, opts
|
|||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export function drawGroup(ctx: ViewContext2D, elem: Element<'group'>, opts: RendererDrawElementOptions) {
|
||||
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
|
||||
const { x, y, w, h, angle } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, { viewScaleInfo }) || elem;
|
||||
const { x, y, w, h, angle } =
|
||||
calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, { viewScaleInfo }) || elem;
|
||||
const viewElem = { ...elem, ...{ x, y, w, h, angle } };
|
||||
rotateElement(ctx, { x, y, w, h, angle }, () => {
|
||||
ctx.globalAlpha = getOpacity(elem) * parentOpacity;
|
||||
|
|
@ -141,6 +143,7 @@ export function drawGroup(ctx: ViewContext2D, elem: Element<'group'>, opts: Rend
|
|||
try {
|
||||
drawElement(ctx, child, { ...opts, ...{ parentOpacity: parentOpacity * getOpacity(elem) } });
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@ import type { RendererDrawElementOptions, ViewContext2D, DataLayout, Element } f
|
|||
import { calcViewElementSize, calcViewBoxSize } from '@idraw/util';
|
||||
import { drawBoxShadow, drawBoxBackground, drawBoxBorder } from './box';
|
||||
|
||||
export function drawLayout(ctx: ViewContext2D, layout: DataLayout, opts: RendererDrawElementOptions, renderContent: (ctx: ViewContext2D) => void) {
|
||||
export function drawLayout(
|
||||
ctx: ViewContext2D,
|
||||
layout: DataLayout,
|
||||
opts: RendererDrawElementOptions,
|
||||
renderContent: (ctx: ViewContext2D) => void
|
||||
) {
|
||||
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
|
||||
const elem: Element = { uuid: 'layout', type: 'group', ...layout } as Element;
|
||||
const { x, y, w, h } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
|
||||
|
|
@ -46,6 +51,6 @@ export function drawLayout(ctx: ViewContext2D, layout: DataLayout, opts: Rendere
|
|||
ctx.restore();
|
||||
}
|
||||
|
||||
drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
|
||||
drawBoxBorder(ctx, viewElem, { originElem: elem, viewScaleInfo, viewSizeInfo });
|
||||
ctx.globalAlpha = parentOpacity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,18 +5,8 @@ import { drawBox, drawBoxShadow } from './box';
|
|||
|
||||
const detailConfig = getDefaultElementDetailConfig();
|
||||
|
||||
// TODO
|
||||
function isTextWidthWithinErrorRange(w0: number, w1: number, scale: number): boolean {
|
||||
if (scale < 0.5) {
|
||||
if (w0 < w1 && (w0 - w1) / w0 > -0.15) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return w0 >= w1;
|
||||
}
|
||||
|
||||
export function drawText(ctx: ViewContext2D, elem: Element<'text'>, opts: RendererDrawElementOptions) {
|
||||
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
|
||||
const { viewScaleInfo, viewSizeInfo, parentOpacity, calculator } = opts;
|
||||
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
|
||||
const viewElem = { ...elem, ...{ x, y, w, h, angle } };
|
||||
rotateElement(ctx, { x, y, w, h, angle }, () => {
|
||||
|
|
@ -45,9 +35,6 @@ export function drawText(ctx: ViewContext2D, elem: Element<'text'>, opts: Render
|
|||
return;
|
||||
}
|
||||
|
||||
const originLineHeight = detail.lineHeight || originFontSize;
|
||||
const lineHeight = originLineHeight * viewScaleInfo.scale;
|
||||
|
||||
ctx.fillStyle = elem.detail.color || detailConfig.color;
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.$setFont({
|
||||
|
|
@ -55,143 +42,28 @@ export function drawText(ctx: ViewContext2D, elem: Element<'text'>, opts: Render
|
|||
fontSize: fontSize,
|
||||
fontFamily: enhanceFontFamliy(detail.fontFamily)
|
||||
});
|
||||
let detailText = detail.text.replace(/\r\n/gi, '\n');
|
||||
if (detail.textTransform === 'lowercase') {
|
||||
detailText = detailText.toLowerCase();
|
||||
} else if (detail.textTransform === 'uppercase') {
|
||||
detailText = detailText.toUpperCase();
|
||||
}
|
||||
|
||||
const fontHeight = lineHeight;
|
||||
const detailTextList = detailText.split('\n');
|
||||
const lines: { text: string; width: number }[] = [];
|
||||
|
||||
let lineNum = 0;
|
||||
detailTextList.forEach((itemText: string, idx: number) => {
|
||||
if (detail.minInlineSize === 'maxContent') {
|
||||
lines.push({
|
||||
text: itemText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(itemText).width)
|
||||
});
|
||||
} else {
|
||||
let lineText = '';
|
||||
let splitStr = '';
|
||||
let tempStrList: string[] = itemText.split(splitStr);
|
||||
if (detail.wordBreak === 'normal') {
|
||||
const splitStr = ' ';
|
||||
const wordList = itemText.split(splitStr);
|
||||
tempStrList = [];
|
||||
wordList.forEach((word: string, idx: number) => {
|
||||
tempStrList.push(word);
|
||||
if (idx < wordList.length - 1) {
|
||||
tempStrList.push(splitStr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (tempStrList.length === 1 && detail.overflow === 'visible') {
|
||||
lines.push({
|
||||
text: tempStrList[0],
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(tempStrList[0]).width)
|
||||
});
|
||||
} else if (tempStrList.length > 0) {
|
||||
for (let i = 0; i < tempStrList.length; i++) {
|
||||
if (isTextWidthWithinErrorRange(ctx.$doPixelRatio(w), ctx.measureText(lineText + tempStrList[i]).width, viewScaleInfo.scale)) {
|
||||
lineText += tempStrList[i] || '';
|
||||
} else {
|
||||
lines.push({
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
lineText = tempStrList[i] || '';
|
||||
lineNum++;
|
||||
}
|
||||
if ((lineNum + 1) * fontHeight > h && detail.overflow === 'hidden') {
|
||||
break;
|
||||
}
|
||||
if (tempStrList.length - 1 === i) {
|
||||
if ((lineNum + 1) * fontHeight <= h) {
|
||||
lines.push({
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
if (idx < detailTextList.length - 1) {
|
||||
lineNum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push({
|
||||
text: '',
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let startY = 0;
|
||||
let eachLineStartY = 0;
|
||||
if (fontHeight > fontSize) {
|
||||
eachLineStartY = (fontHeight - fontSize) / 2;
|
||||
}
|
||||
if (lines.length * fontHeight < h) {
|
||||
if (elem.detail.verticalAlign === 'top') {
|
||||
startY = 0;
|
||||
} else if (elem.detail.verticalAlign === 'bottom') {
|
||||
startY += h - lines.length * fontHeight;
|
||||
} else {
|
||||
// middle and default
|
||||
startY += (h - lines.length * fontHeight) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// draw text lines
|
||||
{
|
||||
const _y = y + startY;
|
||||
if (detail.textShadowColor !== undefined && isColorStr(detail.textShadowColor)) {
|
||||
ctx.shadowColor = detail.textShadowColor;
|
||||
}
|
||||
if (detail.textShadowOffsetX !== undefined && is.number(detail.textShadowOffsetX)) {
|
||||
ctx.shadowOffsetX = detail.textShadowOffsetX;
|
||||
}
|
||||
if (detail.textShadowOffsetY !== undefined && is.number(detail.textShadowOffsetY)) {
|
||||
ctx.shadowOffsetY = detail.textShadowOffsetY;
|
||||
}
|
||||
if (detail.textShadowBlur !== undefined && is.number(detail.textShadowBlur)) {
|
||||
ctx.shadowBlur = detail.textShadowBlur;
|
||||
}
|
||||
lines.forEach((line, i) => {
|
||||
let _x = x;
|
||||
if (detail.textAlign === 'center') {
|
||||
_x = x + (w - line.width) / 2;
|
||||
} else if (detail.textAlign === 'right') {
|
||||
_x = x + (w - line.width);
|
||||
const virtualTextDetail = calculator.getVirtualFlatItem(elem.uuid);
|
||||
if (Array.isArray(virtualTextDetail?.textLines) && virtualTextDetail?.textLines?.length > 0) {
|
||||
if (detail.textShadowColor !== undefined && isColorStr(detail.textShadowColor)) {
|
||||
ctx.shadowColor = detail.textShadowColor;
|
||||
}
|
||||
if (detail.textShadowOffsetX !== undefined && is.number(detail.textShadowOffsetX)) {
|
||||
ctx.shadowOffsetX = detail.textShadowOffsetX;
|
||||
}
|
||||
if (detail.textShadowOffsetY !== undefined && is.number(detail.textShadowOffsetY)) {
|
||||
ctx.shadowOffsetY = detail.textShadowOffsetY;
|
||||
}
|
||||
if (detail.textShadowBlur !== undefined && is.number(detail.textShadowBlur)) {
|
||||
ctx.shadowBlur = detail.textShadowBlur;
|
||||
}
|
||||
ctx.fillText(line.text, _x, _y + fontHeight * i + eachLineStartY);
|
||||
});
|
||||
}
|
||||
|
||||
// // draw text stroke
|
||||
// if (isColorStr(detail.strokeColor) && detail.strokeWidth !== undefined && detail.strokeWidth > 0) {
|
||||
// const _y = y + startY;
|
||||
// lines.forEach((line, i) => {
|
||||
// let _x = x;
|
||||
// if (detail.textAlign === 'center') {
|
||||
// _x = x + (w - line.width) / 2;
|
||||
// } else if (detail.textAlign === 'right') {
|
||||
// _x = x + (w - line.width);
|
||||
// }
|
||||
// if (detail.strokeColor !== undefined) {
|
||||
// ctx.strokeStyle = detail.strokeColor;
|
||||
// }
|
||||
// if (detail.strokeWidth !== undefined && detail.strokeWidth > 0) {
|
||||
// ctx.lineWidth = detail.strokeWidth;
|
||||
// }
|
||||
// ctx.strokeText(line.text, _x, _y + fontHeight * i);
|
||||
// });
|
||||
// }
|
||||
virtualTextDetail?.textLines?.forEach((line) => {
|
||||
ctx.fillText(line.text, x + line.x * viewScaleInfo.scale, y + line.y * viewScaleInfo.scale);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,21 @@ import type { DataLayout, LoadItemMap } from '@idraw/types';
|
|||
import { drawElementList, drawLayout, drawGlobalBackground } from './draw/index';
|
||||
import { Loader } from './loader';
|
||||
import type { Data, BoardRenderer, RendererOptions, RendererEventMap, RendererDrawOptions } from '@idraw/types';
|
||||
import { Calculator } from './calculator';
|
||||
|
||||
export { Calculator };
|
||||
export class Renderer extends EventEmitter<RendererEventMap> implements BoardRenderer {
|
||||
#opts: RendererOptions;
|
||||
#loader: Loader = new Loader();
|
||||
#calculator: Calculator;
|
||||
#hasDestroyed: boolean = false;
|
||||
|
||||
constructor(opts: RendererOptions) {
|
||||
super();
|
||||
this.#opts = opts;
|
||||
this.#calculator = new Calculator({
|
||||
tempContext: opts.tempContext
|
||||
});
|
||||
this.#init();
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +51,8 @@ export class Renderer extends EventEmitter<RendererEventMap> implements BoardRen
|
|||
|
||||
drawData(data: Data, opts: RendererDrawOptions) {
|
||||
const loader = this.#loader;
|
||||
const { calculator, sharer } = this.#opts;
|
||||
const calculator = this.#calculator;
|
||||
const { sharer } = this.#opts;
|
||||
const viewContext = this.#opts.viewContext;
|
||||
viewContext.clearRect(0, 0, viewContext.canvas.width, viewContext.canvas.height);
|
||||
const parentElementSize = {
|
||||
|
|
@ -88,8 +95,18 @@ export class Renderer extends EventEmitter<RendererEventMap> implements BoardRen
|
|||
// TODO
|
||||
return;
|
||||
}
|
||||
const { data, offsetTop, offsetBottom, offsetLeft, offsetRight, width, height, contextHeight, contextWidth, devicePixelRatio } =
|
||||
sharer.getActiveStoreSnapshot();
|
||||
const {
|
||||
data,
|
||||
offsetTop,
|
||||
offsetBottom,
|
||||
offsetLeft,
|
||||
offsetRight,
|
||||
width,
|
||||
height,
|
||||
contextHeight,
|
||||
contextWidth,
|
||||
devicePixelRatio
|
||||
} = sharer.getActiveStoreSnapshot();
|
||||
if (data) {
|
||||
this.drawData(data, {
|
||||
viewScaleInfo: {
|
||||
|
|
@ -121,6 +138,10 @@ export class Renderer extends EventEmitter<RendererEventMap> implements BoardRen
|
|||
getLoader(): Loader {
|
||||
return this.#loader;
|
||||
}
|
||||
|
||||
getCalculator(): Calculator {
|
||||
return this.#calculator;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
|
|
|
|||
|
|
@ -1,61 +1,22 @@
|
|||
import { Element, ElementPosition, Elements, ViewScaleInfo, ViewSizeInfo, ViewRectInfo, ViewVisibleInfoMap, ViewVisibleInfo } from '@idraw/types';
|
||||
import { calcElementOriginRectInfo, originRectInfoToRangeRectInfo } from './view-calc';
|
||||
import { getGroupQueueByElementPosition } from './element';
|
||||
import { calcElementCenter } from './rotate';
|
||||
import { is } from './is';
|
||||
import { Elements, ViewScaleInfo, ViewSizeInfo, ViewRectInfo, VirtualFlatItemMap, ViewContext2D } from '@idraw/types';
|
||||
import { calcElementCenter } from '@idraw/util';
|
||||
import { elementsToVirtualFlatMap } from '../virtual-flat';
|
||||
|
||||
export function sortElementsViewVisiableInfoMap(
|
||||
elements: Elements,
|
||||
opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
tempContext: ViewContext2D;
|
||||
}
|
||||
): {
|
||||
viewVisibleInfoMap: ViewVisibleInfoMap;
|
||||
virtualFlatItemMap: VirtualFlatItemMap;
|
||||
visibleCount: number;
|
||||
invisibleCount: number;
|
||||
} {
|
||||
const visibleInfoMap: ViewVisibleInfoMap = {};
|
||||
const currentPosition: ElementPosition = [];
|
||||
|
||||
const _walk = (elem: Element) => {
|
||||
const baseInfo: Omit<ViewVisibleInfo, 'originRectInfo' | 'rangeRectInfo'> = {
|
||||
isVisibleInView: true,
|
||||
isGroup: elem.type === 'group',
|
||||
position: [...currentPosition]
|
||||
};
|
||||
let originRectInfo: ViewRectInfo | null = null;
|
||||
|
||||
const groupQueue = getGroupQueueByElementPosition(elements, currentPosition);
|
||||
|
||||
originRectInfo = calcElementOriginRectInfo(elem, {
|
||||
groupQueue: groupQueue || []
|
||||
});
|
||||
|
||||
visibleInfoMap[elem.uuid] = {
|
||||
...baseInfo,
|
||||
...{
|
||||
originRectInfo: originRectInfo as ViewRectInfo,
|
||||
rangeRectInfo: is.angle(elem.angle) ? originRectInfoToRangeRectInfo(originRectInfo as ViewRectInfo) : originRectInfo
|
||||
}
|
||||
};
|
||||
|
||||
if (elem.type === 'group') {
|
||||
(elem as Element<'group'>).detail.children.forEach((ele, i) => {
|
||||
currentPosition.push(i);
|
||||
_walk(ele);
|
||||
currentPosition.pop();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
elements.forEach((elem, index) => {
|
||||
currentPosition.push(index);
|
||||
_walk(elem);
|
||||
currentPosition.pop();
|
||||
});
|
||||
|
||||
return updateViewVisibleInfoMapStatus(visibleInfoMap, opts);
|
||||
const { viewScaleInfo, viewSizeInfo, tempContext } = opts;
|
||||
const visibleInfoMap: VirtualFlatItemMap = elementsToVirtualFlatMap(elements, { tempContext });
|
||||
return updateVirtualFlatItemMapStatus(visibleInfoMap, { viewScaleInfo, viewSizeInfo });
|
||||
}
|
||||
|
||||
function isRangeRectInfoCollide(info1: ViewRectInfo, info2: ViewRectInfo): boolean {
|
||||
|
|
@ -79,10 +40,10 @@ function isRangeRectInfoCollide(info1: ViewRectInfo, info2: ViewRectInfo): boole
|
|||
return false;
|
||||
}
|
||||
|
||||
// function logViewVisibleInfoMapStatus(viewVisibleInfoMap: ViewVisibleInfoMap) {
|
||||
// function logVirtualFlatItemMapStatus(virtualFlatItemMap: VirtualFlatItemMap) {
|
||||
// console.log('------------------------------------------------');
|
||||
// Object.keys(viewVisibleInfoMap).forEach((uuid) => {
|
||||
// const item = viewVisibleInfoMap[uuid];
|
||||
// Object.keys(virtualFlatItemMap).forEach((uuid) => {
|
||||
// const item = virtualFlatItemMap[uuid];
|
||||
// const info = item.originRectInfo;
|
||||
// const rect = {
|
||||
// x: info.topLeft.x,
|
||||
|
|
@ -94,31 +55,34 @@ function isRangeRectInfoCollide(info1: ViewRectInfo, info2: ViewRectInfo): boole
|
|||
// });
|
||||
// }
|
||||
|
||||
export function updateViewVisibleInfoMapStatus(
|
||||
viewVisibleInfoMap: ViewVisibleInfoMap,
|
||||
export function updateVirtualFlatItemMapStatus(
|
||||
virtualFlatItemMap: VirtualFlatItemMap,
|
||||
opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }
|
||||
): {
|
||||
viewVisibleInfoMap: ViewVisibleInfoMap;
|
||||
virtualFlatItemMap: VirtualFlatItemMap;
|
||||
visibleCount: number;
|
||||
invisibleCount: number;
|
||||
} {
|
||||
const canvasRectInfo = calcVisibleOriginCanvasRectInfo(opts);
|
||||
let visibleCount = 0;
|
||||
let invisibleCount = 0;
|
||||
Object.keys(viewVisibleInfoMap).forEach((uuid) => {
|
||||
const info = viewVisibleInfoMap[uuid];
|
||||
Object.keys(virtualFlatItemMap).forEach((uuid) => {
|
||||
const info = virtualFlatItemMap[uuid];
|
||||
info.isVisibleInView = isRangeRectInfoCollide(info.rangeRectInfo, canvasRectInfo);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
info.isVisibleInView ? visibleCount++ : invisibleCount++;
|
||||
});
|
||||
|
||||
// logViewVisibleInfoMapStatus(viewVisibleInfoMap);
|
||||
// logVirtualFlatItemMapStatus(virtualFlatItemMap);
|
||||
|
||||
return { viewVisibleInfoMap, visibleCount, invisibleCount };
|
||||
return { virtualFlatItemMap, visibleCount, invisibleCount };
|
||||
}
|
||||
|
||||
export function calcVisibleOriginCanvasRectInfo(opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewRectInfo {
|
||||
export function calcVisibleOriginCanvasRectInfo(opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
}): ViewRectInfo {
|
||||
const { viewScaleInfo, viewSizeInfo } = opts;
|
||||
// console.log('xxx ===== ', viewScaleInfo, viewSizeInfo);
|
||||
const { scale, offsetTop, offsetLeft } = viewScaleInfo;
|
||||
const { width, height } = viewSizeInfo;
|
||||
|
||||
75
packages/renderer/src/virtual-flat/index.ts
Normal file
75
packages/renderer/src/virtual-flat/index.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import {
|
||||
Element,
|
||||
ElementPosition,
|
||||
Elements,
|
||||
ViewRectInfo,
|
||||
VirtualFlatItemMap,
|
||||
VirtualFlatItem,
|
||||
VirtualFlatDetail,
|
||||
ViewContext2D
|
||||
} from '@idraw/types';
|
||||
import {
|
||||
is,
|
||||
getGroupQueueByElementPosition,
|
||||
calcElementOriginRectInfo,
|
||||
originRectInfoToRangeRectInfo
|
||||
} from '@idraw/util';
|
||||
|
||||
import { calcVirtualTextDetail } from './text';
|
||||
|
||||
export function calcVirtualFlatDetail(elem: Element, opts: { tempContext: ViewContext2D }): VirtualFlatDetail {
|
||||
let virtualDetail: VirtualFlatDetail = {};
|
||||
if (elem.type === 'text') {
|
||||
virtualDetail = calcVirtualTextDetail(elem as Element<'text'>, opts);
|
||||
}
|
||||
return virtualDetail;
|
||||
}
|
||||
|
||||
export function elementsToVirtualFlatMap(elements: Elements, opts: { tempContext: ViewContext2D }): VirtualFlatItemMap {
|
||||
const virtualFlatMap: VirtualFlatItemMap = {};
|
||||
const currentPosition: ElementPosition = [];
|
||||
|
||||
const _walk = (elem: Element) => {
|
||||
const baseInfo: Omit<VirtualFlatItem, 'originRectInfo' | 'rangeRectInfo'> = {
|
||||
type: elem.type,
|
||||
isVisibleInView: true,
|
||||
position: [...currentPosition]
|
||||
};
|
||||
let originRectInfo: ViewRectInfo | null = null;
|
||||
|
||||
const groupQueue = getGroupQueueByElementPosition(elements, currentPosition);
|
||||
|
||||
originRectInfo = calcElementOriginRectInfo(elem, {
|
||||
groupQueue: groupQueue || []
|
||||
});
|
||||
|
||||
const virtualItem: VirtualFlatItem = {
|
||||
...baseInfo,
|
||||
...{
|
||||
originRectInfo: originRectInfo as ViewRectInfo,
|
||||
rangeRectInfo: is.angle(elem.angle)
|
||||
? originRectInfoToRangeRectInfo(originRectInfo as ViewRectInfo)
|
||||
: originRectInfo
|
||||
},
|
||||
...calcVirtualFlatDetail(elem, opts)
|
||||
};
|
||||
|
||||
virtualFlatMap[elem.uuid] = virtualItem;
|
||||
|
||||
if (elem.type === 'group') {
|
||||
(elem as Element<'group'>).detail.children.forEach((ele, i) => {
|
||||
currentPosition.push(i);
|
||||
_walk(ele);
|
||||
currentPosition.pop();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
elements.forEach((elem, index) => {
|
||||
currentPosition.push(index);
|
||||
_walk(elem);
|
||||
currentPosition.pop();
|
||||
});
|
||||
|
||||
return virtualFlatMap;
|
||||
}
|
||||
163
packages/renderer/src/virtual-flat/text.ts
Normal file
163
packages/renderer/src/virtual-flat/text.ts
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
import type { Element, CalcVirtualDetailOptions, VirtualFlatTextDetail, VirtualFlatTextLine } from '@idraw/types';
|
||||
import { enhanceFontFamliy, getDefaultElementDetailConfig } from '@idraw/util';
|
||||
|
||||
const detailConfig = getDefaultElementDetailConfig();
|
||||
|
||||
// TODO
|
||||
function isTextWidthWithinErrorRange(w0: number, w1: number, scale: number): boolean {
|
||||
if (scale < 0.5) {
|
||||
if (w0 < w1 && (w0 - w1) / w0 > -0.15) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return w0 >= w1;
|
||||
}
|
||||
|
||||
export function calcVirtualTextDetail(elem: Element<'text'>, opts: CalcVirtualDetailOptions): VirtualFlatTextDetail {
|
||||
const { w, h } = elem;
|
||||
const x = 0;
|
||||
const y = 0;
|
||||
const ctx = opts.tempContext;
|
||||
|
||||
const lines: VirtualFlatTextLine[] = [];
|
||||
const detail: Element<'text'>['detail'] = {
|
||||
...detailConfig,
|
||||
...elem.detail
|
||||
};
|
||||
const originFontSize = detail.fontSize || detailConfig.fontSize;
|
||||
const fontSize = originFontSize;
|
||||
|
||||
if (fontSize < 2) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const originLineHeight = detail.lineHeight || originFontSize;
|
||||
const lineHeight = originLineHeight;
|
||||
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.$setFont({
|
||||
fontWeight: detail.fontWeight,
|
||||
fontSize: fontSize,
|
||||
fontFamily: enhanceFontFamliy(detail.fontFamily)
|
||||
});
|
||||
let detailText = detail.text.replace(/\r\n/gi, '\n');
|
||||
if (detail.textTransform === 'lowercase') {
|
||||
detailText = detailText.toLowerCase();
|
||||
} else if (detail.textTransform === 'uppercase') {
|
||||
detailText = detailText.toUpperCase();
|
||||
}
|
||||
|
||||
const fontHeight = lineHeight;
|
||||
const detailTextList = detailText.split('\n');
|
||||
|
||||
let lineNum = 0;
|
||||
detailTextList.forEach((itemText: string, idx: number) => {
|
||||
if (detail.minInlineSize === 'maxContent') {
|
||||
lines.push({
|
||||
x,
|
||||
y: 0, // TODO
|
||||
text: itemText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(itemText).width)
|
||||
});
|
||||
} else {
|
||||
let lineText = '';
|
||||
let splitStr = '';
|
||||
let tempStrList: string[] = itemText.split(splitStr);
|
||||
if (detail.wordBreak === 'normal') {
|
||||
splitStr = ' ';
|
||||
const wordList = itemText.split(splitStr);
|
||||
tempStrList = [];
|
||||
wordList.forEach((word: string, idx: number) => {
|
||||
tempStrList.push(word);
|
||||
if (idx < wordList.length - 1) {
|
||||
tempStrList.push(splitStr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (tempStrList.length === 1 && detail.overflow === 'visible') {
|
||||
lines.push({
|
||||
x,
|
||||
y: 0, // TODO
|
||||
text: tempStrList[0],
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(tempStrList[0]).width)
|
||||
});
|
||||
} else if (tempStrList.length > 0) {
|
||||
for (let i = 0; i < tempStrList.length; i++) {
|
||||
if (isTextWidthWithinErrorRange(ctx.$doPixelRatio(w), ctx.measureText(lineText + tempStrList[i]).width, 1)) {
|
||||
lineText += tempStrList[i] || '';
|
||||
} else {
|
||||
lines.push({
|
||||
x,
|
||||
y: 0, // TODO
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
lineText = tempStrList[i] || '';
|
||||
lineNum++;
|
||||
}
|
||||
if ((lineNum + 1) * fontHeight > h && detail.overflow === 'hidden') {
|
||||
break;
|
||||
}
|
||||
if (tempStrList.length - 1 === i) {
|
||||
if ((lineNum + 1) * fontHeight <= h) {
|
||||
lines.push({
|
||||
x,
|
||||
y: 0, // TODO
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
if (idx < detailTextList.length - 1) {
|
||||
lineNum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push({
|
||||
x,
|
||||
y: 0, // TODO
|
||||
text: '',
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let startY = 0;
|
||||
let eachLineStartY = 0;
|
||||
if (fontHeight > fontSize) {
|
||||
eachLineStartY = (fontHeight - fontSize) / 2;
|
||||
}
|
||||
if (lines.length * fontHeight < h) {
|
||||
if (elem.detail.verticalAlign === 'top') {
|
||||
startY = 0;
|
||||
} else if (elem.detail.verticalAlign === 'bottom') {
|
||||
startY += h - lines.length * fontHeight;
|
||||
} else {
|
||||
// middle and default
|
||||
startY += (h - lines.length * fontHeight) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// draw text lines
|
||||
{
|
||||
const _y = y + startY;
|
||||
lines.forEach((line, i) => {
|
||||
let _x = x;
|
||||
if (detail.textAlign === 'center') {
|
||||
_x = x + (w - line.width) / 2;
|
||||
} else if (detail.textAlign === 'right') {
|
||||
_x = x + (w - line.width);
|
||||
}
|
||||
lines[i].x = _x;
|
||||
lines[i].y = _y + fontHeight * i + eachLineStartY;
|
||||
});
|
||||
}
|
||||
|
||||
const virtualTextDetail: VirtualFlatTextDetail = {
|
||||
textLines: lines
|
||||
};
|
||||
return virtualTextDetail;
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "@idraw/types",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {},
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export * from './lib/util';
|
||||
export * from './lib/point';
|
||||
export * from './lib/box';
|
||||
export * from './lib/data';
|
||||
export * from './lib/element';
|
||||
export * from './lib/view';
|
||||
|
|
@ -17,3 +18,4 @@ export * from './lib/html';
|
|||
export * from './lib/svg-path';
|
||||
export * from './lib/config';
|
||||
export * from './lib/modify';
|
||||
export * from './lib/virtual-flat';
|
||||
|
|
|
|||
|
|
@ -88,7 +88,10 @@ export interface BoardMiddlewareObject<S extends Record<any | symbol, any> = any
|
|||
clear?(e: BoardWatcherEventMap<S>['clear']): void | boolean;
|
||||
}
|
||||
|
||||
export interface BoardMiddlewareOptions<S extends Record<any | symbol, any> = Record<any | symbol, any>, E extends BoardExtendEventMap = BoardExtendEventMap> {
|
||||
export interface BoardMiddlewareOptions<
|
||||
S extends Record<any | symbol, any> = Record<any | symbol, any>,
|
||||
E extends BoardExtendEventMap = BoardExtendEventMap
|
||||
> {
|
||||
boardContent: BoardContent;
|
||||
sharer: StoreSharer<S>;
|
||||
viewer: BoardViewer;
|
||||
|
|
@ -98,10 +101,11 @@ export interface BoardMiddlewareOptions<S extends Record<any | symbol, any> = Re
|
|||
canvas?: HTMLCanvasElement;
|
||||
}
|
||||
|
||||
export type BoardMiddleware<S extends Record<any | symbol, any> = any, E extends BoardExtendEventMap = BoardExtendEventMap, C extends any = undefined> = (
|
||||
opts: BoardMiddlewareOptions<S, E>,
|
||||
config?: C
|
||||
) => BoardMiddlewareObject<S, C>;
|
||||
export type BoardMiddleware<
|
||||
S extends Record<any | symbol, any> = any,
|
||||
E extends BoardExtendEventMap = BoardExtendEventMap,
|
||||
C extends any = undefined
|
||||
> = (opts: BoardMiddlewareOptions<S, E>, config?: C) => BoardMiddlewareObject<S, C>;
|
||||
|
||||
export interface BoardOptions {
|
||||
boardContent: BoardContent;
|
||||
|
|
@ -114,8 +118,7 @@ export interface BoardViewerFrameSnapshot<S extends Record<any | symbol, any> =
|
|||
}
|
||||
|
||||
export interface BoardViewerEventMap {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
drawFrame: {};
|
||||
drawFrame: object;
|
||||
}
|
||||
|
||||
export interface BoardViewerOptions {
|
||||
|
|
@ -128,24 +131,27 @@ export interface BoardViewerOptions {
|
|||
}
|
||||
|
||||
// export interface BoardViewerStorage {
|
||||
// viewVisibleInfoMap: ViewVisibleInfoMap;
|
||||
// virtualFlatItemMap: VirtualFlatItemMap;
|
||||
// }
|
||||
|
||||
export interface BoardViewer extends UtilEventEmitter<BoardViewerEventMap> {
|
||||
drawFrame(): void;
|
||||
scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }): { moveX: number; moveY: number };
|
||||
scale(opts: { scale: number; point: PointSize; ignoreUpdateVisibleStatus?: boolean }): {
|
||||
moveX: number;
|
||||
moveY: number;
|
||||
};
|
||||
scroll(opts: { moveX?: number; moveY?: number; ignoreUpdateVisibleStatus?: boolean }): ViewScaleInfo;
|
||||
resize(viewSize: Partial<ViewSizeInfo>, opts?: { ignoreUpdateVisibleStatus?: boolean }): ViewSizeInfo;
|
||||
updateViewScaleInfo(opts: { scale: number; offsetX: number; offsetY: number }): ViewScaleInfo;
|
||||
|
||||
// resetViewVisibleInfoMap(
|
||||
// resetVirtualFlatItemMap(
|
||||
// data: Data,
|
||||
// opts: {
|
||||
// viewScaleInfo: ViewScaleInfo;
|
||||
// viewSizeInfo: ViewSizeInfo;
|
||||
// }
|
||||
// ): void;
|
||||
// modifyViewVisibleInfoMap(
|
||||
// modifyVirtualFlatItemMap(
|
||||
// data: Data,
|
||||
// opts: {
|
||||
// modifyOptions: ModifyOptions;
|
||||
|
|
|
|||
56
packages/types/src/lib/box.ts
Normal file
56
packages/types/src/lib/box.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import type { PointSize } from './point';
|
||||
|
||||
export type BoxInfo = {
|
||||
// p0: PointSize; // top-left
|
||||
// p1: PointSize; // top-right
|
||||
// p2: PointSize; // bottom-right
|
||||
// p3: PointSize; // bottom-left
|
||||
|
||||
btw: number; // border-top-width
|
||||
brw: number; // border-right-width
|
||||
bbw: number; // border-bottom-width
|
||||
blw: number; // border-left-width
|
||||
btlr: number; // border-top-left-radius
|
||||
btrr: number; // border-top-right-radius
|
||||
bblr: number; // border-bottom-left-radius
|
||||
bbrr: number; // border-bottom-right-radius
|
||||
|
||||
p0: PointSize; // pointer border-top-left
|
||||
p1: PointSize; // pointer border-top-right
|
||||
p2: PointSize; // pointer border-bottom-right
|
||||
p3: PointSize; // pointer border-bottom-left
|
||||
p0s: PointSize; // pointer border-top-left start
|
||||
p0e: PointSize; // pointer border-top-left end
|
||||
p1s: PointSize; // pointer border-top-right start
|
||||
p1e: PointSize; // pointer border-top-right start
|
||||
p2s: PointSize; // pointer border-bottom-right start
|
||||
p2e: PointSize; // pointer border-bottom-right end
|
||||
p3s: PointSize; // pointer border-bottom-left start
|
||||
p3e: PointSize; // pointer border-bottom-left end
|
||||
|
||||
op0: PointSize; // outer pointer border-top-left
|
||||
op1: PointSize; // outer pointer border-top-right
|
||||
op2: PointSize; // outer pointer border-bottom-right
|
||||
op3: PointSize; // outer pointer border-bottom-left
|
||||
op0s: PointSize; // outer pointer border-top-left start
|
||||
op0e: PointSize; // outer pointer border-top-left end
|
||||
op1s: PointSize; // outer pointer border-top-right start
|
||||
op1e: PointSize; // outer pointer border-top-right start
|
||||
op2s: PointSize; // outer pointer border-bottom-right start
|
||||
op2e: PointSize; // outer pointer border-bottom-right end
|
||||
op3s: PointSize; // outer pointer border-bottom-left start
|
||||
op3e: PointSize; // outer pointer border-bottom-left end
|
||||
|
||||
ip0: PointSize; // inner pointer border-top-left
|
||||
ip1: PointSize; // inner pointer border-top-right
|
||||
ip2: PointSize; // inner pointer border-bottom-right
|
||||
ip3: PointSize; // inner pointer border-bottom-left
|
||||
ip0s: PointSize; // inner pointer border-top-left start
|
||||
ip0e: PointSize; // inner pointer border-top-left end
|
||||
ip1s: PointSize; // inner pointer border-top-right start
|
||||
ip1e: PointSize; // inner pointer border-top-right start
|
||||
ip2s: PointSize; // inner pointer border-bottom-right start
|
||||
ip2e: PointSize; // inner pointer border-bottom-right end
|
||||
ip3s: PointSize; // inner pointer border-bottom-left start
|
||||
ip3e: PointSize; // inner pointer border-bottom-left end
|
||||
};
|
||||
|
|
@ -31,6 +31,8 @@ export interface ViewContext2D {
|
|||
moveTo(x: number, y: number): void;
|
||||
lineTo(x: number, y: number): void;
|
||||
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
||||
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
||||
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
||||
lineWidth: number;
|
||||
getLineDash(): number[];
|
||||
setLineDash(segments: number[]): void;
|
||||
|
|
@ -49,7 +51,17 @@ export interface ViewContext2D {
|
|||
scale(x: number, y: number): void;
|
||||
drawImage(image: CanvasImageSource, dx: number, dy: number): void;
|
||||
drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
|
||||
drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
|
||||
drawImage(
|
||||
image: CanvasImageSource,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sw: number,
|
||||
sh: number,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dw: number,
|
||||
dh: number
|
||||
): void;
|
||||
createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null;
|
||||
globalAlpha: number;
|
||||
globalCompositeOperation: GlobalCompositeOperation;
|
||||
|
|
@ -57,7 +69,16 @@ export interface ViewContext2D {
|
|||
shadowColor: string;
|
||||
shadowOffsetX: number;
|
||||
shadowOffsetY: number;
|
||||
circle(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
||||
circle(
|
||||
x: number,
|
||||
y: number,
|
||||
radiusX: number,
|
||||
radiusY: number,
|
||||
rotation: number,
|
||||
startAngle: number,
|
||||
endAngle: number,
|
||||
counterclockwise?: boolean
|
||||
): void;
|
||||
isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
||||
clip(fillRule?: CanvasFillRule): void;
|
||||
clip(path: Path2D, fillRule?: CanvasFillRule): void;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import type { Element, ElementSize, ElementType, ElementPosition } from './element';
|
||||
import type { ViewScaleInfo } from './view';
|
||||
import type { Data } from './data';
|
||||
import type { ViewContext2D } from './context2d';
|
||||
import type { BoardBaseEventMap } from './board';
|
||||
|
||||
export interface CoreOptions {
|
||||
width: number;
|
||||
height: number;
|
||||
devicePixelRatio?: number;
|
||||
createCustomContext2D?: (opts: { width: number; height: number; devicePixelRatio: number }) => ViewContext2D;
|
||||
}
|
||||
|
||||
export type CursorType =
|
||||
|
|
@ -46,7 +44,9 @@ export interface CoreEventChange {
|
|||
| 'setData'
|
||||
| 'undo'
|
||||
| 'redo'
|
||||
| 'changeLayout' // TODO
|
||||
| 'dragLayout'
|
||||
| 'updateLayout'
|
||||
| 'updateElementName'
|
||||
| 'other';
|
||||
selectedElements?: Element[] | null;
|
||||
hoverElement?: Element | null;
|
||||
|
|
@ -82,7 +82,19 @@ export type CoreEventMap = BoardBaseEventMap & {
|
|||
change: CoreEventChange;
|
||||
ruler: { show: boolean; showGrid: boolean };
|
||||
scale: { scale: number };
|
||||
select: { uuids?: string[]; positions?: ElementPosition[] };
|
||||
select: {
|
||||
uuids?: string[];
|
||||
positions?: ElementPosition[];
|
||||
type?:
|
||||
| 'clickCanvas'
|
||||
| 'selectElement'
|
||||
| 'selectElements'
|
||||
| 'selectElementByPosition'
|
||||
| 'selectElementsByPositions'
|
||||
| 'other'
|
||||
| string;
|
||||
};
|
||||
selectLayout: void; // TODO
|
||||
clearSelect: { uuids?: string[] } | void;
|
||||
textEdit: CoreEventTextEdit;
|
||||
textChange: CoreEventTextChange;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,34 @@
|
|||
import type { Element, ElementType, ElementAssets, ElementSize, ElementGroupDetail, ElementGlobalDetail } from './element';
|
||||
import type { Element, ElementType, ElementAssets, ElementSize, ElementGroupDetail } from './element';
|
||||
|
||||
export type DataLayout = Pick<ElementSize, 'x' | 'y' | 'w' | 'h'> & {
|
||||
detail: Pick<
|
||||
ElementGroupDetail,
|
||||
'background' | 'borderWidth' | 'overflow' | 'borderColor' | 'borderDash' | 'borderRadius' | 'shadowBlur' | 'shadowColor' | 'shadowOffsetX' | 'shadowOffsetY'
|
||||
| 'background'
|
||||
| 'borderWidth'
|
||||
| 'overflow'
|
||||
| 'borderColor'
|
||||
| 'borderDash'
|
||||
| 'borderRadius'
|
||||
| 'shadowBlur'
|
||||
| 'shadowColor'
|
||||
| 'shadowOffsetX'
|
||||
| 'shadowOffsetY'
|
||||
>;
|
||||
operations?: {
|
||||
position?: 'absolute' | 'relative';
|
||||
};
|
||||
};
|
||||
|
||||
export interface DataGlobalDetail {
|
||||
background?: string;
|
||||
}
|
||||
|
||||
export type Data<E extends Record<string, any> = Record<string, any>> = {
|
||||
name?: string;
|
||||
elements: Element<ElementType, E>[];
|
||||
assets?: ElementAssets;
|
||||
layout?: DataLayout;
|
||||
global?: ElementGlobalDetail;
|
||||
global?: DataGlobalDetail;
|
||||
};
|
||||
|
||||
export type Matrix = [
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export interface TransformScale {
|
|||
export type TransformAction = TransformMatrix | TransformTranslate | TransformRotate | TransformScale;
|
||||
|
||||
export interface GradientStop {
|
||||
offset: number;
|
||||
offset: number; // [0, 1] eg. 0.5
|
||||
color: string;
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ export interface ElementBaseDetail {
|
|||
// // background?: string;
|
||||
// }
|
||||
|
||||
export interface ElementRectDetail extends ElementBaseDetail {}
|
||||
export type ElementRectDetail = ElementBaseDetail;
|
||||
|
||||
export interface ElementTextDetail extends ElementBaseDetail {
|
||||
text: string;
|
||||
|
|
@ -182,14 +182,15 @@ export interface ElementGlobalDetail {
|
|||
background?: string;
|
||||
}
|
||||
|
||||
export interface Element<T extends ElementType = ElementType, E extends Record<string, any> = Record<string, any>> extends ElementSize {
|
||||
export interface Element<T extends ElementType = ElementType, E extends Record<string, any> = Record<string, any>>
|
||||
extends ElementSize {
|
||||
uuid: string;
|
||||
name?: string;
|
||||
type: T;
|
||||
detail: ElementDetailMap[T];
|
||||
operations?: ElementOperations;
|
||||
extends?: E;
|
||||
global?: ElementGlobalDetail;
|
||||
// global?: ElementGlobalDetail;
|
||||
}
|
||||
|
||||
export type Elements = Element<ElementType>[];
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import { ViewContext2D } from '@idraw/types';
|
|||
|
||||
export interface RendererOptions {
|
||||
viewContext: ViewContext2D;
|
||||
tempContext: ViewContext2D;
|
||||
sharer?: StoreSharer;
|
||||
calculator?: ViewCalculator;
|
||||
}
|
||||
|
||||
export interface RendererEvent {
|
||||
|
|
@ -37,7 +37,7 @@ export interface RendererDrawOptions {
|
|||
|
||||
export interface RendererDrawElementOptions extends RendererDrawOptions {
|
||||
loader: RendererLoader;
|
||||
calculator?: ViewCalculator;
|
||||
calculator: ViewCalculator;
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
parentElementSize: ElementSize;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import type { Element, ElementType, ElementPosition } from './element';
|
||||
import type { Element, ElementType } from './element';
|
||||
import type { Point, PointSize } from './point';
|
||||
import type { Data } from './data';
|
||||
import type { ViewContext2D } from './context2d';
|
||||
import type { ModifyOptions } from './modify';
|
||||
import { VirtualFlatItem } from './virtual-flat';
|
||||
// import type { BoxInfo } from './box';
|
||||
|
||||
export interface ViewScaleInfo {
|
||||
scale: number;
|
||||
|
|
@ -28,31 +30,22 @@ export interface BoardContent {
|
|||
viewContext: ViewContext2D;
|
||||
overlayContext: ViewContext2D;
|
||||
underlayContext: ViewContext2D;
|
||||
tempContext: ViewContext2D;
|
||||
drawView: () => void;
|
||||
}
|
||||
|
||||
export interface ViewCalculatorOptions {
|
||||
// boardContent?: BoardContent;
|
||||
viewContext: ViewContext2D;
|
||||
}
|
||||
|
||||
export interface ViewCalculatorStorage {
|
||||
viewVisibleInfoMap: ViewVisibleInfoMap;
|
||||
visibleCount: number;
|
||||
invisibleCount: number;
|
||||
tempContext: ViewContext2D;
|
||||
}
|
||||
|
||||
export interface ViewCalculator {
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
isPointInElement(p: Point, elem: Element<ElementType>, viewScaleInfo: ViewScaleInfo, viewSize: ViewSizeInfo): boolean;
|
||||
needRender(elem: Element<ElementType>): boolean;
|
||||
getPointElement(
|
||||
p: Point,
|
||||
opts: { data: Data; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo; groupQueue?: Element<'group'>[] }
|
||||
): { index: number; element: null | Element<ElementType>; groupQueueIndex: number };
|
||||
resetViewVisibleInfoMap(
|
||||
resetVirtualFlatItemMap(
|
||||
data: Data,
|
||||
opts: {
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
|
|
@ -76,7 +69,7 @@ export interface ViewCalculator {
|
|||
viewSizeInfo: ViewSizeInfo;
|
||||
}
|
||||
): ViewRectInfo | null;
|
||||
modifyViewVisibleInfoMap(
|
||||
modifyVirtualFlatItemMap(
|
||||
data: Data,
|
||||
opts: {
|
||||
modifyOptions: ModifyOptions;
|
||||
|
|
@ -86,6 +79,7 @@ export interface ViewCalculator {
|
|||
): void;
|
||||
|
||||
toGridNum(num: number, opts?: { ignore?: boolean }): number;
|
||||
getVirtualFlatItem: (uuid: string) => VirtualFlatItem | null;
|
||||
}
|
||||
|
||||
export type ViewRectVertexes = [PointSize, PointSize, PointSize, PointSize];
|
||||
|
|
@ -109,18 +103,3 @@ export type ViewRectInfo = {
|
|||
left: PointSize;
|
||||
center: PointSize;
|
||||
};
|
||||
|
||||
export type ViewRectInfoMap = {
|
||||
originRectInfo: ViewRectInfo;
|
||||
rangeRectInfo: ViewRectInfo;
|
||||
};
|
||||
|
||||
export type ViewVisibleInfo = ViewRectInfoMap & {
|
||||
isVisibleInView: boolean;
|
||||
isGroup: boolean;
|
||||
position: ElementPosition;
|
||||
};
|
||||
|
||||
export type ViewVisibleInfoMap = {
|
||||
[uuid: string]: ViewVisibleInfo;
|
||||
};
|
||||
|
|
|
|||
39
packages/types/src/lib/virtual-flat.ts
Normal file
39
packages/types/src/lib/virtual-flat.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import type { ViewRectInfo } from './view';
|
||||
import type { ElementPosition, ElementType } from './element';
|
||||
import type { ViewContext2D } from './context2d';
|
||||
|
||||
export type CalcVirtualDetailOptions = {
|
||||
tempContext: ViewContext2D;
|
||||
};
|
||||
|
||||
export type VirtualFlatTextLine = {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type VirtualFlatTextDetail = {
|
||||
textLines?: Array<VirtualFlatTextLine>;
|
||||
};
|
||||
export type VirtualFlatDetail = VirtualFlatTextDetail & {
|
||||
// TODO
|
||||
};
|
||||
|
||||
export type VirtualFlatItem = {
|
||||
type: ElementType;
|
||||
position: ElementPosition;
|
||||
originRectInfo: ViewRectInfo;
|
||||
rangeRectInfo: ViewRectInfo;
|
||||
isVisibleInView: boolean;
|
||||
} & VirtualFlatDetail;
|
||||
|
||||
export type VirtualFlatItemMap = {
|
||||
[uuid: string]: VirtualFlatItem;
|
||||
};
|
||||
|
||||
export interface VirtualFlatStorage {
|
||||
virtualFlatItemMap: VirtualFlatItemMap;
|
||||
visibleCount: number;
|
||||
invisibleCount: number;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/util",
|
||||
"version": "0.4.0-beta.39",
|
||||
"version": "0.4.0-beta.40",
|
||||
"description": "",
|
||||
"main": "dist/esm/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
"url": "https://github.com/idrawjs/idraw/issues"
|
||||
},
|
||||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"author": "idrawjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@idraw/types": "^0.4.0-alpha.0"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,37 @@
|
|||
export { delay, compose, throttle, debounce } from './lib/time';
|
||||
export { downloadImageFromCanvas, parseFileToBase64, pickFile, parseFileToText, downloadFileFromText } from './lib/file';
|
||||
export { toColorHexStr, toColorHexNum, isColorStr, colorNameToHex, colorToCSS, colorToLinearGradientCSS, mergeHexColorAlpha } from './lib/color';
|
||||
export {
|
||||
downloadImageFromCanvas,
|
||||
parseFileToBase64,
|
||||
pickFile,
|
||||
parseFileToText,
|
||||
downloadFileFromText
|
||||
} from './lib/file';
|
||||
export {
|
||||
toColorHexStr,
|
||||
toColorHexNum,
|
||||
isColorStr,
|
||||
colorNameToHex,
|
||||
colorToCSS,
|
||||
colorToLinearGradientCSS,
|
||||
mergeHexColorAlpha
|
||||
} from './lib/color';
|
||||
export { createUUID, isAssetId, createAssetId } from './lib/uuid';
|
||||
export { deepClone, sortDataAsserts, deepCloneElement, filterCompactData } from './lib/data';
|
||||
export { deepClone, sortDataAsserts, deepCloneElement, deepCloneData, filterCompactData } from './lib/data';
|
||||
export { istype } from './lib/istype';
|
||||
export { loadImage, loadSVG, loadHTML } from './lib/load';
|
||||
export { is } from './lib/is';
|
||||
export { check } from './lib/check';
|
||||
export { createBoardContent, createContext2D, createOffscreenContext2D } from './lib/canvas';
|
||||
export { EventEmitter } from './lib/event';
|
||||
export { calcDistance, calcSpeed, equalPoint, equalTouchPoint, vaildPoint, vaildTouchPoint, getCenterFromTwoPoints } from './lib/point';
|
||||
export {
|
||||
calcDistance,
|
||||
calcSpeed,
|
||||
equalPoint,
|
||||
equalTouchPoint,
|
||||
vaildPoint,
|
||||
vaildTouchPoint,
|
||||
getCenterFromTwoPoints
|
||||
} from './lib/point';
|
||||
export { Store } from './lib/store';
|
||||
export { getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from './lib/middleware';
|
||||
export { Context2D } from './lib/context2d';
|
||||
|
|
@ -60,14 +82,17 @@ export {
|
|||
calcViewScaleInfo,
|
||||
calcElementViewRectInfo,
|
||||
calcElementOriginRectInfo,
|
||||
calcElementViewRectInfoMap,
|
||||
originRectInfoToRangeRectInfo,
|
||||
isViewPointInElementSize,
|
||||
isViewPointInVertexes
|
||||
} from './lib/view-calc';
|
||||
export { sortElementsViewVisiableInfoMap, calcVisibleOriginCanvasRectInfo, updateViewVisibleInfoMapStatus } from './lib/view-visible';
|
||||
export { rotatePoint, rotateVertexes, rotateByCenter } from './lib/rotate';
|
||||
export { getElementVertexes, calcElementVertexesInGroup, calcElementVertexesQueueInGroup, calcElementQueueVertexesQueueInGroup } from './lib/vertex';
|
||||
export {
|
||||
getElementVertexes,
|
||||
calcElementVertexesInGroup,
|
||||
calcElementVertexesQueueInGroup,
|
||||
calcElementQueueVertexesQueueInGroup
|
||||
} from './lib/vertex';
|
||||
export { calcElementSizeController, calcLayoutSizeController } from './lib/controller';
|
||||
export { generateSVGPath, parseSVGPath } from './lib/svg-path';
|
||||
export { generateHTML, parseHTML } from './lib/html';
|
||||
|
|
@ -93,3 +118,6 @@ export { enhanceFontFamliy } from './lib/text';
|
|||
export { flatElementList } from './lib/flat';
|
||||
export { groupElementsByPosition, ungroupElementsByPosition } from './lib/group';
|
||||
export { calcPointMoveElementInGroup } from './lib/point-move-element';
|
||||
export { merge } from './lib/merge';
|
||||
export { omit } from './lib/omit';
|
||||
export { elementToBoxInfo } from './lib/box';
|
||||
|
|
|
|||
186
packages/util/src/lib/box.ts
Normal file
186
packages/util/src/lib/box.ts
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import type { BoxInfo, Element, PointSize } from '@idraw/types';
|
||||
import { is } from './is';
|
||||
|
||||
export function elementToBoxInfo(elem: Element): BoxInfo {
|
||||
const { x, y, w, h, detail } = elem;
|
||||
const { borderWidth, borderRadius, boxSizing } = detail;
|
||||
let btw: number = 0; // border-top-width
|
||||
let brw: number = 0; // border-right-width
|
||||
let bbw: number = 0; // border-bottom-width
|
||||
let blw: number = 0; // border-left-width
|
||||
|
||||
let btlr: number = 0; // border-top-left-radius
|
||||
let btrr: number = 0; // border-top-right-radius
|
||||
let bblr: number = 0; // border-bottom-left-radius
|
||||
let bbrr: number = 0; // border-bottom-right-radius
|
||||
|
||||
if (typeof borderWidth === 'number' && borderWidth > 0) {
|
||||
btw = borderWidth;
|
||||
brw = borderWidth;
|
||||
bbw = borderWidth;
|
||||
blw = borderWidth;
|
||||
} else if (Array.isArray(borderWidth)) {
|
||||
btw = is.positiveNum(borderWidth[0]) ? borderWidth[0] : 0;
|
||||
brw = is.positiveNum(borderWidth[1]) ? borderWidth[0] : 0;
|
||||
bbw = is.positiveNum(borderWidth[2]) ? borderWidth[0] : 0;
|
||||
blw = is.positiveNum(borderWidth[3]) ? borderWidth[0] : 0;
|
||||
}
|
||||
|
||||
if (typeof borderRadius === 'number' && borderRadius > 0) {
|
||||
btlr = borderRadius;
|
||||
btrr = borderRadius;
|
||||
bblr = borderRadius;
|
||||
bbrr = borderRadius;
|
||||
} else if (Array.isArray(borderRadius)) {
|
||||
btlr = is.positiveNum(borderRadius[0]) ? borderRadius[0] : 0;
|
||||
btrr = is.positiveNum(borderRadius[0]) ? borderRadius[0] : 0;
|
||||
bblr = is.positiveNum(borderRadius[0]) ? borderRadius[0] : 0;
|
||||
bbrr = is.positiveNum(borderRadius[0]) ? borderRadius[0] : 0;
|
||||
}
|
||||
const p0: PointSize = { x: x, y: y }; // pointer border-top-left
|
||||
const p1: PointSize = { x: x + w, y: y }; // pointer border-top-right
|
||||
const p2: PointSize = { x: x + w, y: y + h }; // pointer border-bottom-right
|
||||
const p3: PointSize = { x: x, y: y + h }; // pointer border-bottom-left
|
||||
|
||||
const p0s: PointSize = { x: x, y: y + btlr }; // pointer border-top-left start
|
||||
const p0e: PointSize = { x: x + btlr, y: y }; // pointer border-top-left end
|
||||
const p1s: PointSize = { x: x + w - btrr, y: y }; // pointer border-top-right start
|
||||
const p1e: PointSize = { x: x + w, y: y + btrr }; // pointer border-top-right start
|
||||
const p2s: PointSize = { x: x + w, y: y + h - bbrr }; // pointer border-bottom-right start
|
||||
const p2e: PointSize = { x: x + w - bbrr, y: y + h }; // pointer border-bottom-right end
|
||||
const p3s: PointSize = { x: x + bblr, y: y + h }; // pointer border-bottom-left start
|
||||
const p3e: PointSize = { x: x, y: y + h - bblr }; // pointer border-bottom-left end
|
||||
|
||||
let op0: PointSize = { ...p0 }; // outer pointer border-top-left
|
||||
let op1: PointSize = { ...p1 }; // outer pointer border-top-right
|
||||
let op2: PointSize = { ...p2 }; // outer pointer border-bottom-right
|
||||
let op3: PointSize = { ...p3 }; // outer pointer border-bottom-left
|
||||
|
||||
let op0s: PointSize = { ...p0s }; // outer pointer border-top-left start
|
||||
let op0e: PointSize = { ...p0e }; // outer pointer border-top-left end
|
||||
let op1s: PointSize = { ...p1s }; // outer pointer border-top-right start
|
||||
let op1e: PointSize = { ...p1e }; // outer pointer border-top-right start
|
||||
let op2s: PointSize = { ...p2s }; // outer pointer border-bottom-right start
|
||||
let op2e: PointSize = { ...p2e }; // outer pointer border-bottom-right end
|
||||
let op3s: PointSize = { ...p3s }; // outer pointer border-bottom-left start
|
||||
let op3e: PointSize = { ...p3e }; // outer pointer border-bottom-left end
|
||||
|
||||
let ip0: PointSize = { ...p0 }; // inner pointer border-top-left
|
||||
let ip1: PointSize = { ...p1 }; // inner pointer border-top-right
|
||||
let ip2: PointSize = { ...p2 }; // inner pointer border-bottom-right
|
||||
let ip3: PointSize = { ...p3 }; // inner pointer border-bottom-left
|
||||
|
||||
let ip0s: PointSize = { ...p0s }; // inner pointer border-top-left start
|
||||
let ip0e: PointSize = { ...p0e }; // inner pointer border-top-left end
|
||||
let ip1s: PointSize = { ...p1s }; // inner pointer border-top-right start
|
||||
let ip1e: PointSize = { ...p1e }; // inner pointer border-top-right start
|
||||
let ip2s: PointSize = { ...p2s }; // inner pointer border-bottom-right start
|
||||
let ip2e: PointSize = { ...p2e }; // inner pointer border-bottom-right end
|
||||
let ip3s: PointSize = { ...p3s }; // inner pointer border-bottom-left start
|
||||
let ip3e: PointSize = { ...p3e }; // inner pointer border-bottom-left end
|
||||
|
||||
if (boxSizing === 'border-box') {
|
||||
ip0 = { x: ip0.x + blw, y: ip0.y + btw };
|
||||
ip1 = { x: ip1.x - brw, y: ip1.y + btw };
|
||||
ip2 = { x: ip2.x - brw, y: ip2.y - bbw };
|
||||
ip3 = { x: ip3.x + blw, y: ip3.y - bbw };
|
||||
ip0s = { x: ip0s.x + blw, y: ip0s.y + btw };
|
||||
ip0e = { x: ip0e.x + blw, y: ip0e.y + btw };
|
||||
ip1s = { x: ip1s.x - brw, y: ip1s.y + btw };
|
||||
ip1e = { x: ip1e.x - brw, y: ip1e.y + btw };
|
||||
ip2s = { x: ip2s.x - brw, y: ip2s.y - bbw };
|
||||
ip2e = { x: ip2e.x - brw, y: ip2e.y - bbw };
|
||||
ip3s = { x: ip3s.x + blw, y: ip3s.y - bbw };
|
||||
ip3e = { x: ip3e.x + blw, y: ip3e.y - bbw };
|
||||
} else if (boxSizing === 'content-box') {
|
||||
op0 = { x: op0.x - blw, y: op0.y - btw };
|
||||
op1 = { x: op1.x + brw, y: op1.y - btw };
|
||||
op2 = { x: op2.x + brw, y: op2.y + bbw };
|
||||
op3 = { x: op3.x - blw, y: op3.y + bbw };
|
||||
op0s = { x: op0s.x - blw, y: op0s.y - btw };
|
||||
op0e = { x: op0e.x - blw, y: op0e.y - btw };
|
||||
op1s = { x: op1s.x + brw, y: op1s.y - btw };
|
||||
op1e = { x: op1e.x + brw, y: op1e.y - btw };
|
||||
op2s = { x: op2s.x + brw, y: op2s.y + bbw };
|
||||
op2e = { x: op2e.x + brw, y: op2e.y + bbw };
|
||||
op3s = { x: op3s.x - blw, y: op3s.y + bbw };
|
||||
op3e = { x: op3e.x - blw, y: op3e.y + bbw };
|
||||
} else {
|
||||
ip0 = { x: ip0.x + blw / 2, y: ip0.y + btw / 2 };
|
||||
ip1 = { x: ip1.x - brw / 2, y: ip1.y + btw / 2 };
|
||||
ip2 = { x: ip2.x - brw / 2, y: ip2.y - bbw / 2 };
|
||||
ip3 = { x: ip3.x + blw / 2, y: ip3.y - bbw / 2 };
|
||||
ip0s = { x: ip0s.x + blw / 2, y: ip0s.y + btw / 2 };
|
||||
ip0e = { x: ip0e.x + blw / 2, y: ip0e.y + btw / 2 };
|
||||
ip1s = { x: ip1s.x - brw / 2, y: ip1s.y + btw / 2 };
|
||||
ip1e = { x: ip1e.x - brw / 2, y: ip1e.y + btw / 2 };
|
||||
ip2s = { x: ip2s.x - brw / 2, y: ip2s.y - bbw / 2 };
|
||||
ip2e = { x: ip2e.x - brw / 2, y: ip2e.y - bbw / 2 };
|
||||
ip3s = { x: ip3s.x + blw / 2, y: ip3s.y - bbw / 2 };
|
||||
ip3e = { x: ip3e.x + blw / 2, y: ip3e.y - bbw / 2 };
|
||||
|
||||
op0 = { x: op0.x - blw / 2, y: op0.y - btw / 2 };
|
||||
op1 = { x: op1.x + brw / 2, y: op1.y - btw / 2 };
|
||||
op2 = { x: op2.x + brw / 2, y: op2.y + bbw / 2 };
|
||||
op3 = { x: op3.x - blw / 2, y: op3.y + bbw / 2 };
|
||||
op0s = { x: op0s.x - blw / 2, y: op0s.y - btw / 2 };
|
||||
op0e = { x: op0e.x - blw / 2, y: op0e.y - btw / 2 };
|
||||
op1s = { x: op1s.x + brw / 2, y: op1s.y - btw / 2 };
|
||||
op1e = { x: op1e.x + brw / 2, y: op1e.y - btw / 2 };
|
||||
op2s = { x: op2s.x + brw / 2, y: op2s.y + bbw / 2 };
|
||||
op2e = { x: op2e.x + brw / 2, y: op2e.y + bbw / 2 };
|
||||
op3s = { x: op3s.x - blw / 2, y: op3s.y + bbw / 2 };
|
||||
op3e = { x: op3e.x - blw / 2, y: op3e.y + bbw / 2 };
|
||||
}
|
||||
|
||||
return {
|
||||
btw,
|
||||
brw,
|
||||
bbw,
|
||||
blw,
|
||||
|
||||
btlr,
|
||||
btrr,
|
||||
bblr,
|
||||
bbrr,
|
||||
|
||||
p0,
|
||||
p1,
|
||||
p2,
|
||||
p3,
|
||||
p0s,
|
||||
p0e,
|
||||
p1s,
|
||||
p1e,
|
||||
p2s,
|
||||
p2e,
|
||||
p3s,
|
||||
p3e,
|
||||
|
||||
op0,
|
||||
op1,
|
||||
op2,
|
||||
op3,
|
||||
op0s,
|
||||
op0e,
|
||||
op1s,
|
||||
op1e,
|
||||
op2s,
|
||||
op2e,
|
||||
op3s,
|
||||
op3e,
|
||||
|
||||
ip0,
|
||||
ip1,
|
||||
ip2,
|
||||
ip3,
|
||||
ip0s,
|
||||
ip0e,
|
||||
ip1s,
|
||||
ip1e,
|
||||
ip2s,
|
||||
ip2e,
|
||||
ip3s,
|
||||
ip3e
|
||||
};
|
||||
}
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
import type { BoardContent, ViewContext2D } from '@idraw/types';
|
||||
import type { BoardContent } from '@idraw/types';
|
||||
import { Context2D } from './context2d';
|
||||
|
||||
export function createContext2D(opts: { ctx?: CanvasRenderingContext2D; width: number; height: number; devicePixelRatio: number }): Context2D {
|
||||
export function createContext2D(opts: {
|
||||
ctx?: CanvasRenderingContext2D;
|
||||
width: number;
|
||||
height: number;
|
||||
devicePixelRatio: number;
|
||||
}): Context2D {
|
||||
const { width, height, ctx, devicePixelRatio } = opts;
|
||||
let context: CanvasRenderingContext2D | undefined = ctx;
|
||||
if (!context) {
|
||||
|
|
@ -34,11 +39,9 @@ export function createBoardContent(
|
|||
width: number;
|
||||
height: number;
|
||||
devicePixelRatio: number;
|
||||
offscreen?: boolean;
|
||||
createCustomContext2D?: (opts: { width: number; height: number; devicePixelRatio: number }) => ViewContext2D;
|
||||
}
|
||||
): BoardContent {
|
||||
const { width, height, devicePixelRatio, offscreen, createCustomContext2D } = opts;
|
||||
const { width, height, devicePixelRatio } = opts;
|
||||
const ctxOpts = {
|
||||
width,
|
||||
height,
|
||||
|
|
@ -47,86 +50,32 @@ export function createBoardContent(
|
|||
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
|
||||
if (createCustomContext2D) {
|
||||
// TODO
|
||||
const viewContext = createCustomContext2D(ctxOpts);
|
||||
const overlayContext = createCustomContext2D(ctxOpts);
|
||||
const underlayContext = createCustomContext2D(ctxOpts);
|
||||
const boardContext = createContext2D({ ctx, ...ctxOpts });
|
||||
// const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const viewContext = createOffscreenContext2D(ctxOpts);
|
||||
const overlayContext = createOffscreenContext2D(ctxOpts);
|
||||
const underlayContext = createOffscreenContext2D(ctxOpts);
|
||||
const boardContext = createContext2D({ ctx, ...ctxOpts });
|
||||
const tempContext = createOffscreenContext2D(ctxOpts);
|
||||
|
||||
const drawView = () => {
|
||||
const { width: w, height: h } = viewContext.$getSize();
|
||||
const drawView = () => {
|
||||
const { width: w, height: h } = viewContext.$getSize();
|
||||
|
||||
boardContext.clearRect(0, 0, w, h);
|
||||
boardContext.drawImage(underlayContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(viewContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(overlayContext.canvas, 0, 0, w, h);
|
||||
underlayContext.clearRect(0, 0, w, h);
|
||||
viewContext.clearRect(0, 0, w, h);
|
||||
overlayContext.clearRect(0, 0, w, h);
|
||||
};
|
||||
boardContext.clearRect(0, 0, w, h);
|
||||
boardContext.drawImage(underlayContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(viewContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(overlayContext.canvas, 0, 0, w, h);
|
||||
underlayContext.clearRect(0, 0, w, h);
|
||||
viewContext.clearRect(0, 0, w, h);
|
||||
overlayContext.clearRect(0, 0, w, h);
|
||||
};
|
||||
|
||||
const content: BoardContent = {
|
||||
underlayContext,
|
||||
viewContext,
|
||||
overlayContext,
|
||||
boardContext,
|
||||
drawView
|
||||
};
|
||||
return content;
|
||||
}
|
||||
|
||||
if (offscreen === true) {
|
||||
// const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const viewContext = createOffscreenContext2D(ctxOpts);
|
||||
const overlayContext = createOffscreenContext2D(ctxOpts);
|
||||
const underlayContext = createOffscreenContext2D(ctxOpts);
|
||||
const boardContext = createContext2D({ ctx, ...ctxOpts });
|
||||
|
||||
const drawView = () => {
|
||||
const { width: w, height: h } = viewContext.$getSize();
|
||||
|
||||
boardContext.clearRect(0, 0, w, h);
|
||||
boardContext.drawImage(underlayContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(viewContext.canvas, 0, 0, w, h);
|
||||
boardContext.drawImage(overlayContext.canvas, 0, 0, w, h);
|
||||
underlayContext.clearRect(0, 0, w, h);
|
||||
viewContext.clearRect(0, 0, w, h);
|
||||
overlayContext.clearRect(0, 0, w, h);
|
||||
};
|
||||
|
||||
const content: BoardContent = {
|
||||
underlayContext,
|
||||
viewContext,
|
||||
overlayContext,
|
||||
boardContext,
|
||||
drawView
|
||||
};
|
||||
return content;
|
||||
} else {
|
||||
// const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const viewContext = createContext2D(ctxOpts);
|
||||
const overlayContext = createContext2D(ctxOpts);
|
||||
const underlayContext = createContext2D(ctxOpts);
|
||||
const boardContext = createContext2D({ ctx, ...ctxOpts });
|
||||
|
||||
const drawView = () => {
|
||||
boardContext.clearRect(0, 0, width, height);
|
||||
boardContext.drawImage(underlayContext.canvas, 0, 0, width, height);
|
||||
boardContext.drawImage(viewContext.canvas, 0, 0, width, height);
|
||||
boardContext.drawImage(overlayContext.canvas, 0, 0, width, height);
|
||||
underlayContext.clearRect(0, 0, width, height);
|
||||
viewContext.clearRect(0, 0, width, height);
|
||||
overlayContext.clearRect(0, 0, width, height);
|
||||
};
|
||||
|
||||
const content: BoardContent = {
|
||||
underlayContext,
|
||||
viewContext,
|
||||
overlayContext,
|
||||
boardContext,
|
||||
drawView
|
||||
};
|
||||
return content;
|
||||
}
|
||||
const content: BoardContent = {
|
||||
underlayContext,
|
||||
viewContext,
|
||||
overlayContext,
|
||||
boardContext,
|
||||
tempContext,
|
||||
drawView
|
||||
};
|
||||
return content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { LinearGradientColor, RadialGradientColor } from '@idraw/types';
|
||||
|
||||
export function toColorHexNum(color: string): number {
|
||||
return parseInt(color.replace(/^\#/, '0x'));
|
||||
return parseInt(color.replace(/^#/, '0x'));
|
||||
}
|
||||
|
||||
export function toColorHexStr(color: number): string {
|
||||
|
|
@ -9,7 +9,9 @@ export function toColorHexStr(color: number): string {
|
|||
}
|
||||
|
||||
export function isColorStr(color?: string): boolean {
|
||||
return typeof color === 'string' && (/^\#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color) || /^[a-z]{1,}$/i.test(color));
|
||||
return (
|
||||
typeof color === 'string' && (/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color) || /^[a-z]{1,}$/i.test(color))
|
||||
);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/1573053/javascript-function-to-convert-color-names-to-hex-codes
|
||||
|
|
@ -170,6 +172,8 @@ export function colorToCSS(color?: string | LinearGradientColor | RadialGradient
|
|||
let css = 'transparent';
|
||||
if (typeof color === 'string') {
|
||||
css = color;
|
||||
} else if (color?.stops.length === 1) {
|
||||
css = color.stops[0].color;
|
||||
} else if (color?.type === 'linear-gradient') {
|
||||
const items: string[] = [];
|
||||
if (typeof color.angle === 'number') {
|
||||
|
|
@ -220,13 +224,13 @@ export function mergeHexColorAlpha(hex: string, alpha: number): string {
|
|||
return hex;
|
||||
}
|
||||
let hexAlpha = 1;
|
||||
const regHex1 = /^\#[0-9a-f]{6,6}$/i;
|
||||
const regHex2 = /^\#[0-9a-f]{8,8}$/i;
|
||||
const regHex1 = /^#[0-9a-f]{6,6}$/i;
|
||||
const regHex2 = /^#[0-9a-f]{8,8}$/i;
|
||||
let result = hex;
|
||||
if (regHex1.test(hex)) {
|
||||
hexAlpha = parseInt(hex.substring(5, 7).replace(/^\#/, '0x'));
|
||||
hexAlpha = parseInt(hex.substring(5, 7).replace(/^#/, '0x'));
|
||||
} else if (regHex2.test(hex)) {
|
||||
hexAlpha = parseInt(hex.substring(7, 9).replace(/^\#/, '0x'));
|
||||
hexAlpha = parseInt(hex.substring(7, 9).replace(/^#/, '0x'));
|
||||
result = hex.substring(0, 7);
|
||||
}
|
||||
hexAlpha = hexAlpha * alpha;
|
||||
|
|
|
|||
|
|
@ -175,8 +175,22 @@ export class Context2D implements ViewContext2D {
|
|||
return this.#ctx.fill(...(args as [path: Path2D, fillRule?: CanvasFillRule | undefined]));
|
||||
}
|
||||
|
||||
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean | undefined): void {
|
||||
return this.#ctx.arc(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(radius), startAngle, endAngle, anticlockwise);
|
||||
arc(
|
||||
x: number,
|
||||
y: number,
|
||||
radius: number,
|
||||
startAngle: number,
|
||||
endAngle: number,
|
||||
anticlockwise?: boolean | undefined
|
||||
): void {
|
||||
return this.#ctx.arc(
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y),
|
||||
this.$doPixelRatio(radius),
|
||||
startAngle,
|
||||
endAngle,
|
||||
anticlockwise
|
||||
);
|
||||
}
|
||||
|
||||
rect(x: number, y: number, w: number, h: number) {
|
||||
|
|
@ -184,11 +198,21 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
fillRect(x: number, y: number, w: number, h: number) {
|
||||
return this.#ctx.fillRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
|
||||
return this.#ctx.fillRect(
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y),
|
||||
this.$doPixelRatio(w),
|
||||
this.$doPixelRatio(h)
|
||||
);
|
||||
}
|
||||
|
||||
clearRect(x: number, y: number, w: number, h: number) {
|
||||
return this.#ctx.clearRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
|
||||
return this.#ctx.clearRect(
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y),
|
||||
this.$doPixelRatio(w),
|
||||
this.$doPixelRatio(h)
|
||||
);
|
||||
}
|
||||
|
||||
beginPath() {
|
||||
|
|
@ -208,7 +232,32 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void {
|
||||
return this.#ctx.arcTo(this.$doPixelRatio(x1), this.$doPixelRatio(y1), this.$doPixelRatio(x2), this.$doPixelRatio(y2), this.$doPixelRatio(radius));
|
||||
return this.#ctx.arcTo(
|
||||
this.$doPixelRatio(x1),
|
||||
this.$doPixelRatio(y1),
|
||||
this.$doPixelRatio(x2),
|
||||
this.$doPixelRatio(y2),
|
||||
this.$doPixelRatio(radius)
|
||||
);
|
||||
}
|
||||
|
||||
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {
|
||||
return this.#ctx.bezierCurveTo(
|
||||
this.$doPixelRatio(cp1x),
|
||||
this.$doPixelRatio(cp1y),
|
||||
this.$doPixelRatio(cp2x),
|
||||
this.$doPixelRatio(cp2y),
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y)
|
||||
);
|
||||
}
|
||||
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {
|
||||
return this.#ctx.quadraticCurveTo(
|
||||
this.$doPixelRatio(cpx),
|
||||
this.$doPixelRatio(cpy),
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y)
|
||||
);
|
||||
}
|
||||
|
||||
getLineDash() {
|
||||
|
|
@ -257,7 +306,13 @@ export class Context2D implements ViewContext2D {
|
|||
this.$doPixelRatio(dh)
|
||||
);
|
||||
} else {
|
||||
return this.#ctx.drawImage(image, this.$doPixelRatio(dx), this.$doPixelRatio(dy), this.$doPixelRatio(dw), this.$doPixelRatio(dh));
|
||||
return this.#ctx.drawImage(
|
||||
image,
|
||||
this.$doPixelRatio(dx),
|
||||
this.$doPixelRatio(dy),
|
||||
this.$doPixelRatio(dw),
|
||||
this.$doPixelRatio(dh)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +393,12 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient {
|
||||
return this.#ctx.createLinearGradient(this.$doPixelRatio(x0), this.$doPixelRatio(y0), this.$doPixelRatio(x1), this.$doPixelRatio(y1));
|
||||
return this.#ctx.createLinearGradient(
|
||||
this.$doPixelRatio(x0),
|
||||
this.$doPixelRatio(y0),
|
||||
this.$doPixelRatio(x1),
|
||||
this.$doPixelRatio(y1)
|
||||
);
|
||||
}
|
||||
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient {
|
||||
return this.#ctx.createRadialGradient(
|
||||
|
|
|
|||
|
|
@ -42,11 +42,24 @@ export function deepCloneElement<T extends Element = Element>(element: T): T {
|
|||
return elem;
|
||||
}
|
||||
|
||||
export function deepCloneData(data: Data): Data {
|
||||
const { elements, ...restData } = data;
|
||||
return {
|
||||
...deepClone(restData),
|
||||
...{
|
||||
elements: elements.map((elem) => deepCloneElement(elem))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function is(target: any): string {
|
||||
return Object.prototype.toString
|
||||
.call(target)
|
||||
.replace(/[\]|\[]{1,1}/gi, '')
|
||||
.split(' ')[1];
|
||||
return (
|
||||
Object.prototype.toString
|
||||
.call(target)
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
.replace(/[\]|\[]{1,1}/gi, '')
|
||||
.split(' ')[1]
|
||||
);
|
||||
}
|
||||
|
||||
export function sortDataAsserts(data: Data, opts?: { clone?: boolean }): Data {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { isColorStr } from './color';
|
||||
|
||||
function positiveNum(value: any) {
|
||||
return typeof value === 'number' && value >= 0;
|
||||
}
|
||||
|
||||
function number(value: any) {
|
||||
return typeof value === 'number' && (value > 0 || value <= 0);
|
||||
}
|
||||
|
|
@ -13,11 +17,11 @@ function y(value: any) {
|
|||
}
|
||||
|
||||
function w(value: any) {
|
||||
return typeof value === 'number' && value >= 0;
|
||||
return positiveNum(value);
|
||||
}
|
||||
|
||||
function h(value: any) {
|
||||
return typeof value === 'number' && value >= 0;
|
||||
return positiveNum(value);
|
||||
}
|
||||
|
||||
function angle(value: any) {
|
||||
|
|
@ -25,11 +29,25 @@ function angle(value: any) {
|
|||
}
|
||||
|
||||
function borderWidth(value: any) {
|
||||
return w(value);
|
||||
return (
|
||||
positiveNum(value) ||
|
||||
(Array.isArray(value) &&
|
||||
positiveNum(value[0]) &&
|
||||
positiveNum(value[1]) &&
|
||||
positiveNum(value[2]) &&
|
||||
positiveNum(value[3]))
|
||||
);
|
||||
}
|
||||
|
||||
function borderRadius(value: any) {
|
||||
return number(value) && value >= 0;
|
||||
return (
|
||||
positiveNum(value) ||
|
||||
(Array.isArray(value) &&
|
||||
positiveNum(value[0]) &&
|
||||
positiveNum(value[1]) &&
|
||||
positiveNum(value[2]) &&
|
||||
positiveNum(value[3]))
|
||||
);
|
||||
}
|
||||
|
||||
function color(value: any) {
|
||||
|
|
@ -49,7 +67,11 @@ function imageSrc(value: any) {
|
|||
}
|
||||
|
||||
function svg(value: any) {
|
||||
return typeof value === 'string' && /^(<svg[\s]{1,}|<svg>)/i.test(`${value}`.trim()) && /<\/[\s]{0,}svg>$/i.test(`${value}`.trim());
|
||||
return (
|
||||
typeof value === 'string' &&
|
||||
/^(<svg[\s]{1,}|<svg>)/i.test(`${value}`.trim()) &&
|
||||
/<\/[\s]{0,}svg>$/i.test(`${value}`.trim())
|
||||
);
|
||||
}
|
||||
|
||||
function html(value: any) {
|
||||
|
|
@ -98,6 +120,7 @@ function numberStr(value: any): boolean {
|
|||
}
|
||||
|
||||
export const is = {
|
||||
positiveNum,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
|
|
|
|||
22
packages/util/src/lib/merge.ts
Normal file
22
packages/util/src/lib/merge.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export function merge<T extends Record<string, any> = any, U extends Record<string, any> = any>(
|
||||
target: T,
|
||||
source: U
|
||||
): T & U {
|
||||
type Result = T & U;
|
||||
const result: Result = target as Result;
|
||||
for (const key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
if (
|
||||
typeof source[key] === 'object' &&
|
||||
source[key] !== null &&
|
||||
typeof result[key] === 'object' &&
|
||||
result[key] !== null
|
||||
) {
|
||||
result[key] = merge(result[key] as object, source[key] as object) as any;
|
||||
} else {
|
||||
result[key] = source[key] as any;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target as T & U;
|
||||
}
|
||||
11
packages/util/src/lib/omit.ts
Normal file
11
packages/util/src/lib/omit.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export function omit<T extends Record<string, any>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
|
||||
// Create a shallow copy of the object
|
||||
const result = { ...obj };
|
||||
|
||||
// Remove the specified keys
|
||||
for (const key of keys) {
|
||||
delete result[key];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2,10 +2,14 @@ import type { Element, ViewScaleInfo, ViewSizeInfo, ViewBoxSize } from '@idraw/t
|
|||
import { getDefaultElementDetailConfig } from './config';
|
||||
const defaultElemConfig = getDefaultElementDetailConfig();
|
||||
|
||||
export function calcViewBoxSize(viewElem: Element, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewBoxSize {
|
||||
export function calcViewBoxSize(
|
||||
viewElem: Element,
|
||||
opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }
|
||||
): ViewBoxSize {
|
||||
const { viewScaleInfo } = opts;
|
||||
const { scale } = viewScaleInfo;
|
||||
let { borderRadius, borderDash } = viewElem.detail;
|
||||
let { borderRadius } = viewElem.detail;
|
||||
const { borderDash } = viewElem.detail;
|
||||
const hasBorderDash = Array.isArray(borderDash) && borderDash.length > 0;
|
||||
|
||||
const { boxSizing = defaultElemConfig.boxSizing, borderWidth } = viewElem.detail;
|
||||
|
|
|
|||
|
|
@ -9,15 +9,17 @@ import {
|
|||
ElementSize,
|
||||
ViewContext2D,
|
||||
ViewRectVertexes,
|
||||
ViewRectInfo,
|
||||
ViewRectInfoMap
|
||||
ViewRectInfo
|
||||
} from '@idraw/types';
|
||||
import { rotateElementVertexes } from './rotate';
|
||||
import { checkRectIntersect } from './rect';
|
||||
import { calcElementVertexesInGroup, calcElementVertexes } from './vertex';
|
||||
import { getCenterFromTwoPoints } from './point';
|
||||
|
||||
export function calcViewScaleInfo(info: { scale: number; offsetX: number; offsetY: number }, opts: { viewSizeInfo: ViewSizeInfo }): ViewScaleInfo {
|
||||
export function calcViewScaleInfo(
|
||||
info: { scale: number; offsetX: number; offsetY: number },
|
||||
opts: { viewSizeInfo: ViewSizeInfo }
|
||||
): ViewScaleInfo {
|
||||
const { scale, offsetX, offsetY } = info;
|
||||
const { viewSizeInfo } = opts;
|
||||
const { width, height, contextWidth, contextHeight } = viewSizeInfo;
|
||||
|
|
@ -38,7 +40,12 @@ export function calcViewScaleInfo(info: { scale: number; offsetX: number; offset
|
|||
return newScaleInfo;
|
||||
}
|
||||
|
||||
export function viewScale(opts: { scale: number; point: PointSize; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): {
|
||||
export function viewScale(opts: {
|
||||
scale: number;
|
||||
point: PointSize;
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
}): {
|
||||
moveX: number;
|
||||
moveY: number;
|
||||
} {
|
||||
|
|
@ -55,7 +62,12 @@ export function viewScale(opts: { scale: number; point: PointSize; viewScaleInfo
|
|||
};
|
||||
}
|
||||
|
||||
export function viewScroll(opts: { moveX?: number; moveY?: number; viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewScaleInfo {
|
||||
export function viewScroll(opts: {
|
||||
moveX?: number;
|
||||
moveY?: number;
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
viewSizeInfo: ViewSizeInfo;
|
||||
}): ViewScaleInfo {
|
||||
const { moveX = 0, moveY = 0, viewScaleInfo, viewSizeInfo } = opts;
|
||||
|
||||
const { scale } = viewScaleInfo;
|
||||
|
|
@ -110,7 +122,10 @@ export function calcViewPointSize(size: PointSize, opts: { viewScaleInfo: ViewSc
|
|||
return newSize;
|
||||
}
|
||||
|
||||
export function calcViewVertexes(vertexes: ViewRectVertexes, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewRectVertexes {
|
||||
export function calcViewVertexes(
|
||||
vertexes: ViewRectVertexes,
|
||||
opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }
|
||||
): ViewRectVertexes {
|
||||
return [
|
||||
calcViewPointSize(vertexes[0], opts),
|
||||
calcViewPointSize(vertexes[1], opts),
|
||||
|
|
@ -264,7 +279,10 @@ export function getViewPointAtElement(
|
|||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function isElementInView(elem: ElementSize, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): boolean {
|
||||
export function isElementInView(
|
||||
elem: ElementSize,
|
||||
opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }
|
||||
): boolean {
|
||||
const { viewSizeInfo, viewScaleInfo } = opts;
|
||||
const { width, height } = viewSizeInfo;
|
||||
const { angle } = elem;
|
||||
|
|
@ -325,10 +343,30 @@ export function calcElementOriginRectInfo(
|
|||
}
|
||||
|
||||
export function originRectInfoToRangeRectInfo(originRectInfo: ViewRectInfo): ViewRectInfo {
|
||||
const rangeMaxX = Math.max(originRectInfo.topLeft.x, originRectInfo.topRight.x, originRectInfo.bottomRight.x, originRectInfo.bottomLeft.x);
|
||||
const rangeMaxY = Math.max(originRectInfo.topLeft.y, originRectInfo.topRight.y, originRectInfo.bottomRight.y, originRectInfo.bottomLeft.y);
|
||||
const rangeMinX = Math.min(originRectInfo.topLeft.x, originRectInfo.topRight.x, originRectInfo.bottomRight.x, originRectInfo.bottomLeft.x);
|
||||
const rangeMinY = Math.min(originRectInfo.topLeft.y, originRectInfo.topRight.y, originRectInfo.bottomRight.y, originRectInfo.bottomLeft.y);
|
||||
const rangeMaxX = Math.max(
|
||||
originRectInfo.topLeft.x,
|
||||
originRectInfo.topRight.x,
|
||||
originRectInfo.bottomRight.x,
|
||||
originRectInfo.bottomLeft.x
|
||||
);
|
||||
const rangeMaxY = Math.max(
|
||||
originRectInfo.topLeft.y,
|
||||
originRectInfo.topRight.y,
|
||||
originRectInfo.bottomRight.y,
|
||||
originRectInfo.bottomLeft.y
|
||||
);
|
||||
const rangeMinX = Math.min(
|
||||
originRectInfo.topLeft.x,
|
||||
originRectInfo.topRight.x,
|
||||
originRectInfo.bottomRight.x,
|
||||
originRectInfo.bottomLeft.x
|
||||
);
|
||||
const rangeMinY = Math.min(
|
||||
originRectInfo.topLeft.y,
|
||||
originRectInfo.topRight.y,
|
||||
originRectInfo.bottomRight.y,
|
||||
originRectInfo.bottomLeft.y
|
||||
);
|
||||
|
||||
const rangeCenter = { x: originRectInfo.center.x, y: originRectInfo.center.y };
|
||||
const rangeTopLeft = { x: rangeMinX, y: rangeMinY };
|
||||
|
|
@ -384,10 +422,30 @@ export function calcElementViewRectInfo(
|
|||
|
||||
if (range === true) {
|
||||
// Range RectInfo
|
||||
const viewMaxX = Math.max(viewRectInfo.topLeft.x, viewRectInfo.topRight.x, viewRectInfo.bottomRight.x, viewRectInfo.bottomLeft.x);
|
||||
const viewMaxY = Math.max(viewRectInfo.topLeft.y, viewRectInfo.topRight.y, viewRectInfo.bottomRight.y, viewRectInfo.bottomLeft.y);
|
||||
const viewMinX = Math.min(viewRectInfo.topLeft.x, viewRectInfo.topRight.x, viewRectInfo.bottomRight.x, viewRectInfo.bottomLeft.x);
|
||||
const viewMinY = Math.min(viewRectInfo.topLeft.y, viewRectInfo.topRight.y, viewRectInfo.bottomRight.y, viewRectInfo.bottomLeft.y);
|
||||
const viewMaxX = Math.max(
|
||||
viewRectInfo.topLeft.x,
|
||||
viewRectInfo.topRight.x,
|
||||
viewRectInfo.bottomRight.x,
|
||||
viewRectInfo.bottomLeft.x
|
||||
);
|
||||
const viewMaxY = Math.max(
|
||||
viewRectInfo.topLeft.y,
|
||||
viewRectInfo.topRight.y,
|
||||
viewRectInfo.bottomRight.y,
|
||||
viewRectInfo.bottomLeft.y
|
||||
);
|
||||
const viewMinX = Math.min(
|
||||
viewRectInfo.topLeft.x,
|
||||
viewRectInfo.topRight.x,
|
||||
viewRectInfo.bottomRight.x,
|
||||
viewRectInfo.bottomLeft.x
|
||||
);
|
||||
const viewMinY = Math.min(
|
||||
viewRectInfo.topLeft.y,
|
||||
viewRectInfo.topRight.y,
|
||||
viewRectInfo.bottomRight.y,
|
||||
viewRectInfo.bottomLeft.y
|
||||
);
|
||||
|
||||
const rangeCenter = { x: viewRectInfo.center.x, y: viewRectInfo.center.y };
|
||||
const rangeTopLeft = { x: viewMinX, y: viewMinY };
|
||||
|
|
@ -416,65 +474,3 @@ export function calcElementViewRectInfo(
|
|||
|
||||
return viewRectInfo;
|
||||
}
|
||||
|
||||
export function calcElementViewRectInfoMap(
|
||||
elemSize: ElementSize,
|
||||
opts: {
|
||||
groupQueue: Element<'group'>[];
|
||||
viewScaleInfo: ViewScaleInfo;
|
||||
}
|
||||
): ViewRectInfoMap {
|
||||
const { groupQueue, viewScaleInfo } = opts;
|
||||
|
||||
// Original RectInfo
|
||||
const originRectInfo = calcElementOriginRectInfo(elemSize, { groupQueue });
|
||||
const { center, top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight } = originRectInfo;
|
||||
|
||||
// View RectInfo
|
||||
const viewRectInfo: ViewRectInfo = {
|
||||
center: calcViewPointSize(center, { viewScaleInfo }),
|
||||
topLeft: calcViewPointSize(topLeft, { viewScaleInfo }),
|
||||
topRight: calcViewPointSize(topRight, { viewScaleInfo }),
|
||||
bottomLeft: calcViewPointSize(bottomLeft, { viewScaleInfo }),
|
||||
bottomRight: calcViewPointSize(bottomRight, { viewScaleInfo }),
|
||||
top: calcViewPointSize(top, { viewScaleInfo }),
|
||||
right: calcViewPointSize(right, { viewScaleInfo }),
|
||||
left: calcViewPointSize(left, { viewScaleInfo }),
|
||||
bottom: calcViewPointSize(bottom, { viewScaleInfo })
|
||||
};
|
||||
|
||||
// Range RectInfo
|
||||
const viewMaxX = Math.max(viewRectInfo.topLeft.x, viewRectInfo.topRight.x, viewRectInfo.bottomRight.x, viewRectInfo.bottomLeft.x);
|
||||
const viewMaxY = Math.max(viewRectInfo.topLeft.y, viewRectInfo.topRight.y, viewRectInfo.bottomRight.y, viewRectInfo.bottomLeft.y);
|
||||
const viewMinX = Math.min(viewRectInfo.topLeft.x, viewRectInfo.topRight.x, viewRectInfo.bottomRight.x, viewRectInfo.bottomLeft.x);
|
||||
const viewMinY = Math.min(viewRectInfo.topLeft.y, viewRectInfo.topRight.y, viewRectInfo.bottomRight.y, viewRectInfo.bottomLeft.y);
|
||||
|
||||
const rangeCenter = { x: viewRectInfo.center.x, y: viewRectInfo.center.y };
|
||||
const rangeTopLeft = { x: viewMinX, y: viewMinY };
|
||||
const rangeTopRight = { x: viewMaxX, y: viewMinY };
|
||||
const rangeBottomRight = { x: viewMaxX, y: viewMaxY };
|
||||
const rangeBottomLeft = { x: viewMinX, y: viewMaxY };
|
||||
|
||||
const rangeTop = getCenterFromTwoPoints(rangeTopLeft, rangeTopRight);
|
||||
const rangeBottom = getCenterFromTwoPoints(rangeBottomLeft, rangeBottomRight);
|
||||
const rangeLeft = getCenterFromTwoPoints(rangeTopLeft, rangeBottomLeft);
|
||||
const rangeRight = getCenterFromTwoPoints(rangeTopRight, rangeBottomRight);
|
||||
|
||||
const rangeRectInfo: ViewRectInfo = {
|
||||
center: rangeCenter,
|
||||
topLeft: rangeTopLeft,
|
||||
topRight: rangeTopRight,
|
||||
bottomLeft: rangeBottomLeft,
|
||||
bottomRight: rangeBottomRight,
|
||||
top: rangeTop,
|
||||
right: rangeRight,
|
||||
left: rangeLeft,
|
||||
bottom: rangeBottom
|
||||
};
|
||||
|
||||
return {
|
||||
originRectInfo,
|
||||
// viewRectInfo,
|
||||
rangeRectInfo
|
||||
};
|
||||
}
|
||||
|
|
|
|||
4542
pnpm-lock.yaml
4542
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -5,10 +5,6 @@ const packages = [
|
|||
dirName: 'util',
|
||||
globalName: 'iDrawUtil'
|
||||
},
|
||||
{
|
||||
dirName: 'board',
|
||||
globalName: 'iDrawBoard'
|
||||
},
|
||||
{
|
||||
dirName: 'renderer',
|
||||
globalName: 'iDrawRenderer'
|
||||
|
|
|
|||
Loading…
Reference in a new issue