@titaui/pc 1.7.22 → 1.7.26
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/lib/components/button/text-btn/index.css +1 -0
- package/lib/components/button/text-btn/index.js +10 -12
- package/lib/components/common-share/index.css +223 -0
- package/lib/components/common-share/index.js +108 -0
- package/lib/components/common-share/publishMblog.js +157 -0
- package/lib/components/common-share/request-apis.js +56 -0
- package/lib/components/common-share/types.js +5 -0
- package/lib/components/follower-visitor/index.css +8 -3
- package/lib/components/menus/components/menu-tree/tree-node/index.css +9 -6
- package/lib/components/nav-top/components/user-message/index.js +9 -0
- package/lib/components/okr-detail/components/okr-tree/tree-node/e-node/e-project.js +4 -2
- package/lib/components/okr-detail/components/okr-tree/tree-node/e-node/e-task-level2.js +2 -2
- package/lib/components/okr-detail/components/okr-tree/tree-node/e-node/e-task.js +2 -2
- package/lib/components/select-tags/index.css +6 -0
- package/lib/components/select-tags/index.js +1 -1
- package/lib/components/weekly-report/board.js +43 -0
- package/lib/components/weekly-report/card.js +231 -0
- package/lib/components/weekly-report/common-painter/darwAvatar.js +157 -0
- package/lib/components/weekly-report/common-painter/drawName.js +59 -0
- package/lib/components/weekly-report/common-painter/openDataPainter.js +95 -0
- package/lib/components/weekly-report/common-painter/setSize.js +19 -0
- package/lib/components/weekly-report/common-painter/utils.js +85 -0
- package/lib/components/weekly-report/img/body.png +0 -0
- package/lib/components/weekly-report/img/bofang.png +0 -0
- package/lib/components/weekly-report/img/bottom.png +0 -0
- package/lib/components/weekly-report/img/close.svg +22 -0
- package/lib/components/weekly-report/img/communication.png +0 -0
- package/lib/components/weekly-report/img/down.png +0 -0
- package/lib/components/weekly-report/img/finish.png +0 -0
- package/lib/components/weekly-report/img/laba.png +0 -0
- package/lib/components/weekly-report/img/praise.png +0 -0
- package/lib/components/weekly-report/img/quote.png +0 -0
- package/lib/components/weekly-report/img/title.png +0 -0
- package/lib/components/weekly-report/img/triangle-pop.png +0 -0
- package/lib/components/weekly-report/img/up.png +0 -0
- package/lib/components/weekly-report/index.css +343 -0
- package/lib/components/weekly-report/index.js +218 -0
- package/lib/components/weekly-report/statistics.js +47 -0
- package/lib/index.js +8 -0
- package/lib/pages/aha2021/index.css +0 -1
- package/lib/pages/new-okr-list/header/filter.js +52 -2
- package/lib/pages/new-okr-list/index.js +45 -6
- package/lib/utils/helpers.js +8 -1
- package/package.json +1 -1
- package/src/components/button/text-btn/index.scss +1 -0
- package/src/components/button/text-btn/index.tsx +13 -13
- package/src/components/button/types.ts +1 -0
- package/src/components/common-share/index.scss +199 -0
- package/src/components/common-share/index.tsx +95 -0
- package/src/components/common-share/publishMblog.tsx +81 -0
- package/src/components/common-share/request-apis.js +37 -0
- package/src/components/common-share/types.ts +4 -0
- package/src/components/follower-visitor/index.scss +9 -4
- package/src/components/menus/components/menu-tree/tree-node/index.scss +2 -1
- package/src/components/nav-top/components/user-message/index.tsx +6 -1
- package/src/components/okr-detail/components/okr-tree/tree-node/e-node/e-project.js +1 -1
- package/src/components/okr-detail/components/okr-tree/tree-node/e-node/e-task-level2.js +2 -2
- package/src/components/okr-detail/components/okr-tree/tree-node/e-node/e-task.js +2 -2
- package/src/components/okr-share/index.tsx +4 -17
- package/src/components/select-tags/index.scss +7 -0
- package/src/components/select-tags/index.tsx +7 -11
- package/src/components/weekly-report/board.tsx +25 -0
- package/src/components/weekly-report/card.tsx +150 -0
- package/src/components/weekly-report/common-painter/darwAvatar.ts +81 -0
- package/src/components/weekly-report/common-painter/drawName.ts +19 -0
- package/src/components/weekly-report/common-painter/openDataPainter.ts +47 -0
- package/src/components/weekly-report/common-painter/setSize.ts +12 -0
- package/src/components/weekly-report/common-painter/utils.ts +83 -0
- package/src/components/weekly-report/img/body.png +0 -0
- package/src/components/weekly-report/img/bofang.png +0 -0
- package/src/components/weekly-report/img/bottom.png +0 -0
- package/src/components/weekly-report/img/close.svg +22 -0
- package/src/components/weekly-report/img/communication.png +0 -0
- package/src/components/weekly-report/img/down.png +0 -0
- package/src/components/weekly-report/img/finish.png +0 -0
- package/src/components/weekly-report/img/laba.png +0 -0
- package/src/components/weekly-report/img/praise.png +0 -0
- package/src/components/weekly-report/img/quote.png +0 -0
- package/src/components/weekly-report/img/title.png +0 -0
- package/src/components/weekly-report/img/triangle-pop.png +0 -0
- package/src/components/weekly-report/img/up.png +0 -0
- package/src/components/weekly-report/index.scss +309 -0
- package/src/components/weekly-report/index.tsx +115 -0
- package/src/components/weekly-report/statistics.tsx +28 -0
- package/src/index.d.ts +2 -1
- package/src/index.js +2 -1
- package/src/pages/aha2021/index.scss +0 -1
- package/src/pages/new-okr-list/header/filter.tsx +36 -4
- package/src/pages/new-okr-list/index.tsx +33 -5
- package/src/utils/helpers.ts +4 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
ReactElement,
|
|
4
|
+
useEffect,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react";
|
|
9
|
+
import html2Canvas from "html2canvas";
|
|
10
|
+
import Board from "./board";
|
|
11
|
+
import { getLoginUserInfo } from "../../utils/helpers";
|
|
12
|
+
import { drawAvatar } from "./common-painter/darwAvatar";
|
|
13
|
+
import drawName from "./common-painter/drawName";
|
|
14
|
+
import Statistics from "./statistics";
|
|
15
|
+
import { isWx } from "../../utils/bs-global";
|
|
16
|
+
import "./index.scss";
|
|
17
|
+
import { rpost,rget } from "../../utils/request";
|
|
18
|
+
|
|
19
|
+
const preCls = "weekly-report-card";
|
|
20
|
+
|
|
21
|
+
interface Props {
|
|
22
|
+
}
|
|
23
|
+
const getImageBase64ByUrl = (toUserId) => {
|
|
24
|
+
return rpost("v1")(`okr/share/getBase64Str`, { toUserId }).then(
|
|
25
|
+
(getBase64Str) => {
|
|
26
|
+
return getBase64Str.Data;
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
function Card({}: Props, ref): ReactElement {
|
|
31
|
+
const [avatarSrc, setAvatarSrc] = useState<string>();
|
|
32
|
+
const [nameSrc, setNameSrc] = useState<string>();
|
|
33
|
+
const loginUserInfo = getLoginUserInfo();
|
|
34
|
+
const cardRef = useRef<any>();
|
|
35
|
+
useImperativeHandle(
|
|
36
|
+
ref,
|
|
37
|
+
() => ({
|
|
38
|
+
getImage: async function () {
|
|
39
|
+
return new Promise((res) => {
|
|
40
|
+
let width = 375, //获取dom 宽度
|
|
41
|
+
height = 710, //获取dom 高度
|
|
42
|
+
canvas = document.createElement("canvas"), //创建一个canvas节点
|
|
43
|
+
scale = 2; //定义任意放大倍数 支持小数
|
|
44
|
+
canvas.width = width * scale; //定义canvas 宽度 * 缩放
|
|
45
|
+
canvas.height = height * scale; //定义canvas高度 *缩放
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
canvas.style.width = width + "px";
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
canvas.style.height = height + "px";
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
let opts = {
|
|
52
|
+
backgroundColor: null, // 背景透明
|
|
53
|
+
scale: scale, // 添加的scale 参数
|
|
54
|
+
canvas: canvas, // 自定义 canvas
|
|
55
|
+
logging: false, // 日志开关,便于查看html2canvas的内部执行流程
|
|
56
|
+
width: width, // dom 原始宽度
|
|
57
|
+
height: height,
|
|
58
|
+
useCORS: true, // 【重要】开启跨域配置
|
|
59
|
+
};
|
|
60
|
+
html2Canvas(cardRef.current as any, opts).then((canvas) => {
|
|
61
|
+
let imgUrl = canvas.toDataURL("image/png"); //得到图片的base64编码数据
|
|
62
|
+
res(imgUrl);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
[]
|
|
68
|
+
);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (isWx()) {
|
|
71
|
+
window["WWOpenData"] &&
|
|
72
|
+
window["WWOpenData"].enableCanvasSharing &&
|
|
73
|
+
window["WWOpenData"].enableCanvasSharing();
|
|
74
|
+
}
|
|
75
|
+
if (loginUserInfo.UserAvatar.HasAvatar) {
|
|
76
|
+
getImageBase64ByUrl(loginUserInfo.Id)
|
|
77
|
+
.then((data) =>
|
|
78
|
+
drawAvatar(
|
|
79
|
+
{
|
|
80
|
+
name: loginUserInfo.Name,
|
|
81
|
+
userId: loginUserInfo.Id,
|
|
82
|
+
color: loginUserInfo.UserAvatar.Color,
|
|
83
|
+
},
|
|
84
|
+
"data:image/jpeg;base64," + data.obj
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
.then(setAvatarSrc);
|
|
88
|
+
} else {
|
|
89
|
+
drawAvatar(
|
|
90
|
+
{
|
|
91
|
+
name: loginUserInfo.Name,
|
|
92
|
+
userId: loginUserInfo.Id,
|
|
93
|
+
color: loginUserInfo.UserAvatar.Color,
|
|
94
|
+
},
|
|
95
|
+
""
|
|
96
|
+
).then(setAvatarSrc);
|
|
97
|
+
}
|
|
98
|
+
drawName(loginUserInfo.Name, loginUserInfo.Id).then(setNameSrc);
|
|
99
|
+
return () => {
|
|
100
|
+
if (isWx()) {
|
|
101
|
+
window["WWOpenData"] &&
|
|
102
|
+
window["WWOpenData"].disableCanvasSharing &&
|
|
103
|
+
window["WWOpenData"].disableCanvasSharing();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div className={preCls + "-content"} ref={cardRef}>
|
|
112
|
+
<img className={preCls + "__title"} src={require("./img/title.png")} />
|
|
113
|
+
<div className={preCls + "__date-range"}>6月7日-6月11日</div>
|
|
114
|
+
<div className={preCls + "__shadow"} />
|
|
115
|
+
<img className={preCls + "__laba"} src={require("./img/laba.png")} />
|
|
116
|
+
<img className={preCls + "__bofang"} src={require("./img/bofang.png")} />
|
|
117
|
+
<div className={preCls + "__body"}>
|
|
118
|
+
<div className={preCls + "__avatar"}>
|
|
119
|
+
<img src={avatarSrc} />
|
|
120
|
+
</div>
|
|
121
|
+
<img className={preCls + "__userName"} src={nameSrc} />
|
|
122
|
+
<img
|
|
123
|
+
className={preCls + "__quote"}
|
|
124
|
+
src={require("./img/quote.png")}
|
|
125
|
+
alt=""
|
|
126
|
+
/>
|
|
127
|
+
<div className={preCls + "__text"}>
|
|
128
|
+
坚持每周反馈才是真正的优秀真正的优秀
|
|
129
|
+
</div>
|
|
130
|
+
<Board percent={80} />
|
|
131
|
+
<div className={preCls + "__comparison"}>
|
|
132
|
+
OKR 完成度
|
|
133
|
+
<img
|
|
134
|
+
className={preCls + "__direction"}
|
|
135
|
+
src={require("./img/up.png")}
|
|
136
|
+
alt=""
|
|
137
|
+
/>
|
|
138
|
+
<span style={{ color: "#4DC591" }}>20%</span>
|
|
139
|
+
</div>
|
|
140
|
+
<div className={preCls + "__colleague"}>
|
|
141
|
+
恭喜超越了 <span>80%</span> 的同事
|
|
142
|
+
</div>
|
|
143
|
+
<Statistics />
|
|
144
|
+
</div>
|
|
145
|
+
<img className={preCls + "__bottom"} src={require("./img/bottom.png")} />
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export default forwardRef(Card);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import openDataPainter from "./openDataPainter";
|
|
2
|
+
import setSize from "./setSize";
|
|
3
|
+
import { drawImage } from "./utils";
|
|
4
|
+
|
|
5
|
+
interface avatarParms {
|
|
6
|
+
url?: string;
|
|
7
|
+
color?: string;
|
|
8
|
+
name: string;
|
|
9
|
+
id: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
maxNameWidth?: number;
|
|
15
|
+
}
|
|
16
|
+
export async function drawAvatar(shareData, avatar: string) {
|
|
17
|
+
if (window['WWOpenData'] && window['WWOpenData'].initCanvas) {
|
|
18
|
+
window['WWOpenData'].initCanvas()
|
|
19
|
+
}
|
|
20
|
+
const canvas = document.createElement('canvas');
|
|
21
|
+
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
22
|
+
setSize(canvas, ctx, 72, 72);
|
|
23
|
+
ctx.beginPath();
|
|
24
|
+
await draw(ctx, {
|
|
25
|
+
width: 72,
|
|
26
|
+
height: 72,
|
|
27
|
+
x: 0,
|
|
28
|
+
y: 0,
|
|
29
|
+
url: avatar,
|
|
30
|
+
name: shareData.name,
|
|
31
|
+
id: shareData.userId,
|
|
32
|
+
color: shareData.color
|
|
33
|
+
});
|
|
34
|
+
const dataUrl = canvas.toDataURL();
|
|
35
|
+
|
|
36
|
+
return dataUrl;
|
|
37
|
+
}
|
|
38
|
+
async function draw (ctx: CanvasRenderingContext2D, params: avatarParms):Promise<number> {
|
|
39
|
+
ctx.save();
|
|
40
|
+
ctx.beginPath();
|
|
41
|
+
ctx.arc(
|
|
42
|
+
params.width / 2 + params.x,
|
|
43
|
+
params.height / 2 + params.y,
|
|
44
|
+
params.width / 2,
|
|
45
|
+
0,
|
|
46
|
+
Math.PI * 2,
|
|
47
|
+
false,
|
|
48
|
+
);
|
|
49
|
+
ctx.clip();
|
|
50
|
+
ctx.closePath();
|
|
51
|
+
params.url ? await drawImageAvatar(ctx, params) : await drawTextAvatar(ctx, params);
|
|
52
|
+
ctx.restore();
|
|
53
|
+
return params.y + params.height;
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
function drawImageAvatar(ctx: CanvasRenderingContext2D, avatar: avatarParms) {
|
|
57
|
+
return drawImage(ctx,avatar.url as string,avatar.x,avatar.y,avatar.width,avatar.height)
|
|
58
|
+
}
|
|
59
|
+
function drawTextAvatar(ctx: CanvasRenderingContext2D, avatar: avatarParms) {
|
|
60
|
+
console.log('text')
|
|
61
|
+
const maxNameWidth = avatar.maxNameWidth || 28;
|
|
62
|
+
return new Promise<void>(async resolve => {
|
|
63
|
+
ctx.fillStyle = avatar.color as string;
|
|
64
|
+
ctx.fill();
|
|
65
|
+
|
|
66
|
+
ctx.closePath();
|
|
67
|
+
ctx.fillStyle = 'white';
|
|
68
|
+
ctx.font = '14px arial';
|
|
69
|
+
ctx.textBaseline = 'bottom';
|
|
70
|
+
let namePainter = await openDataPainter(ctx,{id:avatar.id,name:avatar.name,type:'userName'},22,maxNameWidth);
|
|
71
|
+
const { width, height } = namePainter;
|
|
72
|
+
|
|
73
|
+
namePainter.draw(
|
|
74
|
+
ctx,
|
|
75
|
+
avatar.x + avatar.width / 2 - width / 2,
|
|
76
|
+
avatar.y + avatar.height / 2 - height / 2,
|
|
77
|
+
);
|
|
78
|
+
ctx.closePath();
|
|
79
|
+
resolve();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import openDataPainter from "./openDataPainter";
|
|
2
|
+
import setSize from "./setSize";
|
|
3
|
+
|
|
4
|
+
export default async function(name,id){
|
|
5
|
+
const canvas = document.createElement('canvas');
|
|
6
|
+
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
7
|
+
setSize(canvas, ctx, 295, 24);
|
|
8
|
+
ctx.beginPath();
|
|
9
|
+
const lineHeight = 24;
|
|
10
|
+
ctx.font = `bold 16px/${lineHeight}px arial,sans-serif`;
|
|
11
|
+
ctx.fillStyle = '#141C28';
|
|
12
|
+
ctx.textBaseline='middle';
|
|
13
|
+
const painter = await openDataPainter(ctx, {name,id,type:'userName'},24,295);
|
|
14
|
+
let x = (295 - (painter.width)) / 2
|
|
15
|
+
painter.draw(ctx,x,0)
|
|
16
|
+
const dataUrl = canvas.toDataURL();
|
|
17
|
+
|
|
18
|
+
return dataUrl;
|
|
19
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getOpenId } from "&/components/common/openData";
|
|
2
|
+
import { isWx } from "&/components/helper";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
interface openDataParam {
|
|
6
|
+
id: number; name: string; type: 'userName' | 'departmentName'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default async function (
|
|
10
|
+
ctx: CanvasRenderingContext2D,
|
|
11
|
+
openDataParams: openDataParam,
|
|
12
|
+
lineHeight: number,
|
|
13
|
+
maxWidth: number = Infinity
|
|
14
|
+
) {
|
|
15
|
+
let name = openDataParams.name
|
|
16
|
+
if (isWx()) {
|
|
17
|
+
name = await getOpenData(openDataParams)
|
|
18
|
+
}
|
|
19
|
+
const { width } = ctx.measureText(name);
|
|
20
|
+
let actualWidth = Math.min(width, maxWidth)
|
|
21
|
+
return {
|
|
22
|
+
width: actualWidth,
|
|
23
|
+
height: lineHeight,
|
|
24
|
+
draw: function (ctx: CanvasRenderingContext2D, x: number, y: number) {
|
|
25
|
+
ctx.save()
|
|
26
|
+
ctx.textBaseline = 'middle';
|
|
27
|
+
ctx.beginPath();
|
|
28
|
+
ctx.rect(x, y, actualWidth, lineHeight);
|
|
29
|
+
ctx.clip();
|
|
30
|
+
ctx.fillText(name, x, y + lineHeight / 2);
|
|
31
|
+
ctx.closePath()
|
|
32
|
+
ctx.restore()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const getOpenData = ({ id, name, type }: openDataParam) => {
|
|
37
|
+
const openId = getOpenId(id, type)
|
|
38
|
+
if (!window['WWOpenData'] || !openId) return Promise.resolve(name)
|
|
39
|
+
return new Promise<string>((resolve, reject) => {
|
|
40
|
+
window['WWOpenData'].prefetch({ items: [{ id: openId, type }] }, (err, data) => {
|
|
41
|
+
if (err) {
|
|
42
|
+
return reject(err)
|
|
43
|
+
}
|
|
44
|
+
resolve(data.items[0].data)
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default function (canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, width, height) {
|
|
2
|
+
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
3
|
+
const data = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
4
|
+
//要将 canvas 的宽高设置成容器宽高的 2 倍
|
|
5
|
+
canvas.width = width * devicePixelRatio;
|
|
6
|
+
canvas.height = height * devicePixelRatio;
|
|
7
|
+
canvas.style.width = width + 'px';
|
|
8
|
+
canvas.style.height = height + 'px';
|
|
9
|
+
//然后将画布缩放,将图像放大两倍画到画布上
|
|
10
|
+
ctx.scale(devicePixelRatio, devicePixelRatio);
|
|
11
|
+
ctx.putImageData(data, 0, 0);
|
|
12
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export function drawImage(
|
|
2
|
+
ctx: CanvasRenderingContext2D,
|
|
3
|
+
url: string,
|
|
4
|
+
x: number,
|
|
5
|
+
y: number,
|
|
6
|
+
width: number,
|
|
7
|
+
height: number,
|
|
8
|
+
) {
|
|
9
|
+
return new Promise<void>(res => {
|
|
10
|
+
const img = new Image();
|
|
11
|
+
img.src = url;
|
|
12
|
+
img.onload = function () {
|
|
13
|
+
ctx.drawImage(img, x, y, width, height);
|
|
14
|
+
res();
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function drawTextMiddle(
|
|
19
|
+
ctx: CanvasRenderingContext2D,
|
|
20
|
+
text: string,
|
|
21
|
+
x: number,
|
|
22
|
+
y: number,
|
|
23
|
+
lineHeight: number,
|
|
24
|
+
maxWidth?: number,
|
|
25
|
+
textAlign?: 'left' | 'center'
|
|
26
|
+
) {
|
|
27
|
+
ctx.textBaseline = 'middle';
|
|
28
|
+
if (!maxWidth) {
|
|
29
|
+
|
|
30
|
+
ctx.fillText(text, x, y + lineHeight / 2);
|
|
31
|
+
return y + lineHeight;
|
|
32
|
+
}
|
|
33
|
+
const lines = breakLinesForCanvas(ctx, text, maxWidth);
|
|
34
|
+
lines.forEach((l) => {
|
|
35
|
+
const { width } = ctx.measureText(l)
|
|
36
|
+
let left = x;
|
|
37
|
+
if (textAlign == 'center' && maxWidth) {
|
|
38
|
+
console.log(maxWidth, width)
|
|
39
|
+
left = (maxWidth - width) / 2 + x
|
|
40
|
+
}
|
|
41
|
+
ctx.fillText(l, left, y + lineHeight / 2);
|
|
42
|
+
|
|
43
|
+
y = y + lineHeight;
|
|
44
|
+
})
|
|
45
|
+
return y
|
|
46
|
+
}
|
|
47
|
+
function findBreakPoint(text, width, context) {
|
|
48
|
+
var min = 0;
|
|
49
|
+
var max = text.length - 1;
|
|
50
|
+
|
|
51
|
+
while (min <= max) {
|
|
52
|
+
var middle = Math.floor((min + max) / 2);
|
|
53
|
+
var middleWidth = context.measureText(text.substr(0, middle)).width;
|
|
54
|
+
var oneCharWiderThanMiddleWidth = context.measureText(text.substr(0, middle + 1)).width;
|
|
55
|
+
if (middleWidth <= width && oneCharWiderThanMiddleWidth > width) {
|
|
56
|
+
return middle;
|
|
57
|
+
}
|
|
58
|
+
if (middleWidth < width) {
|
|
59
|
+
min = middle + 1;
|
|
60
|
+
} else {
|
|
61
|
+
max = middle - 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return -1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function breakLinesForCanvas(ctx: CanvasRenderingContext2D, text: string, width: number) {
|
|
69
|
+
var result: string[] = [];
|
|
70
|
+
var breakPoint = 0;
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
while ((breakPoint = findBreakPoint(text, width, ctx)) !== -1) {
|
|
74
|
+
result.push(text.substr(0, breakPoint));
|
|
75
|
+
text = text.substr(breakPoint);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (text) {
|
|
79
|
+
result.push(text);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<title>编组 31</title>
|
|
4
|
+
<defs>
|
|
5
|
+
<filter id="filter-1">
|
|
6
|
+
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1.000000 0 0 0 0 1.000000 0 0 0 0 1.000000 0 0 0 1.000000 0"></feColorMatrix>
|
|
7
|
+
</filter>
|
|
8
|
+
</defs>
|
|
9
|
+
<g id="每周推送" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
10
|
+
<g id="暂定-员工视角" transform="translate(-871.000000, -106.000000)">
|
|
11
|
+
<g id="编组-31" transform="translate(871.000000, 106.000000)">
|
|
12
|
+
<circle id="椭圆形" fill-opacity="0.2" fill="#141C28" cx="16" cy="16" r="16"></circle>
|
|
13
|
+
<g id="canceled" transform="translate(7.000000, 7.000000)" filter="url(#filter-1)">
|
|
14
|
+
<g>
|
|
15
|
+
<rect id="矩形" x="0" y="0" width="18" height="18"></rect>
|
|
16
|
+
<path d="M4.20533009,3.14466991 L8.978,7.917 L13.7512716,3.14466991 C14.0175382,2.87840335 14.4342019,2.8541973 14.7278134,3.07205176 L14.8119318,3.14466991 C15.104825,3.43756313 15.104825,3.91243687 14.8119318,4.20533009 L14.8119318,4.20533009 L10.038,8.978 L14.8119318,13.7512716 C15.104825,14.0441649 15.104825,14.5190386 14.8119318,14.8119318 C14.5190386,15.104825 14.0441649,15.104825 13.7512716,14.8119318 L8.978,10.038 L4.20533009,14.8119318 C3.93906352,15.0781984 3.52239984,15.1024044 3.22878835,14.88455 L3.14466991,14.8119318 C2.8517767,14.5190386 2.8517767,14.0441649 3.14466991,13.7512716 L3.14466991,13.7512716 L7.917,8.978 L3.14466991,4.20533009 C2.8517767,3.91243687 2.8517767,3.43756313 3.14466991,3.14466991 C3.43756313,2.8517767 3.91243687,2.8517767 4.20533009,3.14466991 Z" id="形状结合" fill="#444444"></path>
|
|
17
|
+
</g>
|
|
18
|
+
</g>
|
|
19
|
+
</g>
|
|
20
|
+
</g>
|
|
21
|
+
</g>
|
|
22
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|