功能点
添加图片
由于画板上会有很多图片元素,并且我们需要对每个元素设置不同对圆角以及透明度,所以我们需要在添加图片的时候给当前元素生成一个唯一ID来标示它,并且把它的所有配置属性存储。
图片源
1 | /** |
圆角
主要使用图片的
clipTo
的回调函数,我们可以在当前函数对当前图片画圆arc
.这里其实就是canvas的arc函数。1.6
1 ctx => ctx.arc(0, 0, this.radius[img.id].val, 0, Math.PI * 2, true)
透明度
这里只要设置当前选择图片的style(opacity)即可,然后再重新render画板。
1.6
1
2
3
4
5
6
7
8
9
10
11 setActiveStyle (style) {
const object = this.canvas.getActiveObject();
if (!object) return;
if (object.setSelectionStyles && object.isEditing) {
object.setSelectionStyles(style);
} else {
Reflect.ownKeys(style).forEach(item => object.set(item, style[item]));
}
object.setCoords();
this.canvas.requestRenderAll();
}
添加文字
这里采用fabric的
IText
函数创建一个文本控件。1.6
1
2
3
4
5
6
7
8
9
10
11 addText (content = 'text', options = {}) {
const text = new fabric.IText(content, Object.assign(this.optionsOfType('i-text'), {
left: this.canvas.width / 2,
top: this.canvas.height / 2,
fill: '#000000',
scaleX: 0.5,
scaleY: 0.5,
hasRotatingPoint: true
}, options));
this.addAndSelect(text);
}
透明
与图片透明度一样,设置
opacity
样式即可。
字体
需要设置控件属性
fontFamily
。目前实现的字体:’Arial’, ‘Helvetica’, ‘宋体’, ‘黑体’, ‘微软雅黑’, ‘楷体’, ‘仿宋’, ‘Verdana’, ‘Times New Roman’, ‘Roboto’, ‘Open Sans’, ‘Lato’, ‘Bellefair’, ‘Fresca’, ‘Raleway’
大小
设置控件属性
fontSize
对齐方式
设置控件属性
textAlign
:left、center、right、justify
颜色
使用第三方选择颜色组件:
vue-color
中的Sketch
具体去npm查看。获取rgba。设置控件的fill
样式即可。
字体样式
- 粗体 - 设置属性
fontWeight
为blob
或者normal
- 斜体 - 设置属性
fontStyle
为italic
或者normal
- 下划线 - 设置属性
underline
为true
或者false
- 删除线 - 设置属性
linethrough
为true
或者false
- 上划线 - 设置属性
overline
为true
或者false
行高
设置控件属性:
lineHeight
层级移动
上移
获取当前选择控件调用控件
bringToFront
函数下移
获取当前选择控件调用控件
sendToBack
函数背景图片
与添加图片一样可以从多种数据源添加。
1.6 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32setBackgroundImage (img, opt = {}) {
const { _radius, _resizeMode, _opacity } = opt;
// 获取图片最大的半径
this.backgroundImageRadiusMax = this.imageMaxRange(img);
// 设置图片当前圆角半径
this.backgroundImageRadius = _radius || this.backgroundImageRadiusMax;
// 设置当前图片填充模式
this.backgroundImageResizeMode = _resizeMode || this.backgroundImageResizeMode;
// 根据当前画布大小适配图片比例
const { width, height } = this.canvas;
const scaleX = width / img.width;
const scaleY = height / img.height;
if (this.backgroundImageResizeMode === ResizeMode.stretch) {
// 如果上拉伸填充则不保持百分比直接按画布比例缩放
img.set({ scaleX, scaleY, left: 0, top: 0 });
} else {
// 如果以覆盖整个画布填充则按照最大的画布比例缩放图片宽高,反之为画布的最小比例缩放。
const isCover = this.backgroundImageResizeMode === ResizeMode.cover;
const scale = isCover ? Math.max(scaleX, scaleY) : Math.min(scaleX, scaleY);
img.scale(scale).set({
left: width / 2 - img.width * scale / 2,
top: height / 2 - img.height * scale / 2
});
}
this.canvas.setBackgroundImage(img, this.canvas.renderAll.bind(this.canvas), {
originX: 'left',
originY: 'top',
opacity: _opacity || 1,
clipTo: ctx => ctx.arc(0, 0, this.backgroundImageRadius, 0, Math.PI * 2, true)
});
this.currentBackgroundImg = img;
}
背景颜色
1 | this.canvas.setBackgroundColor(this.rgba, this.canvas.renderAll.bind(this.canvas)); |
删除元素
获取当前控件,从画布中删除
1.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 removeActive () {
const active = this.canvas.getActiveObject();
if (active) {
this.remove(active);
} else {
const objects = this.canvas.getActiveObjects();
this.canvas.discardActiveObject(null);
objects.forEach(object => this.remove(object));
}
}
remove (obj) {
if (obj && obj._remove !== false) {
this.canvas.remove(obj);
Reflect.deleteProperty(this.radius, obj.id);
}
}
保存&导出
1 | async save () { |
加载数据
1 | async loadJSON (val) { |
哎,本人懒人病发了,后面的直接贴代码了,如有不明之处或错误地方可以在当前页面评论交流,或Github issue。
为了使用方便,已上传npm
muse-ui-fabric