新增绘制海报组件

This commit is contained in:
唐明明
2021-09-29 09:47:20 +08:00
parent b21b8d8dbf
commit 86562924a5
181 changed files with 3983 additions and 32858 deletions

View File

@@ -0,0 +1,78 @@
## 1.0.332021-09-16
修改当绘制文字为空字符串时报x: undefined的问题
## 1.0.322021-08-10
修改一些绘制问题
## 1.0.312021-08-05
修改小程序绘制文字时字体加粗影响后面字体的问题
## 1.0.302021-08-05
外框设置圆角
## 1.0.292021-08-05
[修改] 安卓上面图片不显示的问题
## 1.0.282021-08-05
[修改] 安卓上面图片不显示的问题
## 1.0.272021-08-05
[修改] 安卓上面图片不显示的问题
## 1.0.262021-07-27
紧急,忘记改方法名称了。
## 1.0.252021-07-27
[修改] 绘制文字时callBack ex值的不准缺席
[修改] 绘制图片时,当图片为空时一直停留在绘制状态中的问题
## 1.0.242021-07-22
修改 绘制透明背景的png图片时背景成黑色
## 1.0.232021-07-22
修改 绘制透明背景的png图片时背景成黑色
## 1.0.222021-07-22
...
## 1.0.212021-07-21
...
## 1.0.202021-07-21
绘制文字添加 lastWidth 属性,用于限制行数的时候,最后一行的宽度
绘制矩形,绘制图片添加 borderType属性用于设置圆角方向
## 1.0.192021-07-21
绘制文字添加 lastWidth 属性,用于限制行数的时候,最后一行的宽度
绘制矩形,绘制图片添加 borderType属性用于设置圆角方向
## 1.0.182021-07-10
修复绘制文字传入的内容是Number类型时的错误
## 1.0.172021-07-01
完善文档
## 1.0.162021-07-01
添加示例项目
## 1.0.152021-07-01
添加callBack
## 1.0.142021-07-01
紧急修复因为疏忽导致的问题
修改文档参数
## 1.0.132021-06-30
修改一些很蠢的问题
文字添加首行缩进功能
添加绘制海报示例
## 1.0.122021-06-30
绘制文字添加\n实现自定义换行
## 1.0.112021-06-29
添加绘制二维码功能
添加矩形,圆形,三角形绘制边框功能
## 1.0.102021-06-28
添加 三角形定点朝向
## 1.0.092021-06-27
添加图片设置透明度
## 1.0.082021-06-26
添加实例项目
## 1.0.072021-06-26
添加使用文档
## 1.0.062021-06-25
1、添加图片压缩
2、添加绘制三角形
3、添加绘制三角形图片
4、添加图片旋转矩形旋转。三角形旋转
## 1.0.052021-06-18
添加图片mode模式
## 1.0.042021-06-16
[优化] 绘制canvas的的速度
## 1.0.032021-06-15
使用class重新书写绘制canvas
## 1.0.022021-06-08
## 1.0.012021-06-08
## 1.0.02021-06-08

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
function getLocalFilePath(path) {
if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) {
return path
}
if (path.indexOf('file://') === 0) {
return path
}
if (path.indexOf('/storage/emulated/0/') === 0) {
return path
}
if (path.indexOf('/') === 0) {
var localFilePath = plus.io.convertAbsoluteFileSystem(path)
if (localFilePath !== path) {
return localFilePath
} else {
path = path.substr(1)
}
}
return '_www/' + path
}
export function pathToBase64(path) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
if (typeof FileReader === 'function') {
var xhr = new XMLHttpRequest()
xhr.open('GET', path, true)
xhr.responseType = 'blob'
xhr.onload = function() {
if (this.status === 200) {
let fileReader = new FileReader()
fileReader.onload = function(e) {
resolve(e.target.result)
}
fileReader.onerror = reject
fileReader.readAsDataURL(this.response)
}
}
xhr.onerror = reject
xhr.send()
return
}
var canvas = document.createElement('canvas')
var c2x = canvas.getContext('2d')
var img = new Image
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
c2x.drawImage(img, 0, 0)
resolve(canvas.toDataURL())
canvas.height = canvas.width = 0
}
img.onerror = reject
img.src = path
return
}
if (typeof plus === 'object') {
plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
entry.file(function(file) {
var fileReader = new plus.io.FileReader()
fileReader.onload = function(data) {
resolve(data.target.result)
}
fileReader.onerror = function(error) {
reject(error)
}
fileReader.readAsDataURL(file)
}, function(error) {
reject(error)
})
}, function(error) {
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
wx.getFileSystemManager().readFile({
filePath: path,
encoding: 'base64',
success: function(res) {
resolve('data:image/png;base64,' + res.data)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}
export function base64ToPath(base64) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
base64 = base64.split(',')
var type = base64[0].match(/:(.*?);/)[1]
var str = atob(base64[1])
var n = str.length
var array = new Uint8Array(n)
while (n--) {
array[n] = str.charCodeAt(n)
}
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type })))
}
var extName = base64.match(/data\:\S+\/(\S+);/)
if (extName) {
extName = extName[1]
} else {
reject(new Error('base64 error'))
}
var fileName = Date.now() + '.' + extName
if (typeof plus === 'object') {
var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
bitmap.loadBase64Data(base64, function() {
var filePath = '_doc/uniapp_temp/' + fileName
bitmap.save(filePath, {}, function() {
bitmap.clear()
resolve(filePath)
}, function(error) {
bitmap.clear()
reject(error)
})
}, function(error) {
bitmap.clear()
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
var filePath = wx.env.USER_DATA_PATH + '/' + fileName
wx.getFileSystemManager().writeFile({
filePath: filePath,
data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
encoding: 'base64',
success: function() {
resolve(filePath)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,345 @@
// 路径转base64
import { base64ToPath } from './image-tools'
/**
* base64转本地路径
* @param { String } path 路径
* @returns
*/
export function base64ToPathFn(path) {
let reg =
/^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i
if (!reg.test(path)) {
return Promise.resolve(path)
}
return base64ToPath(path)
}
/**
* 下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径
* @param { String } url 资源路径
* @param { Object } options 回调
* @returns
*/
export function downloadFile(url, options = {
onProgressUpdate: () => {}
}) {
return new Promise(resolve => {
try {
let download = uni.downloadFile({
url,
header: options.header || {},
success(res) {
return resolve({
success: true,
data: res
})
},
fail() {
return resolve({
success: false,
message: `下载资源${url}失败`
})
}
})
// 下载进度回调
download.onProgressUpdate(data => {
options.onProgressUpdate(data)
})
} catch(e) {
return resolve({
success: false,
msg: `下载资源${url}失败`
})
}
})
}
/**
* 加载提示框
* @param { String } title 提示内容
* @param { Boolean } mask 是否显示透明蒙层
*/
export function showLoading(title, mask = true) {
uni.showLoading({
title,
mask
})
}
/**
* 关闭加载提示框
*/
export function hideLoading() {
uni.hideLoading()
}
/**
* 不需要确认提示框
* @param { String } title 提示内容
* @param { Object } options 参数
* @param { Stirng } options.icon 提示图片
* @param { String || Number } options.duration 时效
*/
export function showToast(title, options = {}) {
uni.showToast({
title,
icon: options.icon || "none",
duration: options.duration || 1500,
mask: options.mask || false
})
}
/**
* 保存图片到系统相册。
* @param { String } filePath 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径
* @returns
*/
export function saveImageToPhotosAlbum(filePath) {
return new Promise(resolve => {
showLoading('保存中...')
uni.saveImageToPhotosAlbum({
filePath,
success(res) {
hideLoading()
resolve({
success: true,
data: res.file
})
},
fail(err) {
hideLoading()
resolve({
success: false,
message: err
})
}
})
})
}
/**
* 计算文字长度
* @param { CanvasText } Context canvas对象
* @param { String } text 文本
* @param { String } size 长度
* @returns
*/
export function countTextLength(Context, text, size) {
let textLength = 0
try {
textLength = Context.measureText(text)
} catch(e) {
textLength = {}
}
textLength = textLength && textLength.width ? textLength.width : 0
if (textLength == 0) {
for (let i of text) {
textLength += Context.measureText(text)
}
textLength * size
}
return textLength
}
/**
* 压缩图片 H5不支持
* @param { Object } params
* @param { String } params.src 图片路径,图片的路径,可以是相对路径、临时文件路径、存储文件路径
* @param { String } params.quality 压缩质量范围0100数值越小质量越低压缩率越高仅对jpg有效
* @param { String } params.width 缩放图片的宽度,支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto"即根据height与源图高的缩放比例计算若未设置height则使用源图高度
* @param { String } params.height 缩放图片的高度,支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto"即根据height与源图高的缩放比例计算若未设置height则使用源图高度
* @returns
*/
export function compressImage(params = {}) {
return new Promise(resolve => {
uni.compressImage({
src: params.src || '',
quality: params.quality || 80,
width: params.width || 'auto',
height: params.height || 'auto',
success: res => {
resolve({
success: true,
src: res.tempFilePath
})
},
fail: res => {
resolve({
success: false,
message: '压缩图片失败'
})
}
})
})
}
/**
* 获取图片信息
* @param { String } src 图片地址
*/
export function getImageInfo(src){
return new Promise(resolve =>{
uni.getImageInfo({
src,
success: res => {
let { path } = res
// #ifdef H5
let index = path.lastIndexOf('.', path.length)
let type = ''
if (index != -1) {
type = path.substring(index + 1, path.length)
} else {
type = 'png'
}
res.type = type
// #endif
resolve({
success: true,
...res
})
},
fail: e => {
resolve({
success: false,
msg: e
})
}
})
})
}
/**
* 获取使用模式的图片信息
* @param { String | Number } oWidth 原图宽度
* @param { String | Number } oHeight 原图高度
* @param { String | Number } x x轴位置
* @param { String | Number } y y轴位置
* @param { String | Number } width 宽度
* @param { String | Number } height 高度
* @param { String } mode 模式
* aspectFit 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
* aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
* widthFix 宽度不变,高度自动变化,保持原图宽高比不变
* heightFix 高度不变,宽度自动变化,保持原图宽高比不变
*/
export function getModeImage(oWidth, oHeight, x, y, width, height, mode) {
if (mode == 'aspectFit') {
return getAspectFitModelInfo(oWidth, oHeight, x, y, width, height)
}
if (mode == 'aspectFill') {
return getAspectFillModelInfo(oWidth, oHeight, x, y, width, height)
}
if (mode == 'widthFix') {
return getWidthFixModelInfo(oWidth, oHeight, x, y, width, height)
}
if (mode == 'heightFix') {
return getHeightFixModelInfo(oWidth, oHeight, x, y, width, height)
}
if (mode == 'default') {
return {
dw: width,
dh: height,
dx: x,
dy: y
}
}
return getAspectFillModelInfo(oWidth, oHeight, x, y, width, height)
}
// aspectFit 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
function getAspectFitModelInfo(oWidth, oHeight, x, y, width, height) {
let aspect = oHeight / oWidth
let sw = width
let sh = aspect * sw
if (aspect > 1) {
aspect = oWidth / oHeight
sh = height
sw = aspect * sh
}
return {
sw,
sh,
sx: x,
sy: y,
dw: oWidth,
dh: oHeight,
dx: 0,
dy: 0
}
}
// 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
function getAspectFillModelInfo(oWidth, oHeight, x, y, width, height) {
// 高比宽大 宽是短边
let aspect = oHeight / oWidth
let sw = width
let sh = aspect * sw
let dx = 0
let dy = (sh - height) / 2
if (aspect < 1) {
// 高比宽小 高是短边
aspect = oWidth / oHeight
sh = height
sw = aspect * sh
dy = 0
dx = (sw - width) / 2
}
return {
sw,
sh,
sx: x,
sy: y,
dw: oWidth,
dh: oHeight,
dx,
dy
}
}
// 宽度不变,高度自动变化,保持原图宽高比不变
function getWidthFixModelInfo(oWidth, oHeight, x, y, width, height) {
let aspect = oHeight / oWidth
let sw = width
let sh = sw * aspect
let dx = 0
let dy = 0
return {
sw,
sh,
sx: x,
sy: y,
dw: oWidth,
dh: oHeight,
dx,
dy
}
}
// 高度不变,宽度自动变化,保持原图宽高比不变
function getHeightFixModelInfo(oWidth, oHeight, x, y, width, height) {
let aspect = oWidth / oHeight
let sh = height
let sw = sh * aspect
let dx = 0
let dy = 0
return {
sw,
sh,
sx: x,
sy: y,
dw: oWidth,
dh: oHeight,
dx,
dy
}
}

View File

@@ -0,0 +1,83 @@
{
"id": "sakura-canvas",
"displayName": "canvas绘制海报(分享图) ",
"version": "1.0.33",
"description": "支持JSON格式绘制海报。内置拥有许多的封装方法便于你更快绘制",
"keywords": [
"uni_modules",
"canvas",
"绘制海报",
"分享图"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "y",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "u"
}
}
}
}
}

View File

@@ -0,0 +1,478 @@
# sakura-canvas(海报生成器)
# 用前需知:
## 1、小程序绘制时记得配置图片的域名为安全域名(白名单)
## 2、兼容性。目前只测试过APP(不包括NVUE页面), 微信小程序, H5, 字节跳动小程序。其他小程序未测。
# 引入
```javascript
import Draw from '@/uni_modules/sakura-canvas/js_sdk/draw'
```
# 使用教程
## 初始化
```javascript
let draw = new Draw({
width: 375, // canvas(海报)的宽度 必填
height: 500, // canvas(海报)的高度 必填
canvasId: 'myCanvas', // canvasId 必填
_this: this, // 传入this实例 必填
background: {
type: 'color', // 背景样式 color: 纯色 image: 图片
color: '#fffff',
// color: 参数详看绘制矩形的参数
// image: 详看绘制图片时的参数
}, // 背景 默认纯白,
drawDelayTime: 200, // 绘制海报时的延迟时间(单位毫秒),默认200,
delayTime: 200, // 导出图片时的延迟时间(单位毫秒),默认200,
fileType: 'png', // 导出图片的类型, 默认png 可选jpg, png
quality: 1, // 导出图片的质量, 默认1 值范围0~1, 大于一都为1处理
drawTipsText: '绘制中...', // 绘制时的加载提示, 默认绘制中...
})
```
## Draw类内置方法大纲
# 非Json方式绘制
## 绘制文本-text
# !!!注意绘制文本添加使用\n实现自定义换行
```javascript
// 绘制文字
draw.drawText({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
w: 100, // 文字宽度 默认整个画布的宽度 - x轴的距离
text: '你好\n世界', // 文字内容
textIndent: 0, // 文字首行缩进 默认0 注意在设置了windowAlign或者textAlign的时候会失去作用
font: {
size: 12, // 文字大小 默认12
family: '微软雅黑', // 文字字体 默认sans-serif
style: 'normal', // 文字样式 默认 normal 可选: italic: 斜体 oblique: 倾斜体
weight: 'normal' // 文字粗体 默认 normal 可传递 bold: 粗体 数字
},
line: {
num: -1, // 限制文字行数,默认 -1: 不限制 限制行数,多出部分会变成...
height: 16, // 行高默认16
style: 'none', // 样式 默认none: 不需要 可选 underline: 下划线, lineThrough 删除线
type: 'solid', // 线类型 当使用样式时线的类型 默认: solid 实线 可选: dashed 虚线
width: 1, // 线宽度 默认1
},
color: '#000000', // 文字颜色 默认#000000 在不考虑字节跳动小程序的前提下可简写(#000)
alpha: 1, // 透明度 默认1 取值范围 0~1
isFill: true, // 是否是填充字体, false: 线性字体
windowAlign: 'none', // 文字在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
textAlign: 'none', // 文字水平对齐的方式 默认: none 可选 居中: center 右边: right
})
```
## 绘制矩形-rect
```javascript
// 绘制矩形
draw.drawRect({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
w: 100, // 宽度 必填
h: 100, // 高度 必填
r: 0, // 矩形圆角大小 默认: 0
color: '#000000', // 颜色 默认#000000 在不考虑字节跳动小程序的前提下可简写(#000)
alpha: 1, // 透明度 默认1 取值范围 0~1
isFill: true, // 是否是填充矩形, false: 线性矩形
lineWidth: 1, // 当矩形为线性时,矩形的边框宽度
windowAlign: 'none', // 矩形在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
// 旋转
rotate: {
deg: 0, // 旋转角度
type: 'middle', // 旋转的中心点 默认: middle: 矩形正中心
// topLeft: 中心点在上左 topMiddle 中心点在上中 topRight 中心点在上右
// middleLeft: 中心点在中左 bottomMiddle 中心点在正中间 middleRight 中心点在中右
// bottomLeft: 中心点在下左 bottomMiddle 中心点在下中 middleRight 中心点在下右
},
borderWidth: 0, // 边框大小 默认0 (类型为填充矩形时生效)
borderColor: '#ffffff', // 边框颜色 默认无颜色 (类型为填充矩形时生效)
// 圆角的方向
// 值类型为数组, 添加不同的圆角方向设置哪里是圆角哪里不是圆角
// 参数可选值 tr: 上右; tl: 上左; bl:左下; br: 左右; default: 全圆角
borderType: ['tr', 'tl'] // 默认全圆角['default']
})
```
## 绘制圆-arc
```javascript
// 绘制圆
draw.drawArc({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
r: 100, // 圆半径 必填
s: 0, // 画圆的起始角度
e: Math.PI * 2, // 画圆的终止角度
d: false, // 指定弧度的方向是逆时针还是顺时针。默认是false即顺时针。
color: '#000000', // 颜色 默认#000000 在不考虑字节跳动小程序的前提下可简写(#000)
alpha: 1, // 透明度 默认1 取值范围 0~1
isFill: true, // 是否是填充圆, false: 线性圆
lineWidth: 1, // 当圆为线性时,圆的边框宽度
windowAlign: 'none', // 圆在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
borderWidth: 0, // 边框大小 默认0 (类型为填充圆时生效)
borderColor: '#ffffff' // 边框颜色 默认无颜色 (类型为填充圆时生效)
})
```
## 绘制三角形-triangle
```javascript
// 绘制三角形
draw.drawTriangle({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
w: 100, // 宽度 必填
h: 100, // 高度 必填
r: 0, // 矩形圆角大小 默认: 0
color: '#000000', // 颜色 默认#000000 在不考虑字节跳动小程序的前提下可简写(#000)
alpha: 1, // 透明度 默认1 取值范围 0~1
isFill: true, // 是否是填充三角形, false: 线性三角形
lineWidth: 1, // 当三角形为线性时,三角形的边框宽度
drawType: 'isosceles', // 绘制的三角形类型 默认 isosceles: 等腰三角形 right: 直角三角形 custom: 自定义自定义时x, y, 宽, 高都不需要传递。需要传递绘制点的坐标类型是数组(coordinate)
// 三角形定点朝向 top, left, right, bottom (只在等腰三角形和直角三角形里生效,自定义绘制不生效)
direction: params.direction || 'top',
coordinate: [], // 当绘制类别是自定义的时候需要传递的参数[[x1, y1], [x2, y2], [x3, y3]]
windowAlign: 'none', // 三角形在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right (并且三角形类型不能为自定义)
// 旋转
rotate: {
deg: 0, // 旋转角度
type: 'middle', // 旋转的中心点 默认: middle: 三角形正中心
// top: 上 left: 左 right: 右 middle: 中心
},
borderWidth: 0, // 边框大小 默认0 (类型为填充三角形时生效)
borderColor: '#ffffff' // 边框颜色 默认无颜色 (类型为填充三角形时生效)
})
```
## 绘制线条-line
```javascript
// 绘制线条
draw.drawLine({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
w: 100, // 宽度 默认整个画布的宽度 - x轴的距离
color: '#000000', // 颜色 默认#000000 在不考虑字节跳动小程序的前提下可简写(#000)
alpha: 1, // 透明度 默认1 取值范围 0~1
lineType: 'solid', // 线条类型 默认 solid: 实线 可选 dashed: 虚线
pattern: [5, 5], // 当线条类型为虚线是生效具体详看CanvasContext.setLineDash文档
offset: 5, // 虚线偏移量 默认: 5
lineWidth: 1, // 线条高度
lineCap: 'butt', // 线条端点样式 默认 butt 可选 round, square
windowAlign: 'none', // 线条在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
})
```
## 绘制图片-image
```javascript
// 绘制图片
await draw.drawImage({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
w: 100, // 图片宽度 必填
h: 100, // 图片高度 必填
r: 0, // 当图片样式为矩形时, 圆角的大小
alpha: 1, // 透明度 默认1 取值范围 0~1
src: '/static/logo.png', // 图片资源路径 必填 网络路径(小程序中需要配置白名单),本地路径, base64(使用base64格式绘制速度会稍微慢点在IOS端显著。)
mode: 'aspectFill', // 图片模式 默认 aspectFill 可选 aspectFit, widthFix, heightFix
drawType: 'default', // 图片样式 default: 默认 rect: 矩形, arc: 圆形 triangle: 三角形
triangle: {
type: 'isosceles', // 三角形的类型 right: 直角三角形 isosceles: 等腰三角形 custom: 自定义三角形(不支持旋转)
coordinate: [], // 自定义时传递, [[x1, y1], [x2, y2], [x3, y3]],
triangle: 'top', // 三角形顶点朝向
}, // 绘制三角形时传递
borderWidth: 0, // 图片边框大小
borderColor: '#ffffff', // 图片边框颜色
// 图片圆角的方向
// 值类型为数组, 添加不同的圆角方向设置哪里是圆角哪里不是圆角
// 参数可选值 tr: 上右; tl: 上左; bl:左下; br: 左右; default: 全圆角
borderType: ['tr', 'tl'], // 默认全圆角['default']
windowAlign: 'none', // 图片在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
quality: 80, // 压缩图片的质量 默认 80 值范围0~100
rotate: {}, // 旋转 具体可看绘制矩形和绘制三角形中的属性值
})
```
## 绘制二维码
```javascript
// 绘制二维码
draw.drawQrCode({
x: 0, // x轴方向 默认 0
y: 0, // y轴方向 默认 0
size: 100, // 二维码的大小 默认100
text: '', // 二维码内容 默认''
background: '#000000', // 二维码背景色 默认#00000
foreground: '#ffffff', // 二维码前景色 默认#fffff
pdground: '#ffffff', // 二维码角标色 默认 #fffff
lv: 3, // 容错级别(一般不需要调它) 默认值是3
windowAlign: 'none', // 二维码在窗口(整个画布的宽度)对齐的方式 默认: none 可选 居中: center 右边: right
// 二维码中间的图片 可选
image: {
src: '/static/logo.png', //网络路径(小程序中需要配置白名单),本地路径, base64(使用base64格式绘制速度会稍微慢点在IOS端显著。)
size: 30, // 图片大小 默认 30
r: 0, // 图片圆角 默认 0
borderWidth: 0, // 图片边框大小 默认0
borderColor: '#ffffff' // 图片边框颜色 默认无颜色
}
})
```
## 自定义绘制-custom
### 具体详看Context文档 [点我跳转](https://uniapp.dcloud.io/api/canvas/CanvasContext)
```javascript
// 自定义绘制
draw.Context.fillText('你好', 0, 200)
```
## 将通过以上方法绘制的内容绘制到画板上
```javascript
// complete 是否导出图片,默认 true会绘制图片并返回图片路径 false时需要自行调用uni.canvasToTempFilePath()方法导出图片
await draw.canvasDraw(complete)
```
# Json方式绘制内容(推荐使用Json方式绘制)
```javascript
// bgObj: 背景大小含有背景宽高
// ctxObj: 画布大小含有画布宽高
// res接收参数格式
// res.success: 是否成功 true: 成功 false: 失败
// res.message: 成功或者失败时的信息
// res.data: 成功时绘制的图片路径
let res = await draw.createdSharePoster(({ bgObj, ctxObj }) => {
let data = [
// 绘制文字
{
name: '', // 用于在callBack中寻找
type: 'text',
// callBack: 用于知道上一次绘制的内容具体的数据
// before: 上一次绘制的内容的数据,当你绘制的内容处于第一个则是一个空对象
// all: 所有绘制内容的数据
callBack: (before, all) => {
let { sx, sy, ex, ey, w, h } = before
// sx: 上一次绘制内容开始的x轴位置
// sy: 上一次绘制内容开始的y轴位置
// ex: 上一次绘制内容结束的x轴位置
// ey: 上一次绘制内容结束的y轴位置
// w: 上一次绘制内容的宽度
// h: 上一次绘制内容的高度
// callBack 返回的对象会覆盖原属性
return {
x: sx,
y: sy
}
}
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawText 方法的参数
},
// 绘制矩形
{
type: 'rect',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawRect 方法的参数
},
// 绘制圆
{
type: 'arc',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawArc 方法的参数
},
// 绘制三角形
{
type: 'triangle',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawTriangle 方法的参数
},
// 绘制线条
{
type: 'line',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawLine 方法的参数
},
// 绘制图片
{
type: 'image',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawImage 方法的参数
},
// 绘制二维码
{
type: 'qrcode',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawQrCode 方法的参数
},
// 自定义绘制
{
type: 'custom',
zIndex: 0, // 绘制顺序 越小越先绘制
// Context: 调用原生方法绘制
// _this: 调用draw类的内置方法绘制
setDarw(Context, _this) {
// 原生方法绘制
Context.fillText('你好', 0, 200)
// 使用draw类内置方法绘制
_this.drawText({
x: 0,
y: 0,
text: '你好, 世界'
})
}
}
]
return data
})
```
# 绘制时,需要提前绘制一部分内容,然后后面等数据有了在绘制一部分内容的需求
```javascript
// 初始化
let draw = new Draw({
width: 375, // canvas(海报)的宽度,
height: 500, // canvas(海报)的高度,
canvasId: 'myCanvas', // canvasId 必填
_this: this, // 传入this实例 必填
drawDelayTime: 200, // 绘制海报时的延迟时间(单位毫秒),默认200,
delayTime: 200, // 导出图片时的延迟时间(单位毫秒),默认200,
fileType: 'png', // 导出图片的类型, 默认png 可选jpg, png
quality: 1, // 导出图片的质量, 默认1 值范围0~1, 大于一都为1处理
drawTipsText: '绘制中...', // 绘制时的加载提示, 默认绘制中...
})
// 预绘制需要自行调用绘制背景
await draw.preDrawBackground()
// draw.preDraw(drawArray), complete)
// 参数
// drawArray: 参数如下
// complete: 是否绘制完成,绘制完成会自行导出图片 默认false
// 返回值
// res接收参数格式
// res.success: 是否成功 true: 成功 false: 失败
// res.message: 成功或者失败时的信息
// res.data: 成功时绘制的图片路径
let res = await draw.preDraw(({ bgObj, ctxObj }) => {
let data = [
// 绘制文字
{
type: 'text',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawText 方法的参数
},
// 绘制矩形
{
type: 'rect',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawRect 方法的参数
},
// 绘制圆
{
type: 'arc',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawArc 方法的参数
},
// 绘制三角形
{
type: 'triangle',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawTriangle 方法的参数
},
// 绘制线条
{
type: 'line',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawLine 方法的参数
},
// 绘制图片
{
type: 'image',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawImage 方法的参数
},
// 绘制二维码
{
type: 'qrcode',
zIndex: 0, // 绘制顺序 越小越先绘制
// 参数详看draw.drawQrCode 方法的参数
},
// 自定义绘制
{
type: 'custom',
zIndex: 0, // 绘制顺序 越小越先绘制
// Context: 调用原生方法绘制
// _this: 调用draw类的内置方法绘制
setDarw(Context, _this) {
// 原生方法绘制
Context.fillText('你好', 0, 200)
// 使用draw类内置方法绘制
_this.drawText({
x: 0,
y: 0,
text: '你好, 世界'
})
}
}
]
return data
})
```