@visactor/vrender-core 0.17.19-alpha.1 → 0.17.20-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/core/stage.d.ts +2 -1
- package/cjs/core/stage.js +8 -4
- package/cjs/core/stage.js.map +1 -1
- package/cjs/graphic/graphic.js +3 -3
- package/cjs/graphic/graphic.js.map +1 -1
- package/cjs/graphic/node-tree.js +1 -4
- package/cjs/graphic/node-tree.js.map +1 -1
- package/cjs/graphic/richtext/frame.d.ts +2 -2
- package/cjs/graphic/richtext/frame.js +1 -12
- package/cjs/graphic/richtext/frame.js.map +1 -1
- package/cjs/graphic/richtext/line.js +1 -12
- package/cjs/graphic/richtext/line.js.map +1 -1
- package/cjs/graphic/richtext/paragraph.js +2 -2
- package/cjs/graphic/richtext/paragraph.js.map +1 -1
- package/cjs/interface/graphic/richText.d.ts +1 -1
- package/cjs/interface/graphic/richText.js.map +1 -1
- package/cjs/interface/graphic.d.ts +2 -2
- package/cjs/interface/graphic.js.map +1 -1
- package/cjs/interface/picker.d.ts +1 -0
- package/cjs/interface/picker.js.map +1 -1
- package/cjs/interface/render.d.ts +1 -0
- package/cjs/interface/render.js.map +1 -1
- package/cjs/interface/stage.d.ts +3 -1
- package/cjs/interface/stage.js.map +1 -1
- package/cjs/picker/picker-service.js +8 -3
- package/cjs/picker/picker-service.js.map +1 -1
- package/cjs/plugins/builtin-plugin/flex-layout-plugin.d.ts +14 -3
- package/cjs/plugins/builtin-plugin/flex-layout-plugin.js +126 -65
- package/cjs/plugins/builtin-plugin/flex-layout-plugin.js.map +1 -1
- package/cjs/render/contributions/render/draw-contribution.js +13 -6
- package/cjs/render/contributions/render/draw-contribution.js.map +1 -1
- package/cjs/render/contributions/render/image-render.js +2 -4
- package/cjs/render/contributions/render/image-render.js.map +1 -1
- package/cjs/render/contributions/render/incremental-draw-contribution.js +18 -10
- package/cjs/render/contributions/render/incremental-draw-contribution.js.map +1 -1
- package/cjs/render/contributions/render/index.d.ts +0 -1
- package/cjs/render/contributions/render/index.js +1 -2
- package/cjs/render/contributions/render/index.js.map +1 -1
- package/cjs/resource-loader/loader.d.ts +0 -5
- package/cjs/resource-loader/loader.js +15 -56
- package/cjs/resource-loader/loader.js.map +1 -1
- package/es/core/stage.d.ts +2 -1
- package/es/core/stage.js +8 -4
- package/es/core/stage.js.map +1 -1
- package/es/graphic/graphic.js +4 -4
- package/es/graphic/graphic.js.map +1 -1
- package/es/graphic/node-tree.js +1 -4
- package/es/graphic/node-tree.js.map +1 -1
- package/es/graphic/richtext/frame.d.ts +2 -2
- package/es/graphic/richtext/frame.js +1 -12
- package/es/graphic/richtext/frame.js.map +1 -1
- package/es/graphic/richtext/line.js +1 -12
- package/es/graphic/richtext/line.js.map +1 -1
- package/es/graphic/richtext/paragraph.js +2 -2
- package/es/graphic/richtext/paragraph.js.map +1 -1
- package/es/interface/graphic/richText.d.ts +1 -1
- package/es/interface/graphic/richText.js.map +1 -1
- package/es/interface/graphic.d.ts +2 -2
- package/es/interface/graphic.js.map +1 -1
- package/es/interface/picker.d.ts +1 -0
- package/es/interface/picker.js.map +1 -1
- package/es/interface/render.d.ts +1 -0
- package/es/interface/render.js.map +1 -1
- package/es/interface/stage.d.ts +3 -1
- package/es/interface/stage.js.map +1 -1
- package/es/picker/picker-service.js +8 -3
- package/es/picker/picker-service.js.map +1 -1
- package/es/plugins/builtin-plugin/flex-layout-plugin.d.ts +14 -3
- package/es/plugins/builtin-plugin/flex-layout-plugin.js +126 -69
- package/es/plugins/builtin-plugin/flex-layout-plugin.js.map +1 -1
- package/es/render/contributions/render/draw-contribution.js +13 -6
- package/es/render/contributions/render/draw-contribution.js.map +1 -1
- package/es/render/contributions/render/image-render.js +2 -6
- package/es/render/contributions/render/image-render.js.map +1 -1
- package/es/render/contributions/render/incremental-draw-contribution.js +18 -10
- package/es/render/contributions/render/incremental-draw-contribution.js.map +1 -1
- package/es/render/contributions/render/index.d.ts +0 -1
- package/es/render/contributions/render/index.js +0 -2
- package/es/render/contributions/render/index.js.map +1 -1
- package/es/resource-loader/loader.d.ts +0 -5
- package/es/resource-loader/loader.js +14 -56
- package/es/resource-loader/loader.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ export default class Frame {
|
|
|
12
12
|
wordBreak: 'break-word' | 'break-all';
|
|
13
13
|
verticalDirection: 'top' | 'middle' | 'bottom';
|
|
14
14
|
lines: Line[];
|
|
15
|
-
globalAlign: 'left' | 'center' | 'right';
|
|
15
|
+
globalAlign: 'left' | 'center' | 'right' | 'start' | 'end';
|
|
16
16
|
globalBaseline: 'top' | 'middle' | 'bottom';
|
|
17
17
|
layoutDirection: 'horizontal' | 'vertical';
|
|
18
18
|
directionKey: {
|
|
@@ -26,7 +26,7 @@ export default class Frame {
|
|
|
26
26
|
isHeightMax: boolean;
|
|
27
27
|
singleLine: boolean;
|
|
28
28
|
icons: Map<string, IRichTextIcon>;
|
|
29
|
-
constructor(left: number, top: number, width: number, height: number, ellipsis: boolean | string, wordBreak: 'break-word' | 'break-all', verticalDirection: 'top' | 'middle' | 'bottom', globalAlign: 'left' | 'center' | 'right', globalBaseline: 'top' | 'middle' | 'bottom', layoutDirection: 'horizontal' | 'vertical', isWidthMax: boolean, isHeightMax: boolean, singleLine: boolean, icons?: Map<string, IRichTextIcon>);
|
|
29
|
+
constructor(left: number, top: number, width: number, height: number, ellipsis: boolean | string, wordBreak: 'break-word' | 'break-all', verticalDirection: 'top' | 'middle' | 'bottom', globalAlign: 'left' | 'center' | 'right' | 'start' | 'end', globalBaseline: 'top' | 'middle' | 'bottom', layoutDirection: 'horizontal' | 'vertical', isWidthMax: boolean, isHeightMax: boolean, singleLine: boolean, icons?: Map<string, IRichTextIcon>);
|
|
30
30
|
draw(ctx: IContext2d, drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void): boolean;
|
|
31
31
|
getActualSize(): {
|
|
32
32
|
width: number;
|
|
@@ -34,18 +34,7 @@ class Frame {
|
|
|
34
34
|
deltaY = -height;
|
|
35
35
|
}
|
|
36
36
|
let deltaX = 0;
|
|
37
|
-
|
|
38
|
-
case "left":
|
|
39
|
-
deltaX = 0;
|
|
40
|
-
break;
|
|
41
|
-
|
|
42
|
-
case "center":
|
|
43
|
-
deltaX = -width / 2;
|
|
44
|
-
break;
|
|
45
|
-
|
|
46
|
-
case "right":
|
|
47
|
-
deltaX = -width;
|
|
48
|
-
}
|
|
37
|
+
"right" === this.globalAlign || "end" === this.globalAlign ? deltaX = -width : "center" === this.globalAlign && (deltaX = -width / 2);
|
|
49
38
|
let frameHeight = this[this.directionKey.height];
|
|
50
39
|
this.singleLine && (frameHeight = this.lines[0].height + 1);
|
|
51
40
|
let lastLineTag = !1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphic/richtext/frame.ts"],"names":[],"mappings":"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","file":"frame.js","sourcesContent":["// import { IContext2d } from '../../IContext';\nimport type { IContext2d, IRichTextIcon } from '../../interface';\nimport type Line from './line';\nimport { DIRECTION_KEY } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 文字窗口\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/frame.js\nexport default class Frame {\n left: number;\n top: number;\n bottom: number;\n right: number;\n width: number;\n height: number;\n actualHeight: number;\n ellipsis: boolean | string;\n wordBreak: 'break-word' | 'break-all';\n verticalDirection: 'top' | 'middle' | 'bottom';\n lines: Line[];\n // ctx: IContext2d;\n globalAlign: 'left' | 'center' | 'right';\n globalBaseline: 'top' | 'middle' | 'bottom';\n layoutDirection: 'horizontal' | 'vertical';\n directionKey: { width: string; height: string; left: string; top: string; bottom: string };\n isWidthMax: boolean;\n isHeightMax: boolean;\n\n singleLine: boolean;\n\n icons: Map<string, IRichTextIcon>;\n\n constructor(\n left: number,\n top: number,\n width: number,\n height: number,\n ellipsis: boolean | string,\n wordBreak: 'break-word' | 'break-all',\n verticalDirection: 'top' | 'middle' | 'bottom',\n // ctx: IContext2d,\n globalAlign: 'left' | 'center' | 'right',\n globalBaseline: 'top' | 'middle' | 'bottom',\n layoutDirection: 'horizontal' | 'vertical',\n isWidthMax: boolean,\n isHeightMax: boolean,\n singleLine: boolean,\n icons?: Map<string, IRichTextIcon>\n ) {\n this.left = left;\n this.top = top;\n this.width = width;\n this.height = height;\n this.actualHeight = 0;\n this.bottom = top + height;\n this.right = left + width;\n this.ellipsis = ellipsis;\n this.wordBreak = wordBreak;\n this.verticalDirection = verticalDirection;\n this.lines = [];\n // this.ctx = ctx;\n this.globalAlign = globalAlign;\n this.globalBaseline = globalBaseline;\n this.layoutDirection = layoutDirection;\n this.directionKey = DIRECTION_KEY[this.layoutDirection];\n\n this.isWidthMax = isWidthMax;\n this.isHeightMax = isHeightMax;\n\n this.singleLine = singleLine;\n\n if (icons) {\n icons.clear();\n this.icons = icons;\n } else {\n this.icons = new Map();\n }\n }\n\n draw(\n ctx: IContext2d,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) {\n const { width: actualWidth, height: actualHeight } = this.getActualSize();\n const width = this.isWidthMax ? Math.min(this.width, actualWidth) : this.width || actualWidth || 0;\n let height = this.isHeightMax ? Math.min(this.height, actualHeight) : this.height || actualHeight || 0;\n // 1. height 可能受 maxHeight 影响大于 actualHeight 计算出来的实际高度\n // 2. actualHeight 是不加省略内容的高度,可能会大于 height\n // 以上两种情况都可以通过 Math.min 解决\n height = Math.min(height, actualHeight);\n /**\n * 根据 align 和 baseline 进行偏移\n */\n let deltaY = 0;\n switch (this.globalBaseline) {\n case 'top':\n deltaY = 0;\n break;\n case 'middle':\n deltaY = -height / 2;\n break;\n case 'bottom':\n deltaY = -height;\n break;\n default:\n break;\n }\n\n let deltaX = 0;\n switch (this.globalAlign) {\n case 'left':\n deltaX = 0;\n break;\n case 'center':\n deltaX = -width / 2;\n break;\n case 'right':\n deltaX = -width;\n break;\n default:\n break;\n }\n\n let frameHeight = this[this.directionKey.height];\n if (this.singleLine) {\n frameHeight = this.lines[0].height + 1;\n }\n let lastLineTag = false;\n if (this.verticalDirection === 'middle') {\n if (this.actualHeight >= frameHeight && frameHeight !== 0) {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) {\n return lastLineTag; // 不在展示范围内的line不绘制\n }\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(\n ctx,\n lastLine,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n } else {\n const detalHeight = Math.floor((frameHeight - this.actualHeight) / 2);\n if (this.layoutDirection === 'vertical') {\n deltaX += detalHeight;\n } else {\n deltaY += detalHeight;\n }\n for (let i = 0; i < this.lines.length; i++) {\n this.lines[i].draw(\n ctx,\n false,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n }\n\n // top = this.top + (this.height - this.actualHeight) / 2\n } else if (this.verticalDirection === 'bottom' && this.layoutDirection !== 'vertical') {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n const y = frameHeight - this.lines[i].top - this.lines[i].height;\n // if (y + height < this.top || y + height > this.bottom) {\n if (frameHeight === 0) {\n this.lines[i].draw(ctx, false, deltaX, y + deltaY, drawIcon);\n } else if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) {\n return lastLineTag; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top]) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(ctx, lastLine, deltaX, y + deltaY, drawIcon);\n }\n }\n } else {\n if (\n this.verticalDirection === 'bottom' &&\n this.layoutDirection === 'vertical' &&\n this.singleLine &&\n this.isWidthMax\n ) {\n deltaX += this.lines[0].height + 1;\n }\n for (let i = 0; i < this.lines.length; i++) {\n if (this.verticalDirection === 'bottom' && this.layoutDirection === 'vertical') {\n deltaX -= this.lines[i].height + this.lines[i].top;\n }\n const { top, height } = this.lines[i];\n if (frameHeight === 0) {\n this.lines[i].draw(\n ctx,\n false,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n } else if (\n top + height < this[this.directionKey.top] ||\n top + height > this[this.directionKey.top] + frameHeight\n ) {\n return lastLineTag; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(\n ctx,\n lastLine,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n }\n }\n\n return lastLineTag;\n }\n\n getActualSize(): { width: number; height: number } {\n if (this.ellipsis) {\n return this.getActualSizeWidthEllipsis();\n }\n\n return this.getRawActualSize();\n }\n\n getRawActualSize(): { width: number; height: number } {\n let width: number = 0;\n let height: number = 0;\n for (let i = 0; i < this.lines.length; i++) {\n const line = this.lines[i];\n if (line.actualWidth > width) {\n width = line.actualWidth;\n }\n height += line.height;\n }\n\n // return { width, height };\n return {\n width: this.layoutDirection === 'vertical' ? height : width,\n height: this.layoutDirection === 'vertical' ? width : height\n };\n }\n\n getActualSizeWidthEllipsis(): { width: number; height: number } {\n let widthBound: number = 0;\n let heightBound: number = 0;\n\n const { width: actualWidth, height: actualHeight } = this.getRawActualSize();\n const width = this.width || actualWidth || 0;\n let height = this.height || actualHeight || 0;\n // 1. height 可能受 maxHeight 影响大于 actualHeight 计算出来的实际高度\n // 2. actualHeight 是不加省略内容的高度,可能会大于 height\n // 以上两种情况都可以通过 Math.min 解决\n height = Math.min(height, actualHeight);\n /**\n * 根据 align 和 baseline 进行偏移\n */\n const deltaY = 0;\n\n let frameHeight = this[this.directionKey.height];\n if (this.singleLine) {\n frameHeight = this.lines[0].height + 1;\n }\n\n if (this.verticalDirection === 'middle') {\n if (this.actualHeight >= frameHeight && frameHeight !== 0) {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n // this.lines[i].draw(ctx, lastLine, deltaX, this.lines[i].top + deltaY);\n }\n }\n } else {\n const detalHeight = Math.floor((frameHeight - this.actualHeight) / 2);\n for (let i = 0; i < this.lines.length; i++) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n\n // top = this.top + (this.height - this.actualHeight) / 2\n } else if (this.verticalDirection === 'bottom') {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n const y = frameHeight - this.lines[i].top - this.lines[i].height;\n // if (y + height < this.top || y + height > this.bottom) {\n if (frameHeight === 0) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n } else if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n const lastLine = false;\n if (this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top]) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n }\n } else {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (frameHeight === 0) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n } else if (\n top + height < this[this.directionKey.top] ||\n top + height > this[this.directionKey.top] + frameHeight\n ) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n const lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n }\n }\n\n return {\n width: this.layoutDirection === 'vertical' ? heightBound : widthBound,\n height: this.layoutDirection === 'vertical' ? widthBound : heightBound\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphic/richtext/frame.ts"],"names":[],"mappings":"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","file":"frame.js","sourcesContent":["// import { IContext2d } from '../../IContext';\nimport type { IContext2d, IRichTextIcon } from '../../interface';\nimport type Line from './line';\nimport { DIRECTION_KEY } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 文字窗口\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/frame.js\nexport default class Frame {\n left: number;\n top: number;\n bottom: number;\n right: number;\n width: number;\n height: number;\n actualHeight: number;\n ellipsis: boolean | string;\n wordBreak: 'break-word' | 'break-all';\n verticalDirection: 'top' | 'middle' | 'bottom';\n lines: Line[];\n // ctx: IContext2d;\n globalAlign: 'left' | 'center' | 'right' | 'start' | 'end';\n globalBaseline: 'top' | 'middle' | 'bottom';\n layoutDirection: 'horizontal' | 'vertical';\n directionKey: { width: string; height: string; left: string; top: string; bottom: string };\n isWidthMax: boolean;\n isHeightMax: boolean;\n\n singleLine: boolean;\n\n icons: Map<string, IRichTextIcon>;\n\n constructor(\n left: number,\n top: number,\n width: number,\n height: number,\n ellipsis: boolean | string,\n wordBreak: 'break-word' | 'break-all',\n verticalDirection: 'top' | 'middle' | 'bottom',\n // ctx: IContext2d,\n globalAlign: 'left' | 'center' | 'right' | 'start' | 'end',\n globalBaseline: 'top' | 'middle' | 'bottom',\n layoutDirection: 'horizontal' | 'vertical',\n isWidthMax: boolean,\n isHeightMax: boolean,\n singleLine: boolean,\n icons?: Map<string, IRichTextIcon>\n ) {\n this.left = left;\n this.top = top;\n this.width = width;\n this.height = height;\n this.actualHeight = 0;\n this.bottom = top + height;\n this.right = left + width;\n this.ellipsis = ellipsis;\n this.wordBreak = wordBreak;\n this.verticalDirection = verticalDirection;\n this.lines = [];\n // this.ctx = ctx;\n this.globalAlign = globalAlign;\n this.globalBaseline = globalBaseline;\n this.layoutDirection = layoutDirection;\n this.directionKey = DIRECTION_KEY[this.layoutDirection];\n\n this.isWidthMax = isWidthMax;\n this.isHeightMax = isHeightMax;\n\n this.singleLine = singleLine;\n\n if (icons) {\n icons.clear();\n this.icons = icons;\n } else {\n this.icons = new Map();\n }\n }\n\n draw(\n ctx: IContext2d,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) {\n const { width: actualWidth, height: actualHeight } = this.getActualSize();\n const width = this.isWidthMax ? Math.min(this.width, actualWidth) : this.width || actualWidth || 0;\n let height = this.isHeightMax ? Math.min(this.height, actualHeight) : this.height || actualHeight || 0;\n // 1. height 可能受 maxHeight 影响大于 actualHeight 计算出来的实际高度\n // 2. actualHeight 是不加省略内容的高度,可能会大于 height\n // 以上两种情况都可以通过 Math.min 解决\n height = Math.min(height, actualHeight);\n /**\n * 根据 align 和 baseline 进行偏移\n */\n let deltaY = 0;\n switch (this.globalBaseline) {\n case 'top':\n deltaY = 0;\n break;\n case 'middle':\n deltaY = -height / 2;\n break;\n case 'bottom':\n deltaY = -height;\n break;\n default:\n break;\n }\n\n let deltaX = 0;\n if (this.globalAlign === 'right' || this.globalAlign === 'end') {\n deltaX = -width;\n } else if (this.globalAlign === 'center') {\n deltaX = -width / 2;\n }\n\n let frameHeight = this[this.directionKey.height];\n if (this.singleLine) {\n frameHeight = this.lines[0].height + 1;\n }\n let lastLineTag = false;\n if (this.verticalDirection === 'middle') {\n if (this.actualHeight >= frameHeight && frameHeight !== 0) {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) {\n return lastLineTag; // 不在展示范围内的line不绘制\n }\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(\n ctx,\n lastLine,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n } else {\n const detalHeight = Math.floor((frameHeight - this.actualHeight) / 2);\n if (this.layoutDirection === 'vertical') {\n deltaX += detalHeight;\n } else {\n deltaY += detalHeight;\n }\n for (let i = 0; i < this.lines.length; i++) {\n this.lines[i].draw(\n ctx,\n false,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n }\n\n // top = this.top + (this.height - this.actualHeight) / 2\n } else if (this.verticalDirection === 'bottom' && this.layoutDirection !== 'vertical') {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n const y = frameHeight - this.lines[i].top - this.lines[i].height;\n // if (y + height < this.top || y + height > this.bottom) {\n if (frameHeight === 0) {\n this.lines[i].draw(ctx, false, deltaX, y + deltaY, drawIcon);\n } else if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) {\n return lastLineTag; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top]) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(ctx, lastLine, deltaX, y + deltaY, drawIcon);\n }\n }\n } else {\n if (\n this.verticalDirection === 'bottom' &&\n this.layoutDirection === 'vertical' &&\n this.singleLine &&\n this.isWidthMax\n ) {\n deltaX += this.lines[0].height + 1;\n }\n for (let i = 0; i < this.lines.length; i++) {\n if (this.verticalDirection === 'bottom' && this.layoutDirection === 'vertical') {\n deltaX -= this.lines[i].height + this.lines[i].top;\n }\n const { top, height } = this.lines[i];\n if (frameHeight === 0) {\n this.lines[i].draw(\n ctx,\n false,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n } else if (\n top + height < this[this.directionKey.top] ||\n top + height > this[this.directionKey.top] + frameHeight\n ) {\n return lastLineTag; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n let lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n lastLine = true;\n lastLineTag = true;\n }\n this.lines[i].draw(\n ctx,\n lastLine,\n this.lines[i][this.directionKey.left] + deltaX,\n this.lines[i][this.directionKey.top] + deltaY,\n drawIcon\n );\n }\n }\n }\n\n return lastLineTag;\n }\n\n getActualSize(): { width: number; height: number } {\n if (this.ellipsis) {\n return this.getActualSizeWidthEllipsis();\n }\n\n return this.getRawActualSize();\n }\n\n getRawActualSize(): { width: number; height: number } {\n let width: number = 0;\n let height: number = 0;\n for (let i = 0; i < this.lines.length; i++) {\n const line = this.lines[i];\n if (line.actualWidth > width) {\n width = line.actualWidth;\n }\n height += line.height;\n }\n\n // return { width, height };\n return {\n width: this.layoutDirection === 'vertical' ? height : width,\n height: this.layoutDirection === 'vertical' ? width : height\n };\n }\n\n getActualSizeWidthEllipsis(): { width: number; height: number } {\n let widthBound: number = 0;\n let heightBound: number = 0;\n\n const { width: actualWidth, height: actualHeight } = this.getRawActualSize();\n const width = this.width || actualWidth || 0;\n let height = this.height || actualHeight || 0;\n // 1. height 可能受 maxHeight 影响大于 actualHeight 计算出来的实际高度\n // 2. actualHeight 是不加省略内容的高度,可能会大于 height\n // 以上两种情况都可以通过 Math.min 解决\n height = Math.min(height, actualHeight);\n /**\n * 根据 align 和 baseline 进行偏移\n */\n const deltaY = 0;\n\n let frameHeight = this[this.directionKey.height];\n if (this.singleLine) {\n frameHeight = this.lines[0].height + 1;\n }\n\n if (this.verticalDirection === 'middle') {\n if (this.actualHeight >= frameHeight && frameHeight !== 0) {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n // this.lines[i].draw(ctx, lastLine, deltaX, this.lines[i].top + deltaY);\n }\n }\n } else {\n const detalHeight = Math.floor((frameHeight - this.actualHeight) / 2);\n for (let i = 0; i < this.lines.length; i++) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n\n // top = this.top + (this.height - this.actualHeight) / 2\n } else if (this.verticalDirection === 'bottom') {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n const y = frameHeight - this.lines[i].top - this.lines[i].height;\n // if (y + height < this.top || y + height > this.bottom) {\n if (frameHeight === 0) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n } else if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n const lastLine = false;\n if (this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top]) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n }\n } else {\n for (let i = 0; i < this.lines.length; i++) {\n const { top, height } = this.lines[i];\n if (frameHeight === 0) {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n } else if (\n top + height < this[this.directionKey.top] ||\n top + height > this[this.directionKey.top] + frameHeight\n ) {\n // return; // 不在展示范围内的line不绘制\n } else {\n // 判断需要显示省略号且是展示范围内的最后一行\n const lastLine = false;\n if (\n this.ellipsis &&\n this.lines[i + 1] &&\n this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight\n ) {\n const lineWidth = this.lines[i].getWidthWithEllips();\n if (lineWidth > widthBound) {\n widthBound = lineWidth;\n }\n heightBound += this.lines[i].height;\n } else {\n if (this.lines[i].actualWidth > widthBound) {\n widthBound = this.lines[i].actualWidth;\n }\n heightBound += this.lines[i].height;\n }\n }\n }\n }\n\n return {\n width: this.layoutDirection === 'vertical' ? heightBound : widthBound,\n height: this.layoutDirection === 'vertical' ? widthBound : heightBound\n };\n }\n}\n"]}
|
|
@@ -33,18 +33,7 @@ class Line {
|
|
|
33
33
|
calcOffset(width, isWidthMax) {
|
|
34
34
|
const directionKey = this.directionKey, maxHeight = this.height;
|
|
35
35
|
let x = this.left, spacing = 0;
|
|
36
|
-
|
|
37
|
-
case "right":
|
|
38
|
-
x = width - this.actualWidth;
|
|
39
|
-
break;
|
|
40
|
-
|
|
41
|
-
case "center":
|
|
42
|
-
x = (width - this.actualWidth) / 2;
|
|
43
|
-
break;
|
|
44
|
-
|
|
45
|
-
case "justify":
|
|
46
|
-
this.paragraphs.length < 2 ? x = (width - this.actualWidth) / 2 : spacing = (width - this.actualWidth) / (this.paragraphs.length - 1);
|
|
47
|
-
}
|
|
36
|
+
this.actualWidth < width && !isWidthMax && ("right" === this.textAlign || "end" === this.textAlign ? x = width - this.actualWidth : "center" === this.textAlign ? x = (width - this.actualWidth) / 2 : "justify" === this.textAlign && (this.paragraphs.length < 2 ? x = (width - this.actualWidth) / 2 : spacing = (width - this.actualWidth) / (this.paragraphs.length - 1))),
|
|
48
37
|
this.paragraphs.map((function(paragraph) {
|
|
49
38
|
paragraph instanceof icon_1.RichTextIcon ? (paragraph["_" + directionKey.x] = x,
|
|
50
39
|
x += paragraph[directionKey.width] + spacing, paragraph["_" + directionKey.y] = "top" === paragraph.attribute.textBaseline ? 0 : "bottom" === paragraph.attribute.textBaseline ? maxHeight - paragraph.height : (maxHeight - paragraph.height) / 2) : (paragraph[directionKey.left] = x,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphic/richtext/line.ts"],"names":[],"mappings":"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","file":"line.js","sourcesContent":["// import { IContext2d } from '../../IContext';\nimport type { IContext2d, IRichTextIcon } from '../../interface';\nimport { RichTextIcon } from './icon';\nimport Paragraph from './paragraph';\nimport { DIRECTION_KEY, measureTextCanvas, regFirstSpace } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 行\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/line.js\nexport default class Line {\n left: number;\n top: number;\n width: number;\n height: number;\n baseline: number;\n ascent: number;\n descent: number;\n paragraphs: (Paragraph | RichTextIcon)[];\n actualWidth: number;\n blankWidth: number;\n textAlign: string;\n direction: 'horizontal' | 'vertical';\n directionKey: { width: string; height: string; left: string; x: string; y: string };\n\n constructor(\n left: number,\n width: number,\n baseline: number,\n ascent: number,\n descent: number,\n lineBuffer: (Paragraph | RichTextIcon)[],\n direction: 'horizontal' | 'vertical',\n isWidthMax: boolean\n ) {\n this.left = left;\n this.width = width;\n this.baseline = baseline;\n this.ascent = ascent;\n this.descent = descent;\n // this.height = ascent + descent;\n this.top = baseline - ascent;\n this.paragraphs = lineBuffer.map(p => p);\n this.textAlign =\n (this.paragraphs[0] instanceof RichTextIcon\n ? this.paragraphs[0].attribute.textAlign\n : this.paragraphs[0].character.textAlign) || 'left'; // 对齐方式选择第一个paragraph属性\n this.direction = direction;\n this.directionKey = DIRECTION_KEY[this.direction];\n\n this.actualWidth = 0;\n let maxHeight = 0;\n this.paragraphs.forEach((word, index) => {\n // 每行中第一个字符不能是空格\n if (index === 0 && word instanceof Paragraph) {\n const result = regFirstSpace.exec(word.text);\n if (result?.index !== 0) {\n word.text = word.text.slice(result?.index);\n word.updateWidth();\n }\n }\n this.actualWidth += word[this.directionKey.width];\n maxHeight = Math.max(word[this.directionKey.height], maxHeight);\n });\n this.height = maxHeight;\n\n this.blankWidth = !isWidthMax ? this.width - this.actualWidth : 0;\n\n this.calcOffset(width, isWidthMax);\n }\n\n calcOffset(width: number, isWidthMax: boolean) {\n // 处理对齐方式,计算左侧偏移距离和字符之间间距\n const directionKey = this.directionKey;\n const maxHeight = this.height;\n let x = this.left;\n let spacing = 0;\n if (this.actualWidth < width && !isWidthMax) {\n switch (this.textAlign) {\n case 'right':\n x = width - this.actualWidth;\n break;\n case 'center':\n x = (width - this.actualWidth) / 2;\n break;\n case 'justify':\n if (this.paragraphs.length < 2) {\n // 只有一个paragraph两端对齐居中显示\n x = (width - this.actualWidth) / 2;\n } else {\n spacing = (width - this.actualWidth) / (this.paragraphs.length - 1);\n }\n break;\n }\n }\n\n this.paragraphs.map(function (paragraph) {\n if (paragraph instanceof RichTextIcon) {\n // paragraph.setAttribute(directionKey.x, x);\n paragraph['_' + directionKey.x] = x;\n x += paragraph[directionKey.width] + spacing;\n // 处理纵向对齐\n paragraph['_' + directionKey.y] =\n paragraph.attribute.textBaseline === 'top'\n ? 0\n : paragraph.attribute.textBaseline === 'bottom'\n ? maxHeight - paragraph.height\n : (maxHeight - paragraph.height) / 2;\n } else {\n paragraph[directionKey.left] = x;\n x += paragraph[directionKey.width] + spacing;\n }\n });\n }\n\n draw(\n ctx: IContext2d,\n lastLine: boolean,\n x: number,\n y: number,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) {\n if (lastLine) {\n // 处理省略号\n let otherParagraphWidth = 0;\n for (let i = this.paragraphs.length - 1; i >= 0; i--) {\n const paragraph = this.paragraphs[i];\n if (paragraph instanceof RichTextIcon) {\n break; // todo: 处理最后为图标,显示省略号的情况\n }\n if (this.direction === 'vertical' && paragraph.direction !== 'vertical') {\n paragraph.verticalEllipsis = true;\n break;\n }\n // const { width } = measureText('...', paragraph.style);\n const { width } = measureTextCanvas('...', paragraph.character);\n const ellipsisWidth = width || 0;\n if (ellipsisWidth <= this.blankWidth + otherParagraphWidth) {\n // 省略号可以直接接在后面paragraph\n paragraph.ellipsis = 'add';\n\n break;\n } else if (ellipsisWidth <= this.blankWidth + otherParagraphWidth + paragraph.width) {\n // 省略号需要替换paragraph中的字符\n paragraph.ellipsis = 'replace';\n paragraph.ellipsisWidth = ellipsisWidth;\n paragraph.ellipsisOtherParagraphWidth = this.blankWidth + otherParagraphWidth;\n\n break;\n } else {\n // 省略号需要的width大于paragraph的width,隐藏paragraph,向前搜索\n paragraph.ellipsis = 'hide';\n otherParagraphWidth += paragraph.width;\n }\n }\n }\n\n // 正常绘制\n this.paragraphs.map((paragraph, index) => {\n if (paragraph instanceof RichTextIcon) {\n // 更新icon位置\n paragraph.setAttributes({\n x: x + paragraph._x,\n y: y + paragraph._y\n });\n\n // 绘制icon\n drawIcon(paragraph, ctx, x + paragraph._x, y + paragraph._y, this.ascent);\n return;\n }\n paragraph.draw(ctx, y + this.ascent, x, index === 0, this.textAlign);\n });\n }\n\n getWidthWithEllips() {\n // 处理省略号\n let otherParagraphWidth = 0;\n for (let i = this.paragraphs.length - 1; i >= 0; i--) {\n const paragraph = this.paragraphs[i];\n if (paragraph instanceof RichTextIcon) {\n break; // todo: 处理最后为图标,显示省略号的情况\n }\n\n const { width } = measureTextCanvas('...', paragraph.character);\n const ellipsisWidth = width || 0;\n if (ellipsisWidth <= this.blankWidth + otherParagraphWidth) {\n // 省略号可以直接接在后面paragraph\n paragraph.ellipsis = 'add';\n paragraph.ellipsisWidth = ellipsisWidth;\n break;\n } else if (ellipsisWidth <= this.blankWidth + otherParagraphWidth + paragraph.width) {\n // 省略号需要替换paragraph中的字符\n paragraph.ellipsis = 'replace';\n paragraph.ellipsisWidth = ellipsisWidth;\n paragraph.ellipsisOtherParagraphWidth = this.blankWidth + otherParagraphWidth;\n\n break;\n } else {\n // 省略号需要的width大于paragraph的width,隐藏paragraph,向前搜索\n paragraph.ellipsis = 'hide';\n otherParagraphWidth += paragraph.width;\n }\n }\n\n let width = 0;\n // 正常绘制\n this.paragraphs.map((paragraph, index) => {\n if (paragraph instanceof RichTextIcon) {\n width += paragraph.width; // todo: 处理direction\n } else {\n width += paragraph.getWidthWithEllips(this.direction);\n }\n });\n\n return width;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphic/richtext/line.ts"],"names":[],"mappings":"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","file":"line.js","sourcesContent":["// import { IContext2d } from '../../IContext';\nimport type { IContext2d, IRichTextIcon } from '../../interface';\nimport { RichTextIcon } from './icon';\nimport Paragraph from './paragraph';\nimport { DIRECTION_KEY, measureTextCanvas, regFirstSpace } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 行\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/line.js\nexport default class Line {\n left: number;\n top: number;\n width: number;\n height: number;\n baseline: number;\n ascent: number;\n descent: number;\n paragraphs: (Paragraph | RichTextIcon)[];\n actualWidth: number;\n blankWidth: number;\n textAlign: string;\n direction: 'horizontal' | 'vertical';\n directionKey: { width: string; height: string; left: string; x: string; y: string };\n\n constructor(\n left: number,\n width: number,\n baseline: number,\n ascent: number,\n descent: number,\n lineBuffer: (Paragraph | RichTextIcon)[],\n direction: 'horizontal' | 'vertical',\n isWidthMax: boolean\n ) {\n this.left = left;\n this.width = width;\n this.baseline = baseline;\n this.ascent = ascent;\n this.descent = descent;\n // this.height = ascent + descent;\n this.top = baseline - ascent;\n this.paragraphs = lineBuffer.map(p => p);\n this.textAlign =\n (this.paragraphs[0] instanceof RichTextIcon\n ? this.paragraphs[0].attribute.textAlign\n : this.paragraphs[0].character.textAlign) || 'left'; // 对齐方式选择第一个paragraph属性\n this.direction = direction;\n this.directionKey = DIRECTION_KEY[this.direction];\n\n this.actualWidth = 0;\n let maxHeight = 0;\n this.paragraphs.forEach((word, index) => {\n // 每行中第一个字符不能是空格\n if (index === 0 && word instanceof Paragraph) {\n const result = regFirstSpace.exec(word.text);\n if (result?.index !== 0) {\n word.text = word.text.slice(result?.index);\n word.updateWidth();\n }\n }\n this.actualWidth += word[this.directionKey.width];\n maxHeight = Math.max(word[this.directionKey.height], maxHeight);\n });\n this.height = maxHeight;\n\n this.blankWidth = !isWidthMax ? this.width - this.actualWidth : 0;\n\n this.calcOffset(width, isWidthMax);\n }\n\n calcOffset(width: number, isWidthMax: boolean) {\n // 处理对齐方式,计算左侧偏移距离和字符之间间距\n const directionKey = this.directionKey;\n const maxHeight = this.height;\n let x = this.left;\n let spacing = 0;\n if (this.actualWidth < width && !isWidthMax) {\n if (this.textAlign === 'right' || this.textAlign === 'end') {\n x = width - this.actualWidth;\n } else if (this.textAlign === 'center') {\n x = (width - this.actualWidth) / 2;\n } else if (this.textAlign === 'justify') {\n if (this.paragraphs.length < 2) {\n // 只有一个paragraph两端对齐居中显示\n x = (width - this.actualWidth) / 2;\n } else {\n spacing = (width - this.actualWidth) / (this.paragraphs.length - 1);\n }\n }\n }\n\n this.paragraphs.map(function (paragraph) {\n if (paragraph instanceof RichTextIcon) {\n // paragraph.setAttribute(directionKey.x, x);\n paragraph['_' + directionKey.x] = x;\n x += paragraph[directionKey.width] + spacing;\n // 处理纵向对齐\n paragraph['_' + directionKey.y] =\n paragraph.attribute.textBaseline === 'top'\n ? 0\n : paragraph.attribute.textBaseline === 'bottom'\n ? maxHeight - paragraph.height\n : (maxHeight - paragraph.height) / 2;\n } else {\n paragraph[directionKey.left] = x;\n x += paragraph[directionKey.width] + spacing;\n }\n });\n }\n\n draw(\n ctx: IContext2d,\n lastLine: boolean,\n x: number,\n y: number,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) {\n if (lastLine) {\n // 处理省略号\n let otherParagraphWidth = 0;\n for (let i = this.paragraphs.length - 1; i >= 0; i--) {\n const paragraph = this.paragraphs[i];\n if (paragraph instanceof RichTextIcon) {\n break; // todo: 处理最后为图标,显示省略号的情况\n }\n if (this.direction === 'vertical' && paragraph.direction !== 'vertical') {\n paragraph.verticalEllipsis = true;\n break;\n }\n // const { width } = measureText('...', paragraph.style);\n const { width } = measureTextCanvas('...', paragraph.character);\n const ellipsisWidth = width || 0;\n if (ellipsisWidth <= this.blankWidth + otherParagraphWidth) {\n // 省略号可以直接接在后面paragraph\n paragraph.ellipsis = 'add';\n\n break;\n } else if (ellipsisWidth <= this.blankWidth + otherParagraphWidth + paragraph.width) {\n // 省略号需要替换paragraph中的字符\n paragraph.ellipsis = 'replace';\n paragraph.ellipsisWidth = ellipsisWidth;\n paragraph.ellipsisOtherParagraphWidth = this.blankWidth + otherParagraphWidth;\n\n break;\n } else {\n // 省略号需要的width大于paragraph的width,隐藏paragraph,向前搜索\n paragraph.ellipsis = 'hide';\n otherParagraphWidth += paragraph.width;\n }\n }\n }\n\n // 正常绘制\n this.paragraphs.map((paragraph, index) => {\n if (paragraph instanceof RichTextIcon) {\n // 更新icon位置\n paragraph.setAttributes({\n x: x + paragraph._x,\n y: y + paragraph._y\n });\n\n // 绘制icon\n drawIcon(paragraph, ctx, x + paragraph._x, y + paragraph._y, this.ascent);\n return;\n }\n paragraph.draw(ctx, y + this.ascent, x, index === 0, this.textAlign);\n });\n }\n\n getWidthWithEllips() {\n // 处理省略号\n let otherParagraphWidth = 0;\n for (let i = this.paragraphs.length - 1; i >= 0; i--) {\n const paragraph = this.paragraphs[i];\n if (paragraph instanceof RichTextIcon) {\n break; // todo: 处理最后为图标,显示省略号的情况\n }\n\n const { width } = measureTextCanvas('...', paragraph.character);\n const ellipsisWidth = width || 0;\n if (ellipsisWidth <= this.blankWidth + otherParagraphWidth) {\n // 省略号可以直接接在后面paragraph\n paragraph.ellipsis = 'add';\n paragraph.ellipsisWidth = ellipsisWidth;\n break;\n } else if (ellipsisWidth <= this.blankWidth + otherParagraphWidth + paragraph.width) {\n // 省略号需要替换paragraph中的字符\n paragraph.ellipsis = 'replace';\n paragraph.ellipsisWidth = ellipsisWidth;\n paragraph.ellipsisOtherParagraphWidth = this.blankWidth + otherParagraphWidth;\n\n break;\n } else {\n // 省略号需要的width大于paragraph的width,隐藏paragraph,向前搜索\n paragraph.ellipsis = 'hide';\n otherParagraphWidth += paragraph.width;\n }\n }\n\n let width = 0;\n // 正常绘制\n this.paragraphs.map((paragraph, index) => {\n if (paragraph instanceof RichTextIcon) {\n width += paragraph.width; // todo: 处理direction\n } else {\n width += paragraph.getWidthWithEllips(this.direction);\n }\n });\n\n return width;\n }\n}\n"]}
|
|
@@ -36,9 +36,9 @@ class Paragraph {
|
|
|
36
36
|
let direction = this.direction;
|
|
37
37
|
if (this.verticalEllipsis) text = "...", direction = "vertical", baseline -= this.ellipsisWidth / 2; else {
|
|
38
38
|
if ("hide" === this.ellipsis) return;
|
|
39
|
-
if ("add" === this.ellipsis) text += "...", "right"
|
|
39
|
+
if ("add" === this.ellipsis) text += "...", "right" !== textAlign && "end" !== textAlign || (left -= this.ellipsisWidth); else if ("replace" === this.ellipsis) {
|
|
40
40
|
const index = (0, utils_2.getStrByWithCanvas)(text, ("vertical" === direction ? this.height : this.width) - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.character, text.length - 1);
|
|
41
|
-
if (text = text.slice(0, index), text += "...", "right" === textAlign) {
|
|
41
|
+
if (text = text.slice(0, index), text += "...", "right" === textAlign || "end" === textAlign) {
|
|
42
42
|
const {width: width} = (0, utils_2.measureTextCanvas)(this.text.slice(index), this.character);
|
|
43
43
|
"vertical" === direction || (left -= this.ellipsisWidth - width);
|
|
44
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphic/richtext/paragraph.ts"],"names":[],"mappings":"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","file":"paragraph.js","sourcesContent":["import { calculateLineHeight } from '../../common/utils';\nimport type { IContext2d, IRichTextParagraphCharacter } from '../../interface';\nimport { measureTextCanvas, applyFillStyle, applyStrokeStyle, getStrByWithCanvas } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 文字段\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/text.js\nexport default class Paragraph {\n text: string;\n ascent: number;\n descent: number;\n width: number;\n height: number;\n lineHeight: number;\n fontSize: number;\n length: number;\n newLine: boolean;\n character: IRichTextParagraphCharacter;\n left: number;\n top: number;\n // rotate?: number;\n direction?: 'horizontal' | 'vertical';\n // bounds?: Bounds;\n widthOrigin?: number;\n heightOrigin?: number;\n textBaseline?: CanvasTextBaseline;\n\n ellipsis: 'normal' | 'add' | 'replace' | 'hide';\n ellipsisWidth: number;\n ellipsisOtherParagraphWidth: number;\n verticalEllipsis?: boolean;\n\n constructor(text: string, newLine: boolean, character: IRichTextParagraphCharacter) {\n // 测量文字\n this.fontSize = character.fontSize || 16;\n this.textBaseline = character.textBaseline || 'alphabetic';\n\n // 处理行高:\n // lineHeight为数字时,大于fontSize取lineHeight,小于fontSize时取fontSize\n // lineHeight不为数字时,统一认为lineHeight为'normal',值取1.2 * fontSize\n const lineHeight = calculateLineHeight(character.lineHeight, this.fontSize);\n if (typeof lineHeight === 'number') {\n this.lineHeight = lineHeight > this.fontSize ? lineHeight : this.fontSize;\n } else {\n this.lineHeight = Math.floor(1.2 * this.fontSize);\n }\n\n this.height = this.lineHeight;\n\n const { ascent, height, descent, width } = measureTextCanvas(text, character);\n\n let halfDetaHeight = 0;\n let deltaAscent = 0;\n let deltaDescent = 0;\n if (this.height > height) {\n // measureTextCanvas测量出的是纯文字高度,this.height是考虑行高后的高度\n // 如果this.height > height,将超过的高度平均分配到ascent和descent上\n halfDetaHeight = (this.height - height) / 2;\n deltaAscent = Math.ceil(halfDetaHeight);\n deltaDescent = Math.floor(halfDetaHeight);\n }\n\n if (this.textBaseline === 'top') {\n this.ascent = halfDetaHeight;\n this.descent = height - halfDetaHeight;\n } else if (this.textBaseline === 'bottom') {\n this.ascent = height - halfDetaHeight;\n this.descent = halfDetaHeight;\n } else if (this.textBaseline === 'middle') {\n this.ascent = this.height / 2;\n this.descent = this.height / 2;\n } else {\n this.ascent = ascent + deltaAscent;\n this.descent = descent + deltaDescent;\n }\n\n this.length = text.length;\n this.width = width || 0;\n this.text = text || '';\n this.newLine = newLine || false;\n this.character = character;\n\n this.left = 0;\n this.top = 0;\n\n this.ellipsis = 'normal';\n this.ellipsisWidth = 0;\n this.ellipsisOtherParagraphWidth = 0;\n\n // 处理旋转\n if (character.direction === 'vertical') {\n this.direction = character.direction;\n this.widthOrigin = this.width;\n this.heightOrigin = this.height;\n // const bounds = new Bounds();\n // bounds.set(0, 0, this.width, this.height);\n // bounds.rotate(Math.PI / 2, this.width / 2, this.height / 2);\n // this.bounds = bounds;\n // this.width = bounds.width();\n // this.height = bounds.height();\n this.width = this.heightOrigin;\n this.height = this.widthOrigin;\n this.lineHeight = this.height;\n }\n }\n\n updateWidth() {\n const { width } = measureTextCanvas(this.text, this.character);\n this.width = width;\n if (this.direction === 'vertical') {\n this.widthOrigin = this.width;\n this.width = this.heightOrigin;\n this.height = this.widthOrigin;\n }\n }\n\n draw(ctx: IContext2d, baseline: number, deltaLeft: number, isLineFirst: boolean, textAlign: string) {\n let text = this.text;\n let left = this.left + deltaLeft;\n baseline += this.top;\n let direction = this.direction;\n\n if (this.verticalEllipsis) {\n text = '...';\n direction = 'vertical';\n baseline -= this.ellipsisWidth / 2;\n } else if (this.ellipsis === 'hide') {\n return;\n } else if (this.ellipsis === 'add') {\n text += '...';\n\n if (textAlign === 'right') {\n left -= this.ellipsisWidth;\n }\n } else if (this.ellipsis === 'replace') {\n // 找到需要截断的字符长度\n // const index = getStrByWith(text, this.width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.style, text.length - 1);\n const index = getStrByWithCanvas(\n text,\n (direction === 'vertical' ? this.height : this.width) - this.ellipsisWidth + this.ellipsisOtherParagraphWidth,\n this.character,\n text.length - 1\n );\n text = text.slice(0, index);\n text += '...';\n\n if (textAlign === 'right') {\n const { width } = measureTextCanvas(this.text.slice(index), this.character);\n if (direction === 'vertical') {\n // baseline -= this.ellipsisWidth - width;\n } else {\n left -= this.ellipsisWidth - width;\n }\n }\n }\n\n // prepareContext(ctx);\n switch (this.character.script) {\n case 'super':\n baseline -= this.ascent * (1 / 3);\n break;\n case 'sub':\n baseline += this.descent / 2;\n break;\n }\n\n // if (isLineFirst) {\n // const result = regFirstSpace.exec(text);\n // if (result?.index !== 0) {\n // text = text.slice(result?.index);\n // }\n // }\n\n // 处理旋转\n if (direction === 'vertical') {\n ctx.save();\n ctx.rotateAbout(Math.PI / 2, left, baseline);\n ctx.translate(-(this.heightOrigin as number) || -this.lineHeight / 2, -this.descent / 2);\n ctx.translate(left, baseline);\n left = 0;\n baseline = 0;\n }\n\n if (this.character.stroke) {\n applyStrokeStyle(ctx, this.character);\n ctx.strokeText(text, left, baseline);\n }\n\n // 下面绘制underline和line-through时需要设置FillStyle\n applyFillStyle(ctx, this.character);\n\n if (this.character.fill) {\n ctx.fillText(text, left, baseline);\n }\n\n if (this.character.fill) {\n if (typeof this.character.lineThrough === 'boolean' || typeof this.character.underline === 'boolean') {\n if (this.character.underline) {\n ctx.fillRect(\n left,\n 1 + baseline,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n if (this.character.lineThrough) {\n ctx.fillRect(\n left,\n 1 + baseline - this.ascent / 2,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n } else if (this.character.textDecoration === 'underline') {\n ctx.fillRect(\n left,\n 1 + baseline,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n } else if (this.character.textDecoration === 'line-through') {\n ctx.fillRect(\n left,\n 1 + baseline - this.ascent / 2,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n }\n\n if (direction === 'vertical') {\n ctx.restore();\n }\n }\n\n getWidthWithEllips(direction: string): number {\n let text = this.text;\n // const direction = this.direction;\n const width = direction === 'vertical' ? this.height : this.width;\n // const height = direction === 'vertical' ? this.width: this.height;\n\n if (this.ellipsis === 'hide') {\n return width;\n } else if (this.ellipsis === 'add') {\n return width + this.ellipsisWidth;\n } else if (this.ellipsis === 'replace') {\n // 找到需要截断的字符长度\n // const index = getStrByWith(text, width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.style, text.length - 1);\n const index = getStrByWithCanvas(\n text,\n width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth,\n this.character,\n text.length - 1\n );\n text = text.slice(0, index);\n text += '...';\n\n const { width: measureWidth } = measureTextCanvas(this.text.slice(index), this.character);\n return width + this.ellipsisWidth - measureWidth;\n }\n return width;\n }\n}\n\nexport function seperateParagraph(paragraph: Paragraph, index: number) {\n const text1 = paragraph.text.slice(0, index);\n const text2 = paragraph.text.slice(index);\n const p1 = new Paragraph(text1, paragraph.newLine, paragraph.character);\n const p2 = new Paragraph(text2, true, paragraph.character);\n\n return [p1, p2];\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphic/richtext/paragraph.ts"],"names":[],"mappings":"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","file":"paragraph.js","sourcesContent":["import { calculateLineHeight } from '../../common/utils';\nimport type { IContext2d, IRichTextParagraphCharacter } from '../../interface';\nimport { measureTextCanvas, applyFillStyle, applyStrokeStyle, getStrByWithCanvas } from './utils';\n\n/**\n * 部分代码参考 https://github.com/danielearwicker/carota/\n * The MIT License (MIT)\n\n \"Carota\" - Copyright (c) 2013 Daniel Earwicker\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n// 文字段\n// 参考carota\n// https://github.com/danielearwicker/carota/blob/master/src/text.js\nexport default class Paragraph {\n text: string;\n ascent: number;\n descent: number;\n width: number;\n height: number;\n lineHeight: number;\n fontSize: number;\n length: number;\n newLine: boolean;\n character: IRichTextParagraphCharacter;\n left: number;\n top: number;\n // rotate?: number;\n direction?: 'horizontal' | 'vertical';\n // bounds?: Bounds;\n widthOrigin?: number;\n heightOrigin?: number;\n textBaseline?: CanvasTextBaseline;\n\n ellipsis: 'normal' | 'add' | 'replace' | 'hide';\n ellipsisWidth: number;\n ellipsisOtherParagraphWidth: number;\n verticalEllipsis?: boolean;\n\n constructor(text: string, newLine: boolean, character: IRichTextParagraphCharacter) {\n // 测量文字\n this.fontSize = character.fontSize || 16;\n this.textBaseline = character.textBaseline || 'alphabetic';\n\n // 处理行高:\n // lineHeight为数字时,大于fontSize取lineHeight,小于fontSize时取fontSize\n // lineHeight不为数字时,统一认为lineHeight为'normal',值取1.2 * fontSize\n const lineHeight = calculateLineHeight(character.lineHeight, this.fontSize);\n if (typeof lineHeight === 'number') {\n this.lineHeight = lineHeight > this.fontSize ? lineHeight : this.fontSize;\n } else {\n this.lineHeight = Math.floor(1.2 * this.fontSize);\n }\n\n this.height = this.lineHeight;\n\n const { ascent, height, descent, width } = measureTextCanvas(text, character);\n\n let halfDetaHeight = 0;\n let deltaAscent = 0;\n let deltaDescent = 0;\n if (this.height > height) {\n // measureTextCanvas测量出的是纯文字高度,this.height是考虑行高后的高度\n // 如果this.height > height,将超过的高度平均分配到ascent和descent上\n halfDetaHeight = (this.height - height) / 2;\n deltaAscent = Math.ceil(halfDetaHeight);\n deltaDescent = Math.floor(halfDetaHeight);\n }\n\n if (this.textBaseline === 'top') {\n this.ascent = halfDetaHeight;\n this.descent = height - halfDetaHeight;\n } else if (this.textBaseline === 'bottom') {\n this.ascent = height - halfDetaHeight;\n this.descent = halfDetaHeight;\n } else if (this.textBaseline === 'middle') {\n this.ascent = this.height / 2;\n this.descent = this.height / 2;\n } else {\n this.ascent = ascent + deltaAscent;\n this.descent = descent + deltaDescent;\n }\n\n this.length = text.length;\n this.width = width || 0;\n this.text = text || '';\n this.newLine = newLine || false;\n this.character = character;\n\n this.left = 0;\n this.top = 0;\n\n this.ellipsis = 'normal';\n this.ellipsisWidth = 0;\n this.ellipsisOtherParagraphWidth = 0;\n\n // 处理旋转\n if (character.direction === 'vertical') {\n this.direction = character.direction;\n this.widthOrigin = this.width;\n this.heightOrigin = this.height;\n // const bounds = new Bounds();\n // bounds.set(0, 0, this.width, this.height);\n // bounds.rotate(Math.PI / 2, this.width / 2, this.height / 2);\n // this.bounds = bounds;\n // this.width = bounds.width();\n // this.height = bounds.height();\n this.width = this.heightOrigin;\n this.height = this.widthOrigin;\n this.lineHeight = this.height;\n }\n }\n\n updateWidth() {\n const { width } = measureTextCanvas(this.text, this.character);\n this.width = width;\n if (this.direction === 'vertical') {\n this.widthOrigin = this.width;\n this.width = this.heightOrigin;\n this.height = this.widthOrigin;\n }\n }\n\n draw(ctx: IContext2d, baseline: number, deltaLeft: number, isLineFirst: boolean, textAlign: string) {\n let text = this.text;\n let left = this.left + deltaLeft;\n baseline += this.top;\n let direction = this.direction;\n\n if (this.verticalEllipsis) {\n text = '...';\n direction = 'vertical';\n baseline -= this.ellipsisWidth / 2;\n } else if (this.ellipsis === 'hide') {\n return;\n } else if (this.ellipsis === 'add') {\n text += '...';\n\n if (textAlign === 'right' || textAlign === 'end') {\n left -= this.ellipsisWidth;\n }\n } else if (this.ellipsis === 'replace') {\n // 找到需要截断的字符长度\n // const index = getStrByWith(text, this.width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.style, text.length - 1);\n const index = getStrByWithCanvas(\n text,\n (direction === 'vertical' ? this.height : this.width) - this.ellipsisWidth + this.ellipsisOtherParagraphWidth,\n this.character,\n text.length - 1\n );\n text = text.slice(0, index);\n text += '...';\n\n if (textAlign === 'right' || textAlign === 'end') {\n const { width } = measureTextCanvas(this.text.slice(index), this.character);\n if (direction === 'vertical') {\n // baseline -= this.ellipsisWidth - width;\n } else {\n left -= this.ellipsisWidth - width;\n }\n }\n }\n\n // prepareContext(ctx);\n switch (this.character.script) {\n case 'super':\n baseline -= this.ascent * (1 / 3);\n break;\n case 'sub':\n baseline += this.descent / 2;\n break;\n }\n\n // if (isLineFirst) {\n // const result = regFirstSpace.exec(text);\n // if (result?.index !== 0) {\n // text = text.slice(result?.index);\n // }\n // }\n\n // 处理旋转\n if (direction === 'vertical') {\n ctx.save();\n ctx.rotateAbout(Math.PI / 2, left, baseline);\n ctx.translate(-(this.heightOrigin as number) || -this.lineHeight / 2, -this.descent / 2);\n ctx.translate(left, baseline);\n left = 0;\n baseline = 0;\n }\n\n if (this.character.stroke) {\n applyStrokeStyle(ctx, this.character);\n ctx.strokeText(text, left, baseline);\n }\n\n // 下面绘制underline和line-through时需要设置FillStyle\n applyFillStyle(ctx, this.character);\n\n if (this.character.fill) {\n ctx.fillText(text, left, baseline);\n }\n\n if (this.character.fill) {\n if (typeof this.character.lineThrough === 'boolean' || typeof this.character.underline === 'boolean') {\n if (this.character.underline) {\n ctx.fillRect(\n left,\n 1 + baseline,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n if (this.character.lineThrough) {\n ctx.fillRect(\n left,\n 1 + baseline - this.ascent / 2,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n } else if (this.character.textDecoration === 'underline') {\n ctx.fillRect(\n left,\n 1 + baseline,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n } else if (this.character.textDecoration === 'line-through') {\n ctx.fillRect(\n left,\n 1 + baseline - this.ascent / 2,\n this.widthOrigin || this.width,\n this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1\n );\n }\n }\n\n if (direction === 'vertical') {\n ctx.restore();\n }\n }\n\n getWidthWithEllips(direction: string): number {\n let text = this.text;\n // const direction = this.direction;\n const width = direction === 'vertical' ? this.height : this.width;\n // const height = direction === 'vertical' ? this.width: this.height;\n\n if (this.ellipsis === 'hide') {\n return width;\n } else if (this.ellipsis === 'add') {\n return width + this.ellipsisWidth;\n } else if (this.ellipsis === 'replace') {\n // 找到需要截断的字符长度\n // const index = getStrByWith(text, width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.style, text.length - 1);\n const index = getStrByWithCanvas(\n text,\n width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth,\n this.character,\n text.length - 1\n );\n text = text.slice(0, index);\n text += '...';\n\n const { width: measureWidth } = measureTextCanvas(this.text.slice(index), this.character);\n return width + this.ellipsisWidth - measureWidth;\n }\n return width;\n }\n}\n\nexport function seperateParagraph(paragraph: Paragraph, index: number) {\n const text1 = paragraph.text.slice(0, index);\n const text2 = paragraph.text.slice(index);\n const p1 = new Paragraph(text1, paragraph.newLine, paragraph.character);\n const p2 = new Paragraph(text2, true, paragraph.character);\n\n return [p1, p2];\n}\n"]}
|
|
@@ -137,7 +137,7 @@ export interface IRichTextFrame {
|
|
|
137
137
|
wordBreak: 'break-word' | 'break-all';
|
|
138
138
|
verticalDirection: 'top' | 'middle' | 'bottom';
|
|
139
139
|
lines: IRichTextLine[];
|
|
140
|
-
globalAlign: 'left' | 'center' | 'right';
|
|
140
|
+
globalAlign: 'left' | 'center' | 'right' | 'start' | 'end';
|
|
141
141
|
globalBaseline: 'top' | 'middle' | 'bottom';
|
|
142
142
|
layoutDirection: 'horizontal' | 'vertical';
|
|
143
143
|
directionKey: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/graphic/richText.ts"],"names":[],"mappings":"","file":"richText.js","sourcesContent":["import type { IColor } from '../color';\nimport type { IContext2d } from '../context';\nimport type { IGraphicAttribute, IGraphic } from '../graphic';\nimport type { IImage, IImageGraphicAttribute } from './image';\n\nexport type IRichTextAttribute = {\n width: number;\n height: number;\n ellipsis: boolean | string;\n wordBreak: RichTextWordBreak;\n verticalDirection: RichTextVerticalDirection;\n maxHeight: number;\n maxWidth: number;\n textAlign: RichTextGlobalAlignType;\n textBaseline: RichTextGlobalBaselineType;\n layoutDirection: RichTextLayoutDirectionType;\n textConfig: IRichTextCharacter[];\n singleLine: boolean;\n};\n\nexport type IRichTextGraphicAttribute = Partial<IGraphicAttribute> & Partial<IRichTextAttribute>;\n\nexport type RichTextWordBreak = 'break-word' | 'break-all';\nexport type RichTextVerticalDirection = 'top' | 'middle' | 'bottom';\nexport type RichTextGlobalAlignType = 'left' | 'right' | 'center';\nexport type RichTextGlobalBaselineType = 'top' | 'middle' | 'bottom';\nexport type RichTextLayoutDirectionType = 'horizontal' | 'vertical';\nexport type RichTextFontStyle = 'normal' | 'italic' | 'oblique';\nexport type RichTextTextDecoration = 'none' | 'underline' | 'line-through';\n// export type RichTextTextAlign = 'left' | 'right' | 'center';\nexport type RichTextScript = 'normal' | 'sub' | 'super';\n\nexport type IRichTextBasicCharacter = {\n lineHeight?: number | string;\n textAlign?: CanvasTextAlign; // left, right, center\n textBaseline?: CanvasTextBaseline;\n direction?: RichTextLayoutDirectionType;\n};\n\nexport type IRichTextParagraphCharacter = IRichTextBasicCharacter & {\n text: string | number;\n fontSize?: number;\n fontFamily?: string;\n fill?: IColor | boolean;\n stroke?: IColor | boolean;\n fontWeight?: string;\n // lineHeight?: number;\n fontStyle?: RichTextFontStyle; // normal, italic, oblique\n textDecoration?: RichTextTextDecoration; // none, underline, line-through\n // textAlign?: RichTextTextAlign; // left, right, center\n script?: RichTextScript; // normal, sub, super\n underline?: boolean;\n lineThrough?: boolean;\n // direction?: RichTextLayoutDirectionType;\n};\n\nexport type IRichTextImageCharacter = IRichTextBasicCharacter & {\n // 图片基础属性\n image: string | HTMLImageElement | HTMLCanvasElement;\n width: number;\n height: number;\n\n // hover相关属性\n // backgroundShow?: boolean; // 是否显示background\n backgroundShowMode?: 'always' | 'hover';\n backgroundFill?: boolean | IColor; // 背景矩形填充颜色\n backgroundFillOpacity?: number; // 背景矩形填充透明度\n backgroundStroke?: boolean | IColor; // 背景矩形边框颜色\n backgroundStrokeOpacity?: number; // 背景矩形边框透明度\n backgroundRadius?: number; // 背景矩形圆角\n // background size 同时控制了该icon的响应范围\n backgroundWidth?: number;\n backgroundHeight?: number;\n\n // 唯一标识符\n id?: string;\n\n // lineHeight?: number;\n // textAlign?: RichTextTextAlign; // left, right, center\n // direction?: RichTextLayoutDirectionType;\n margin?: number | number[];\n\n funcType?: string;\n hoverImage?: string | HTMLImageElement | HTMLCanvasElement;\n};\n\nexport type IRichTextCharacter = IRichTextParagraphCharacter | IRichTextImageCharacter;\n\nexport type IRichTextIconGraphicAttribute = IImageGraphicAttribute & {\n id?: string;\n backgroundShowMode?: 'always' | 'hover' | 'never';\n backgroundFill?: boolean | IColor; // 背景矩形填充颜色\n backgroundFillOpacity?: number; // 背景矩形填充透明度\n backgroundStroke?: boolean | IColor; // 背景矩形边框颜色\n backgroundStrokeOpacity?: number; // 背景矩形边框透明度\n backgroundRadius?: number; // 背景矩形圆角\n backgroundWidth?: number;\n backgroundHeight?: number;\n\n // lineHeight?: number;\n textAlign?: CanvasTextAlign; // left, right, center\n textBaseline?: CanvasTextBaseline;\n direction?: RichTextLayoutDirectionType;\n\n margin?: number | number[];\n\n // backgroundShow?: boolean;\n};\n\nexport interface IRichTextParagraph {\n text: string;\n ascent: number;\n descent: number;\n width: number;\n height: number;\n lineHeight: number;\n fontSize: number;\n length: number;\n newLine: boolean;\n character: IRichTextParagraphCharacter;\n left: number;\n top: number;\n direction?: 'horizontal' | 'vertical';\n widthOrigin?: number;\n heightOrigin?: number;\n textBaseline?: CanvasTextBaseline;\n ellipsis: 'normal' | 'add' | 'replace' | 'hide';\n ellipsisWidth: number;\n ellipsisOtherParagraphWidth: number;\n verticalEllipsis?: boolean;\n updateWidth: () => void;\n draw: (ctx: IContext2d, baseline: number, deltaLeft: number, isLineFirst: boolean, textAlign: string) => void;\n getWidthWithEllips: (direction: string) => number;\n}\n\nexport interface IRichTextLine {\n left: number;\n top: number;\n width: number;\n height: number;\n baseline: number;\n ascent: number;\n descent: number;\n paragraphs: (IRichTextParagraph | IRichTextIcon)[];\n actualWidth: number;\n blankWidth: number;\n textAlign: string;\n direction: 'horizontal' | 'vertical';\n directionKey: {\n width: string;\n height: string;\n left: string;\n x: string;\n y: string;\n };\n draw: (\n ctx: IContext2d,\n lastLine: boolean,\n x: number,\n y: number,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) => void;\n getWidthWithEllips: () => number;\n}\n\nexport interface IRichTextFrame {\n left: number;\n top: number;\n bottom: number;\n right: number;\n width: number;\n height: number;\n actualHeight: number;\n ellipsis: boolean | string;\n wordBreak: 'break-word' | 'break-all';\n verticalDirection: 'top' | 'middle' | 'bottom';\n lines: IRichTextLine[];\n globalAlign: 'left' | 'center' | 'right';\n globalBaseline: 'top' | 'middle' | 'bottom';\n layoutDirection: 'horizontal' | 'vertical';\n directionKey: {\n width: string;\n height: string;\n left: string;\n top: string;\n bottom: string;\n };\n isWidthMax: boolean;\n isHeightMax: boolean;\n singleLine: boolean;\n icons: Map<string, IRichTextIcon>;\n draw: (\n ctx: IContext2d,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) => boolean;\n getActualSize: () => {\n width: number;\n height: number;\n };\n getRawActualSize: () => {\n width: number;\n height: number;\n };\n getActualSizeWidthEllipsis: () => {\n width: number;\n height: number;\n };\n}\n\nexport interface IRichText extends IGraphic<IRichTextGraphicAttribute> {\n getFrameCache: () => IRichTextFrame;\n}\n\nexport interface IRichTextIcon extends IImage {\n attribute: IRichTextIconGraphicAttribute;\n richtextId?: string;\n globalX?: number;\n globalY?: number;\n\n _x: number;\n _y: number;\n _hovered: boolean;\n _marginArray: [number, number, number, number];\n\n setHoverState: (hovered: boolean) => void;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/graphic/richText.ts"],"names":[],"mappings":"","file":"richText.js","sourcesContent":["import type { IColor } from '../color';\nimport type { IContext2d } from '../context';\nimport type { IGraphicAttribute, IGraphic } from '../graphic';\nimport type { IImage, IImageGraphicAttribute } from './image';\n\nexport type IRichTextAttribute = {\n width: number;\n height: number;\n ellipsis: boolean | string;\n wordBreak: RichTextWordBreak;\n verticalDirection: RichTextVerticalDirection;\n maxHeight: number;\n maxWidth: number;\n textAlign: RichTextGlobalAlignType;\n textBaseline: RichTextGlobalBaselineType;\n layoutDirection: RichTextLayoutDirectionType;\n textConfig: IRichTextCharacter[];\n singleLine: boolean;\n};\n\nexport type IRichTextGraphicAttribute = Partial<IGraphicAttribute> & Partial<IRichTextAttribute>;\n\nexport type RichTextWordBreak = 'break-word' | 'break-all';\nexport type RichTextVerticalDirection = 'top' | 'middle' | 'bottom';\nexport type RichTextGlobalAlignType = 'left' | 'right' | 'center';\nexport type RichTextGlobalBaselineType = 'top' | 'middle' | 'bottom';\nexport type RichTextLayoutDirectionType = 'horizontal' | 'vertical';\nexport type RichTextFontStyle = 'normal' | 'italic' | 'oblique';\nexport type RichTextTextDecoration = 'none' | 'underline' | 'line-through';\n// export type RichTextTextAlign = 'left' | 'right' | 'center';\nexport type RichTextScript = 'normal' | 'sub' | 'super';\n\nexport type IRichTextBasicCharacter = {\n lineHeight?: number | string;\n textAlign?: CanvasTextAlign; // left, right, center\n textBaseline?: CanvasTextBaseline;\n direction?: RichTextLayoutDirectionType;\n};\n\nexport type IRichTextParagraphCharacter = IRichTextBasicCharacter & {\n text: string | number;\n fontSize?: number;\n fontFamily?: string;\n fill?: IColor | boolean;\n stroke?: IColor | boolean;\n fontWeight?: string;\n // lineHeight?: number;\n fontStyle?: RichTextFontStyle; // normal, italic, oblique\n textDecoration?: RichTextTextDecoration; // none, underline, line-through\n // textAlign?: RichTextTextAlign; // left, right, center\n script?: RichTextScript; // normal, sub, super\n underline?: boolean;\n lineThrough?: boolean;\n // direction?: RichTextLayoutDirectionType;\n};\n\nexport type IRichTextImageCharacter = IRichTextBasicCharacter & {\n // 图片基础属性\n image: string | HTMLImageElement | HTMLCanvasElement;\n width: number;\n height: number;\n\n // hover相关属性\n // backgroundShow?: boolean; // 是否显示background\n backgroundShowMode?: 'always' | 'hover';\n backgroundFill?: boolean | IColor; // 背景矩形填充颜色\n backgroundFillOpacity?: number; // 背景矩形填充透明度\n backgroundStroke?: boolean | IColor; // 背景矩形边框颜色\n backgroundStrokeOpacity?: number; // 背景矩形边框透明度\n backgroundRadius?: number; // 背景矩形圆角\n // background size 同时控制了该icon的响应范围\n backgroundWidth?: number;\n backgroundHeight?: number;\n\n // 唯一标识符\n id?: string;\n\n // lineHeight?: number;\n // textAlign?: RichTextTextAlign; // left, right, center\n // direction?: RichTextLayoutDirectionType;\n margin?: number | number[];\n\n funcType?: string;\n hoverImage?: string | HTMLImageElement | HTMLCanvasElement;\n};\n\nexport type IRichTextCharacter = IRichTextParagraphCharacter | IRichTextImageCharacter;\n\nexport type IRichTextIconGraphicAttribute = IImageGraphicAttribute & {\n id?: string;\n backgroundShowMode?: 'always' | 'hover' | 'never';\n backgroundFill?: boolean | IColor; // 背景矩形填充颜色\n backgroundFillOpacity?: number; // 背景矩形填充透明度\n backgroundStroke?: boolean | IColor; // 背景矩形边框颜色\n backgroundStrokeOpacity?: number; // 背景矩形边框透明度\n backgroundRadius?: number; // 背景矩形圆角\n backgroundWidth?: number;\n backgroundHeight?: number;\n\n // lineHeight?: number;\n textAlign?: CanvasTextAlign; // left, right, center\n textBaseline?: CanvasTextBaseline;\n direction?: RichTextLayoutDirectionType;\n\n margin?: number | number[];\n\n // backgroundShow?: boolean;\n};\n\nexport interface IRichTextParagraph {\n text: string;\n ascent: number;\n descent: number;\n width: number;\n height: number;\n lineHeight: number;\n fontSize: number;\n length: number;\n newLine: boolean;\n character: IRichTextParagraphCharacter;\n left: number;\n top: number;\n direction?: 'horizontal' | 'vertical';\n widthOrigin?: number;\n heightOrigin?: number;\n textBaseline?: CanvasTextBaseline;\n ellipsis: 'normal' | 'add' | 'replace' | 'hide';\n ellipsisWidth: number;\n ellipsisOtherParagraphWidth: number;\n verticalEllipsis?: boolean;\n updateWidth: () => void;\n draw: (ctx: IContext2d, baseline: number, deltaLeft: number, isLineFirst: boolean, textAlign: string) => void;\n getWidthWithEllips: (direction: string) => number;\n}\n\nexport interface IRichTextLine {\n left: number;\n top: number;\n width: number;\n height: number;\n baseline: number;\n ascent: number;\n descent: number;\n paragraphs: (IRichTextParagraph | IRichTextIcon)[];\n actualWidth: number;\n blankWidth: number;\n textAlign: string;\n direction: 'horizontal' | 'vertical';\n directionKey: {\n width: string;\n height: string;\n left: string;\n x: string;\n y: string;\n };\n draw: (\n ctx: IContext2d,\n lastLine: boolean,\n x: number,\n y: number,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) => void;\n getWidthWithEllips: () => number;\n}\n\nexport interface IRichTextFrame {\n left: number;\n top: number;\n bottom: number;\n right: number;\n width: number;\n height: number;\n actualHeight: number;\n ellipsis: boolean | string;\n wordBreak: 'break-word' | 'break-all';\n verticalDirection: 'top' | 'middle' | 'bottom';\n lines: IRichTextLine[];\n globalAlign: 'left' | 'center' | 'right' | 'start' | 'end';\n globalBaseline: 'top' | 'middle' | 'bottom';\n layoutDirection: 'horizontal' | 'vertical';\n directionKey: {\n width: string;\n height: string;\n left: string;\n top: string;\n bottom: string;\n };\n isWidthMax: boolean;\n isHeightMax: boolean;\n singleLine: boolean;\n icons: Map<string, IRichTextIcon>;\n draw: (\n ctx: IContext2d,\n drawIcon: (icon: IRichTextIcon, context: IContext2d, x: number, y: number, baseline: number) => void\n ) => boolean;\n getActualSize: () => {\n width: number;\n height: number;\n };\n getRawActualSize: () => {\n width: number;\n height: number;\n };\n getActualSizeWidthEllipsis: () => {\n width: number;\n height: number;\n };\n}\n\nexport interface IRichText extends IGraphic<IRichTextGraphicAttribute> {\n getFrameCache: () => IRichTextFrame;\n}\n\nexport interface IRichTextIcon extends IImage {\n attribute: IRichTextIconGraphicAttribute;\n richtextId?: string;\n globalX?: number;\n globalY?: number;\n\n _x: number;\n _y: number;\n _hovered: boolean;\n _marginArray: [number, number, number, number];\n\n setHoverState: (hovered: boolean) => void;\n}\n"]}
|
|
@@ -48,7 +48,7 @@ export type IFillStyle = {
|
|
|
48
48
|
fill: IFillType;
|
|
49
49
|
};
|
|
50
50
|
export type ILayout = {
|
|
51
|
-
alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center'
|
|
51
|
+
alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';
|
|
52
52
|
};
|
|
53
53
|
export type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {
|
|
54
54
|
distance: number | string;
|
|
@@ -94,7 +94,7 @@ export type IBackgroundConfig = {
|
|
|
94
94
|
expandY?: number;
|
|
95
95
|
};
|
|
96
96
|
type IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;
|
|
97
|
-
export type IGraphicStyle = IFillStyle & IStrokeStyle & IPickStyle & {
|
|
97
|
+
export type IGraphicStyle = ILayout & IFillStyle & IStrokeStyle & IPickStyle & {
|
|
98
98
|
opacity: number;
|
|
99
99
|
backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
|
|
100
100
|
backgroundFit: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IOBBBounds, IMatrix, IPointLike, IPoint } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget } from './animate';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\n\ntype IStrokeSeg = {\n start: number; // 百分比\n // end和length二选一\n end: number; // 百分比\n length: number; // 像素长度\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph';\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n x: number;\n y: number;\n z: number;\n dx: number;\n dy: number;\n dz: number;\n scrollX: number;\n scrollY: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n angle: number;\n alpha: number;\n beta: number;\n scaleCenter: [number | string, number | string];\n anchor: [number | string, number | string]; // 基于AABB的锚点位置,用于简单的定位某些path\n anchor3d: [number | string, number | string, number] | [number | string, number | string]; // 3d的锚点位置\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n fillOpacity: number;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n fill: IFillType;\n};\n\nexport type ILayout = {\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n distance: number | string;\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n outerBorder: Partial<IBorderStyle>;\n innerBorder: Partial<IBorderStyle>;\n strokeOpacity: number;\n lineDash: number[];\n lineDashOffset: number;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n // 描边的boundsBuffer,用于控制bounds的buffer\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n // 连接,取零或者断开\n connectedType: 'connect' | 'zero' | 'none';\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\ntype IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport type IGraphicStyle = IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n opacity: number;\n backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关)\n backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n backgroundCornerRadius: number | number[];\n background:\n | IBackgroundType\n | {\n background: IBackgroundType;\n dx?: number;\n dy?: number;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n texture: TextureType | string; // 纹理\n textureColor: string; // 纹理颜色\n textureSize: number; // 纹理大小\n texturePadding: number; // 纹理间隙\n blur: number;\n cursor: Cursor | null; // 鼠标样式\n // HTML的dom或者string\n html: {\n dom: string | HTMLElement; // dom字符串或者dom\n container: string | HTMLElement | null; // id或者dom\n width: number; // 容器的宽度\n height: number; // 容器的高度\n style: string | Record<string, any>; // 容器的样式\n visible?: boolean;\n anchorType?: 'position' | 'boundsLeftTop';\n } | null;\n };\n\nexport type IPickStyle = {\n // 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n // 包围盒的padding\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n zIndex: number;\n layout: any;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n globalZIndex: number;\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n // 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n id?: number | string;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n\n bindDom?: Map<string | HTMLElement, { container: HTMLElement | string; dom: HTMLElement; wrapGroup: HTMLDivElement }>;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: Record<string, Partial<T>>;\n normalAttrs?: Partial<T>;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string, hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (attrs: Partial<T>, stateNames: string[], hasAnimation?: boolean, isClear?: boolean) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/graphic.ts"],"names":[],"mappings":"","file":"graphic.js","sourcesContent":["import type { IAABBBounds, IOBBBounds, IMatrix, IPointLike, IPoint } from '@visactor/vutils';\nimport type { IAnimate, IStep, EasingType, IAnimateTarget } from './animate';\nimport type { IColor } from './color';\nimport type { IGroup } from './graphic/group';\nimport type { IShadowRoot } from './graphic/shadow-root';\nimport type { ILayer } from './layer';\nimport type { INode } from './node-tree';\nimport type { ICustomPath2D } from './path';\nimport type { IStage } from './stage';\nimport type { IGlyphGraphicAttribute } from './graphic/glyph';\nimport type { IContainPointMode } from '../common/enums';\nimport type { IFace3d } from './graphic/face3d';\nimport type { IPickerService } from './picker';\n\ntype IStrokeSeg = {\n start: number; // 百分比\n // end和length二选一\n end: number; // 百分比\n length: number; // 像素长度\n};\n\n// TODO 最后加一个any\nexport type GraphicType =\n | 'area'\n | 'circle'\n | 'ellipse'\n | 'line'\n | 'rect'\n | 'rect3d'\n | 'path'\n | 'richtext'\n | 'text'\n | 'arc'\n | 'arc3d'\n | 'image'\n | 'symbol'\n | 'group'\n | 'shadowroot'\n | 'polygon'\n | 'pyramid3d'\n | 'glyph';\n\n// Cursor style\n// See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\nexport type Cursor =\n | 'auto'\n | 'default'\n | 'none'\n | 'context-menu'\n | 'help'\n | 'pointer'\n | 'progress'\n | 'wait'\n | 'cell'\n | 'crosshair'\n | 'text'\n | 'vertical-text'\n | 'alias'\n | 'copy'\n | 'move'\n | 'no-drop'\n | 'not-allowed'\n | 'grab'\n | 'grabbing'\n | 'all-scroll'\n | 'col-resize'\n | 'row-resize'\n | 'n-resize'\n | 'e-resize'\n | 's-resize'\n | 'w-resize'\n | 'ne-resize'\n | 'nw-resize'\n | 'se-resize'\n | 'sw-resize'\n | 'ew-resize'\n | 'ns-resize'\n | 'nesw-resize'\n | 'nwse-resize'\n | 'zoom-in'\n | 'zoom-out';\n\nexport type ITransform = {\n x: number;\n y: number;\n z: number;\n dx: number;\n dy: number;\n dz: number;\n scrollX: number;\n scrollY: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n angle: number;\n alpha: number;\n beta: number;\n scaleCenter: [number | string, number | string];\n anchor: [number | string, number | string]; // 基于AABB的锚点位置,用于简单的定位某些path\n anchor3d: [number | string, number | string, number] | [number | string, number | string]; // 3d的锚点位置\n postMatrix: IMatrix;\n};\n\nexport type IFillType = boolean | string | IColor;\nexport type IFillStyle = {\n fillOpacity: number;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n fill: IFillType;\n};\n\nexport type ILayout = {\n alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center';\n};\n\nexport type IBorderStyle = Omit<IStrokeStyle, 'outerBorder' | 'innerBorder'> & {\n distance: number | string;\n visible?: boolean;\n};\n\nexport type IStrokeType = boolean | string | IColor | null;\nexport type IStrokeStyle = {\n outerBorder: Partial<IBorderStyle>;\n innerBorder: Partial<IBorderStyle>;\n strokeOpacity: number;\n lineDash: number[];\n lineDashOffset: number;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n // 描边的boundsBuffer,用于控制bounds的buffer\n strokeBoundsBuffer: number;\n /**\n * stroke - true 全描边\n * stroke - false 不描边\n * stroke 为数值类型,适用于rect\\arc等图形,用于配置部分描边的场景,其中\n *\n * 0b00000 - 不描边\n * 0b000001 - top\n * 0b000010 - right\n * 0b000100 - bottom\n * 0b001000 - left\n * 相应的:\n * 0b000011 - top + right\n * 0b000111 - top + right + bottom\n * 0b001111 - 全描边\n *\n * stroke - boolean[],适用于rect\\arc等图形,用于配置部分描边的场景\n */\n stroke: IStrokeType[] | IStrokeType;\n};\n\ntype TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid';\n\nexport type IConnectedStyle = {\n // 连接,取零或者断开\n connectedType: 'connect' | 'zero' | 'none';\n connectedStyle: {\n stroke: IStrokeStyle['stroke'];\n strokeOpacity: IStrokeStyle['strokeOpacity'];\n lineDash: IStrokeStyle['lineDash'];\n lineDashOffset: IStrokeStyle['lineDashOffset'];\n lineCap: IStrokeStyle['lineCap'];\n lineJoin: IStrokeStyle['lineJoin'];\n lineWidth: IStrokeStyle['lineWidth'];\n fill: IFillStyle['fill'];\n fillOpacity: IFillStyle['fillOpacity'];\n };\n connectedX: number;\n connectedY: number;\n};\n\nexport type IBackgroundConfig = {\n stroke?: string | boolean;\n fill?: string | boolean;\n lineWidth?: number;\n cornerRadius?: number;\n expandX?: number;\n expandY?: number;\n};\n\ntype IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig;\n\nexport type IGraphicStyle = ILayout &\n IFillStyle &\n IStrokeStyle &\n IPickStyle & {\n opacity: number;\n backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关)\n backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效\n backgroundCornerRadius: number | number[];\n background:\n | IBackgroundType\n | {\n background: IBackgroundType;\n dx?: number;\n dy?: number;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n }\n | null; // 背景,可以与fill同时存在\n texture: TextureType | string; // 纹理\n textureColor: string; // 纹理颜色\n textureSize: number; // 纹理大小\n texturePadding: number; // 纹理间隙\n blur: number;\n cursor: Cursor | null; // 鼠标样式\n // HTML的dom或者string\n html: {\n dom: string | HTMLElement; // dom字符串或者dom\n container: string | HTMLElement | null; // id或者dom\n width: number; // 容器的宽度\n height: number; // 容器的高度\n style: string | Record<string, any>; // 容器的样式\n visible?: boolean;\n anchorType?: 'position' | 'boundsLeftTop';\n } | null;\n };\n\nexport type IPickStyle = {\n // 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围\n pickStrokeBuffer: number;\n};\n\nexport type IDebugType = {\n _debug_bounds: boolean | ((c: any, g: any) => void);\n};\nexport type IGraphicAttribute = IDebugType &\n IGraphicStyle &\n ITransform & {\n /**\n * stroke百分比\n */\n strokeSeg: IStrokeSeg | null;\n // 包围盒的padding\n boundsPadding: number | number[];\n /**\n * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式\n */\n pickMode: 'accurate' | 'imprecise' | 'custom';\n boundsMode: 'accurate' | 'imprecise';\n customPickShape: () => boolean | null;\n /**\n * 是否支持事件拾取,默认为 true。\n * @default true\n */\n pickable: boolean;\n /**\n * 是否支持fill拾取,默认为 true。\n * @experimental\n * @default true\n */\n fillPickable: boolean;\n /**\n * 是否支持stroke拾取,默认为 true。\n * @experimental\n * @default true\n */\n strokePickable: boolean;\n /**\n * 对于 group 节点,是否支持其子元素的事件拾取,默认为 true。\n * 如果 group `pickable` 关闭,`childrenPickable` 开启,那么 group 的子节点仍参与事件拾取\n * @default true\n */\n childrenPickable: boolean;\n /**\n * 元素是否可见。\n * @default true\n */\n visible: boolean;\n zIndex: number;\n layout: any;\n /**\n * 是否在3d中控制方向\n * false: 不控制方向\n * true: 始终控制方向朝摄像机\n */\n keepDirIn3d?: boolean;\n shadowRootIdx: number;\n globalZIndex: number;\n globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | '';\n // 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动\n overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y';\n };\n\nexport interface IGraphicJson<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>> {\n attribute: Partial<T>;\n _uid: number;\n type: string;\n name: string;\n children: IGraphicJson<T>[];\n}\n\n/** the context of setAttribute */\nexport type ISetAttributeContext = {\n /** type of setAttribute */\n type?: number;\n animationState?: {\n step?: IStep;\n isFirstFrameOfStep?: boolean;\n /** ratio of animation */\n ratio?: number;\n /** is animation end? */\n end?: boolean;\n };\n skipUpdateCallback?: boolean;\n};\n\nexport type IGraphicAnimateParams = {\n id?: number | string;\n onStart?: () => void;\n onFrame?: (step: IStep, ratio: number) => void;\n onEnd?: () => void;\n onRemove?: () => void;\n interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;\n};\n\nexport interface IGraphic<T extends Partial<IGraphicAttribute> = Partial<IGraphicAttribute>>\n extends INode,\n IAnimateTarget {\n type?: GraphicType;\n numberType?: number;\n stage?: IStage;\n layer?: ILayer;\n shadowRoot?: IShadowRoot;\n glyphHost?: IGraphic<IGlyphGraphicAttribute>;\n backgroundImg?: boolean;\n\n bindDom?: Map<string | HTMLElement, { container: HTMLElement | string; dom: HTMLElement; wrapGroup: HTMLDivElement }>;\n\n valid: boolean;\n parent: IGroup | null;\n isContainer?: boolean;\n // 是否是3d模式(是否应用3d视角)\n in3dMode?: boolean;\n\n // 上次更新的stamp\n stamp?: number;\n animationBackUps?: {\n from: Record<string, any>;\n to: Record<string, any>;\n };\n\n attribute: Partial<T>;\n\n /** 用于实现morph动画场景,转换成bezier曲线渲染 */\n pathProxy?: ICustomPath2D | ((attrs: T) => ICustomPath2D);\n incremental?: number;\n incrementalAt?: number;\n\n /** 记录state对应的图形属性 */\n states?: Record<string, Partial<T>>;\n normalAttrs?: Partial<T>;\n stateProxy?: (stateName: string, targetStates?: string[]) => Partial<T>;\n findFace?: () => IFace3d;\n toggleState: (stateName: string, hasAnimation?: boolean) => void;\n removeState: (stateName: string, hasAnimation?: boolean) => void;\n clearStates: (hasAnimation?: boolean) => void;\n useStates: (states: string[], hasAnimation?: boolean) => void;\n addState: (stateName: string, keepCurrentStates?: boolean, hasAnimation?: boolean) => void;\n hasState: (stateName?: string) => boolean;\n getState: (stateName: string) => Partial<T>;\n onBeforeAttributeUpdate?: (\n val: any,\n attributes: Partial<T>,\n key: null | string | string[],\n context?: ISetAttributeContext\n ) => T | undefined;\n applyStateAttrs: (attrs: Partial<T>, stateNames: string[], hasAnimation?: boolean, isClear?: boolean) => void;\n updateNormalAttrs: (stateAttrs: Partial<T>) => void;\n\n // get\n readonly AABBBounds: IAABBBounds; // 用于获取当前节点的AABB包围盒\n readonly OBBBounds: IOBBBounds; // 获取OBB包围盒,旋转防重叠需要用\n readonly globalAABBBounds: IAABBBounds; // 全局AABB包围盒\n readonly transMatrix: IMatrix; // 变换矩阵,动态计算\n readonly globalTransMatrix: IMatrix; // 变换矩阵,动态计算\n\n getOffsetXY: (attr?: ITransform) => IPoint;\n\n // function\n containsPoint: (x: number, y: number, mode?: IContainPointMode, picker?: IPickerService) => boolean;\n\n setMode: (mode: '3d' | '2d') => void;\n isValid: () => boolean;\n\n // TODO: transform API\n // 基于当前transform的变换,普通用户尽量别用,拿捏不住的~\n translate: (x: number, y: number) => this;\n translateTo: (x: number, y: number) => this;\n scale: (scaleX: number, scaleY: number, scaleCenter?: IPointLike) => this;\n scaleTo: (scaleX: number, scaleY: number) => this;\n rotate: (angle: number, rotateCenter?: IPointLike) => this;\n rotateTo: (angle: number) => this;\n skewTo: (b: number, c: number) => this;\n addUpdateBoundTag: () => void;\n addUpdateShapeAndBoundsTag: () => void;\n addUpdateLayoutTag: () => void;\n\n update: (d?: { bounds: boolean; trans: boolean }) => void;\n\n // animate\n animate: (params?: IGraphicAnimateParams) => IAnimate;\n\n // 语法糖,可有可无,有的为了首屏性能考虑做成get方法,有的由外界直接托管,内部不赋值\n name?: string;\n\n // 供render处理shape缓存tag\n shouldUpdateShape: () => boolean;\n clearUpdateShapeTag: () => void;\n\n // // 供render缓存shape\n // cacheShape?: ICustomPath2D;\n // // 线段使用的path2D\n // cacheLine?: ISegPath2D | ISegPath2D[];\n // // 面积图使用的path2D\n // cacheArea?: IAreaCacheItem | IAreaCacheItem[];\n\n setAttributes: (params: Partial<T>, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n initAttributes: (params: Partial<T>) => void;\n\n setAttribute: (key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext) => void;\n\n setStage: (stage?: IStage, layer?: ILayer) => void;\n onSetStage: (cb: (g: IGraphic, stage: IStage) => void) => void;\n\n shouldUpdateAABBBounds: () => boolean;\n shouldSelfChangeUpdateAABBBounds: () => boolean;\n shouldUpdateGlobalMatrix: () => boolean;\n\n addUpdatePositionTag: () => void;\n addUpdateGlobalPositionTag: () => void;\n\n attachShadow: () => IShadowRoot;\n detachShadow: () => void;\n\n toJson: () => IGraphicJson;\n\n /** 创建pathProxy */\n createPathProxy: (path?: string) => void;\n /** 将图形转换成CustomPath2D */\n toCustomPath?: () => ICustomPath2D;\n\n resources?: Map<\n string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig,\n { state: 'init' | 'loading' | 'success' | 'fail'; data?: HTMLImageElement | HTMLCanvasElement }\n >;\n imageLoadSuccess: (url: string, data: HTMLImageElement) => void;\n imageLoadFail: (url: string) => void;\n\n clone: () => IGraphic;\n stopAnimates: (stopChildren?: boolean) => void;\n getNoWorkAnimateAttr: () => Record<string, number>;\n}\n\nexport interface IRoot extends IGraphic {\n pick: (x: number, y: number) => IGraphic;\n}\n\n/**\n * 动画配置\n */\nexport type IAnimateConfig = {\n duration?: number;\n easing?: EasingType;\n};\n\nexport type GraphicReleaseStatus = 'released' | 'willRelease';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/picker.ts"],"names":[],"mappings":"","file":"picker.js","sourcesContent":["import type { IBounds, IMatrix, IPoint, IPointLike } from '@visactor/vutils';\nimport type { IGraphic } from './graphic';\nimport type { IContext2d } from './context';\nimport type { EnvType, IGlobal } from './global';\nimport type { IGroup } from './graphic/group';\nimport type { IDrawContribution } from './render';\n\nexport type PickResult = {\n graphic?: IGraphic | null;\n group?: IGroup | null;\n params?: {\n shadowTarget?: IGraphic;\n };\n};\n\nexport interface IGraphicPicker {\n type: string;\n numberType: number;\n\n contains: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n}\n\nexport interface IPickParams {\n group?: boolean;\n graphic?: boolean;\n bounds?: IBounds;\n pickContext?: IContext2d;\n pickerService?: IPickerService;\n // 内部设置\n in3dInterceptor?: boolean;\n hack_pieFace?: string;\n}\n\nexport interface IPickerService {\n type: string;\n\n pickContext?: IContext2d;\n pickerMap: Map<number, IGraphicPicker>;\n configure: (global: IGlobal, env: EnvType) => void;\n pick: (group: IGraphic[], point: IPoint, params?: IPickParams) => PickResult;\n pickGroup: (group: IGroup, point: IPointLike, parentMatrix: IMatrix, params: IPickParams) => PickResult;\n pickItem: (\n graphic: IGraphic,\n point: IPointLike,\n parentMatrix: IMatrix | null,\n params?: IPickParams\n ) => PickResult | null;\n containsPoint: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n drawContribution?: IDrawContribution;\n}\n\nexport interface IPickItemInterceptorContribution {\n order: number;\n // null代表没匹配到,boolean代表是否pick中\n beforePickItem?: (\n graphic: IGraphic,\n pickerService: IPickerService,\n point: IPointLike,\n drawContext: {\n in3dInterceptor?: boolean;\n },\n params?: {\n parentMatrix: IMatrix;\n }\n ) => PickResult | null;\n\n afterPickItem?: (\n graphic: IGraphic,\n pickerService: IPickerService,\n point: IPointLike,\n drawContext: {\n in3dInterceptor?: boolean;\n },\n params?: {\n parentMatrix: IMatrix;\n }\n ) => PickResult | null;\n // afterPickItem?: (\n // graphic: IGraphic,\n // pickerService: IPickerService,\n // ) => boolean;\n}\n\nexport interface IBoundsPicker {\n type: string;\n numberType?: number;\n\n contains: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/picker.ts"],"names":[],"mappings":"","file":"picker.js","sourcesContent":["import type { IBounds, IMatrix, IPoint, IPointLike } from '@visactor/vutils';\nimport type { IGraphic } from './graphic';\nimport type { IContext2d } from './context';\nimport type { EnvType, IGlobal } from './global';\nimport type { IGroup } from './graphic/group';\nimport type { IDrawContribution } from './render';\n\nexport type PickResult = {\n graphic?: IGraphic | null;\n group?: IGroup | null;\n params?: {\n shadowTarget?: IGraphic;\n };\n};\n\nexport interface IGraphicPicker {\n type: string;\n numberType: number;\n\n contains: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n}\n\nexport interface IPickParams {\n group?: boolean;\n graphic?: boolean;\n bounds?: IBounds;\n // 是否使用当前的Matrix,不用重新初始化matrix\n keepMatrix?: boolean;\n pickContext?: IContext2d;\n pickerService?: IPickerService;\n // 内部设置\n in3dInterceptor?: boolean;\n hack_pieFace?: string;\n}\n\nexport interface IPickerService {\n type: string;\n\n pickContext?: IContext2d;\n pickerMap: Map<number, IGraphicPicker>;\n configure: (global: IGlobal, env: EnvType) => void;\n pick: (group: IGraphic[], point: IPoint, params?: IPickParams) => PickResult;\n pickGroup: (group: IGroup, point: IPointLike, parentMatrix: IMatrix, params: IPickParams) => PickResult;\n pickItem: (\n graphic: IGraphic,\n point: IPointLike,\n parentMatrix: IMatrix | null,\n params?: IPickParams\n ) => PickResult | null;\n containsPoint: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n drawContribution?: IDrawContribution;\n}\n\nexport interface IPickItemInterceptorContribution {\n order: number;\n // null代表没匹配到,boolean代表是否pick中\n beforePickItem?: (\n graphic: IGraphic,\n pickerService: IPickerService,\n point: IPointLike,\n drawContext: {\n in3dInterceptor?: boolean;\n },\n params?: {\n parentMatrix: IMatrix;\n }\n ) => PickResult | null;\n\n afterPickItem?: (\n graphic: IGraphic,\n pickerService: IPickerService,\n point: IPointLike,\n drawContext: {\n in3dInterceptor?: boolean;\n },\n params?: {\n parentMatrix: IMatrix;\n }\n ) => PickResult | null;\n // afterPickItem?: (\n // graphic: IGraphic,\n // pickerService: IPickerService,\n // ) => boolean;\n}\n\nexport interface IBoundsPicker {\n type: string;\n numberType?: number;\n\n contains: (graphic: IGraphic, point: IPointLike, params?: IPickParams) => boolean;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interface/render.ts"],"names":[],"mappings":"","file":"render.js","sourcesContent":["import type { IAABBBounds, IBounds, IMatrixLike } from '@visactor/vutils';\nimport type { IColor } from './color';\nimport type { IContext2d } from './context';\nimport type { IGraphic, IGraphicAttribute } from './graphic';\nimport type { IMarkAttribute, IThemeAttribute } from './graphic/creator';\nimport type { IFullThemeSpec } from './graphic/theme';\nimport type { ILayer } from './layer';\nimport type { IStage } from './stage';\nimport type { IGroup } from './graphic/group';\nimport type { MaybePromise } from './common';\nimport type { ISyncHook } from './sync-hook';\n\n// 用于绘制的参数,提供context\n// TODO: 考虑是否可以隐藏上下文类型\nexport interface IRenderServiceDrawParams {\n context?: IContext2d;\n\n // 绘制的区域以及是否需要清屏\n clear?: string | IColor | boolean;\n width: number;\n height: number;\n x: number;\n y: number;\n stage: IStage;\n layer: ILayer;\n renderService: IRenderService;\n updateBounds: boolean;\n renderStyle?: string;\n}\n\nexport interface IRenderService {\n dirtyBounds: IBounds;\n renderTreeRoots: IGraphic[]; // 此次render的数组\n renderLists: IGraphic[];\n drawParams: IRenderServiceDrawParams;\n\n prepare: (updateBounds: boolean) => void;\n prepareRenderList: () => void;\n beforeDraw: (params: IRenderServiceDrawParams) => void;\n draw: (params: IRenderServiceDrawParams) => void;\n afterDraw: (params: IRenderServiceDrawParams) => void;\n render: (groups: IGroup[], params: IRenderServiceDrawParams) => MaybePromise<void>;\n}\n\nexport interface IDrawContext extends IRenderServiceDrawParams {\n startAtId?: number;\n break?: boolean;\n restartIncremental?: boolean;\n // multi图元开始的位置\n multiGraphicOptions?: {\n startAtIdx: number;\n length: number;\n };\n in3dInterceptor?: boolean;\n drawContribution?: IDrawContribution;\n // hack内容\n hack_pieFace?: 'inside' | 'bottom' | 'top' | 'outside';\n}\n\nexport interface IDrawContribution {\n hooks?: {\n completeDraw: ISyncHook<[]>;\n };\n dirtyBounds?: IAABBBounds;\n backupDirtyBounds?: IAABBBounds;\n rendering?: boolean;\n currentRenderMap: Map<number, IGraphicRender>;\n defaultRenderMap: Map<number, IGraphicRender>;\n styleRenderMap: Map<string, Map<number, IGraphicRender>>;\n draw: (renderService: IRenderService, drawParams: IDrawContext) => MaybePromise<void>;\n afterDraw?: (renderService: IRenderService, drawParams: IDrawContext) => MaybePromise<void>;\n getRenderContribution: (graphic: IGraphic) => IGraphicRender | null;\n renderGroup: (group: IGroup, drawContext: IDrawContext, matrix: IMatrixLike, skipSort?: boolean) => void;\n renderItem: (graphic: IGraphic, drawContext: IDrawContext, params?: IGraphicRenderDrawParams) => void;\n}\n\nexport interface IGraphicRenderDrawParams {\n beforeDrawCb?: () => void;\n afterDrawCb?: () => void;\n drawingCb?: () => void;\n skipDraw?: boolean;\n theme?: IFullThemeSpec;\n}\n\nexport interface IGraphicRender {\n type: string; // 图元类型\n numberType: number;\n style?: string;\n z?: number;\n draw: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n params?: IGraphicRenderDrawParams\n ) => void;\n drawShape?: (\n graphic: IGraphic,\n ctx: IContext2d,\n x: number,\n y: number,\n drawContext: IDrawContext,\n params?: IGraphicRenderDrawParams,\n fillCb?: (\n ctx: IContext2d,\n markAttribute: Partial<IMarkAttribute & IGraphicAttribute>,\n themeAttribute: IThemeAttribute\n ) => boolean,\n strokeCb?: (\n ctx: IContext2d,\n markAttribute: Partial<IMarkAttribute & IGraphicAttribute>,\n themeAttribute: IThemeAttribute\n ) => boolean\n ) => void;\n}\n\nexport interface IBeforeRenderConstribution {\n apply: (renderService: IRenderService) => MaybePromise<void>;\n}\n\nexport interface IRenderSelector {\n selector: (graphic: IGraphic) => IGraphicRender | null;\n}\n\nexport interface IDrawItemInterceptorContribution {\n order: number;\n beforeDrawItem?: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n drawContribution: IDrawContribution,\n params?: IGraphicRenderDrawParams\n ) => boolean;\n afterDrawItem?: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n drawContribution: IDrawContribution,\n params?: IGraphicRenderDrawParams\n ) => boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interface/render.ts"],"names":[],"mappings":"","file":"render.js","sourcesContent":["import type { IAABBBounds, IBounds, IMatrixLike } from '@visactor/vutils';\nimport type { IColor } from './color';\nimport type { IContext2d } from './context';\nimport type { IGraphic, IGraphicAttribute } from './graphic';\nimport type { IMarkAttribute, IThemeAttribute } from './graphic/creator';\nimport type { IFullThemeSpec } from './graphic/theme';\nimport type { ILayer } from './layer';\nimport type { IStage } from './stage';\nimport type { IGroup } from './graphic/group';\nimport type { MaybePromise } from './common';\nimport type { ISyncHook } from './sync-hook';\n\n// 用于绘制的参数,提供context\n// TODO: 考虑是否可以隐藏上下文类型\nexport interface IRenderServiceDrawParams {\n context?: IContext2d;\n\n // 绘制的区域以及是否需要清屏\n clear?: string | IColor | boolean;\n width: number;\n height: number;\n x: number;\n y: number;\n // 是否使用当前的Matrix,不用重新初始化matrix\n keepMatrix?: boolean;\n stage: IStage;\n layer: ILayer;\n renderService: IRenderService;\n updateBounds: boolean;\n renderStyle?: string;\n}\n\nexport interface IRenderService {\n dirtyBounds: IBounds;\n renderTreeRoots: IGraphic[]; // 此次render的数组\n renderLists: IGraphic[];\n drawParams: IRenderServiceDrawParams;\n\n prepare: (updateBounds: boolean) => void;\n prepareRenderList: () => void;\n beforeDraw: (params: IRenderServiceDrawParams) => void;\n draw: (params: IRenderServiceDrawParams) => void;\n afterDraw: (params: IRenderServiceDrawParams) => void;\n render: (groups: IGroup[], params: IRenderServiceDrawParams) => MaybePromise<void>;\n}\n\nexport interface IDrawContext extends IRenderServiceDrawParams {\n startAtId?: number;\n break?: boolean;\n restartIncremental?: boolean;\n // multi图元开始的位置\n multiGraphicOptions?: {\n startAtIdx: number;\n length: number;\n };\n in3dInterceptor?: boolean;\n drawContribution?: IDrawContribution;\n // hack内容\n hack_pieFace?: 'inside' | 'bottom' | 'top' | 'outside';\n}\n\nexport interface IDrawContribution {\n hooks?: {\n completeDraw: ISyncHook<[]>;\n };\n dirtyBounds?: IAABBBounds;\n backupDirtyBounds?: IAABBBounds;\n rendering?: boolean;\n currentRenderMap: Map<number, IGraphicRender>;\n defaultRenderMap: Map<number, IGraphicRender>;\n styleRenderMap: Map<string, Map<number, IGraphicRender>>;\n draw: (renderService: IRenderService, drawParams: IDrawContext) => MaybePromise<void>;\n afterDraw?: (renderService: IRenderService, drawParams: IDrawContext) => MaybePromise<void>;\n getRenderContribution: (graphic: IGraphic) => IGraphicRender | null;\n renderGroup: (group: IGroup, drawContext: IDrawContext, matrix: IMatrixLike, skipSort?: boolean) => void;\n renderItem: (graphic: IGraphic, drawContext: IDrawContext, params?: IGraphicRenderDrawParams) => void;\n}\n\nexport interface IGraphicRenderDrawParams {\n beforeDrawCb?: () => void;\n afterDrawCb?: () => void;\n drawingCb?: () => void;\n skipDraw?: boolean;\n theme?: IFullThemeSpec;\n}\n\nexport interface IGraphicRender {\n type: string; // 图元类型\n numberType: number;\n style?: string;\n z?: number;\n draw: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n params?: IGraphicRenderDrawParams\n ) => void;\n drawShape?: (\n graphic: IGraphic,\n ctx: IContext2d,\n x: number,\n y: number,\n drawContext: IDrawContext,\n params?: IGraphicRenderDrawParams,\n fillCb?: (\n ctx: IContext2d,\n markAttribute: Partial<IMarkAttribute & IGraphicAttribute>,\n themeAttribute: IThemeAttribute\n ) => boolean,\n strokeCb?: (\n ctx: IContext2d,\n markAttribute: Partial<IMarkAttribute & IGraphicAttribute>,\n themeAttribute: IThemeAttribute\n ) => boolean\n ) => void;\n}\n\nexport interface IBeforeRenderConstribution {\n apply: (renderService: IRenderService) => MaybePromise<void>;\n}\n\nexport interface IRenderSelector {\n selector: (graphic: IGraphic) => IGraphicRender | null;\n}\n\nexport interface IDrawItemInterceptorContribution {\n order: number;\n beforeDrawItem?: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n drawContribution: IDrawContribution,\n params?: IGraphicRenderDrawParams\n ) => boolean;\n afterDrawItem?: (\n graphic: IGraphic,\n renderService: IRenderService,\n drawContext: IDrawContext,\n drawContribution: IDrawContribution,\n params?: IGraphicRenderDrawParams\n ) => boolean;\n}\n"]}
|