第一种:适用于各种canvas
// https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742274&di=5497f461b1a60344f896498712586e7c&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F04543555484f5a0000019ae9ceafb9.jpg
// https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742270&di=8efd74b4992000bde9dfe10431499406&imgtype=0&src=http%3A%2F%2Fimages.movie.xunlei.kankan.com%2Fgallery%2F1454%2Fa81c449bf9860b5638021cf906019686.jpg
// https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742269&di=36e1084ee4ec6d4b2314cf3422db46b8&imgtype=0&src=http%3A%2F%2Fdata.whicdn.com%2Fimages%2F157788811%2Flarge.jpg
// https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742269&di=fb8e324d0fb91200af7e14cb7f1c5cbe&imgtype=0&src=http%3A%2F%2Fimg0.pconline.com.cn%2Fpconline%2F1312%2F05%2F3944596_2917_thumb.jpg
// http://img5.duitang.com/uploads/item/201312/05/20131205172503_Q5ivC.jpeg
export default {
name: 'Share',
data () {
return {
imgUrl: ['https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742274&di=5497f461b1a60344f896498712586e7c&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F04543555484f5a0000019ae9ceafb9.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742270&di=8efd74b4992000bde9dfe10431499406&imgtype=0&src=http%3A%2F%2Fimages.movie.xunlei.kankan.com%2Fgallery%2F1454%2Fa81c449bf9860b5638021cf906019686.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742269&di=36e1084ee4ec6d4b2314cf3422db46b8&imgtype=0&src=http%3A%2F%2Fdata.whicdn.com%2Fimages%2F157788811%2Flarge.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547528742269&di=fb8e324d0fb91200af7e14cb7f1c5cbe&imgtype=0&src=http%3A%2F%2Fimg0.pconline.com.cn%2Fpconline%2F1312%2F05%2F3944596_2917_thumb.jpg'
],
width: wx.getSystemInfoSync().windowWidth * 9 / 10,
height: "2000rpx",
shujv: "6546464a65sd4asd快乐就lsakhkdljashkljhaskjldhkKLhjkjlaxshdfkjlashld;kash;kdhaslk;dhaskjdhkalsjdhklasjdh;lksah好是看得见哈克龙金沙看见类似的哈萨克吉利帝豪昆仑决安徽省asd"
}
},
methods: {
test () {
}
},
mounted () {
const that = this
function getImageInfoMethods (_getimgUrl) {
console.log(_getimgUrl)
return new Promise((relove, reject) => {
wx.getImageInfo({
src: _getimgUrl,//服务器返回的带参数的小程序码地址
success: function (res) {
//res.path是网络图片的本地地址
relove(res)
}
})
})
}
async function imgInfo (imgUrl) {
const leng = imgUrl.length
let _imgInfo = []
for (let i = 0; i < leng; i++) {
console.log(i)
await getImageInfoMethods(imgUrl[i]).then(res => {
console.log(res)
_imgInfo.push(res)
})
if (i === leng - 1) {
return _imgInfo
}
}
}
// function imgInfo (imgUrl) {
// return new Promise((relove, reject) => {
// const leng = imgUrl.length
// let _imgInfo = []
// for (let i = 0; i < leng; i++) {
// wx.getImageInfo({
// src: imgUrl[i],//服务器返回的带参数的小程序码地址
// success: function (res) {
// //res.path是网络图片的本地地址
// _imgInfo.push(res)
// if (i === leng - 1) {
// relove(_imgInfo)
// }
// }
// })
// }
// })
// }
// res.map(a => {
// wx.saveImageToPhotosAlbum({
// filePath: a.path,
// success: res => {
// console.log(res)
// }
// })
// })
function drawText (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
//第一个参数是canvas实例,第二个是要画的字符串,第三四为起点坐标 ,第五个是距离顶部的位置,最后一个是canvas的宽度
var lineWidth = 0;
var lastSubStrIndex = 0; //每次开始截取的字符串的索引
for (let i = 0; i < str.length; i++) {
lineWidth += ctx.measureText(str[i]).width;
if (lineWidth > canvasWidth) {
ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
initHeight += 30; //18为字体的高度
lineWidth = 0;
lastSubStrIndex = i;
titleHeight += 30;
}
if (i == str.length - 1) { //绘制剩余部分
ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
}
}
// 标题border-bottom 线距顶部距离
titleHeight = titleHeight + 10;
return titleHeight
}
imgInfo(this.imgUrl).then(res => {
const ctx = wx.createCanvasContext('shareCanvas')
res.map((a, index) => {
let _width = that.width * 5 / 100 + (index - 1) * that.width * 3 / 10;
let _height = that.width * 9 / 10 + 30;
console.log(_height)
if (index === 0) {
ctx.drawImage(a.path, that.width * 5 / 100, that.width * 5 / 100, that.width * 9 / 10, that.width * 9 / 10)
} else {
//ctx.setStrokeStyle('rgba(248,248,248,1)')
// ctx.strokeRect(_width ,_height, that.width * 3/ 10, that.width * 3/ 10)
ctx.drawImage(a.path, _width, _height, that.width * 3 / 10, that.width * 3 / 10)
}
if (index === res.length - 1) {
_width = _width + that.width * 3 / 10 - 80
let zitiH = _height + that.width * 3 / 10 + 30
ctx.font = 'normal bold 16px PingFangSC';
ctx.fillText('雅诗兰黛6色腮红修容彩妆盘', 20, zitiH)
zitiH = zitiH + 34
ctx.setFillStyle('#FD2951')
ctx.font = 'normal 400 12px PingFangSC'
ctx.fillText('¥', 20, zitiH)
ctx.font = 'normal bold 16px PingFangSC'
ctx.fillText('999', 34, zitiH)
ctx.font = 'normal bold 14px PingFangSC'
ctx.beginPath()
ctx.moveTo(83, zitiH - 6)
ctx.lineTo(120, zitiH - 6)
ctx.stroke()
ctx.setFillStyle('#999999')
ctx.fillText('¥999', 80, zitiH - 1)
zitiH += 40
ctx.setFillStyle('#333333')
ctx.font = 'normal 400 12px PingFangSC'
ctx.fillText(`规 格: 5g*6`, 20, zitiH)
ctx.fillText(`款 式:`, 20, zitiH + 25)
console.log(zitiH)
zitiH = drawText(ctx, that.shujv, 68, zitiH + 25, zitiH, that.width * 8.5 / 10 - 68) //使用drawText方法进行行,返回值是距离顶部的高度
console.log(zitiH)
}
})
ctx.draw()
})
// wx.getImageInfo({
// src: this.imgUrl[0],//服务器返回的带参数的小程序码地址
// success: function (res) {
// //res.path是网络图片的本地地址
// console.log(res)
// const ctx = wx.createCanvasContext('shareCanvas')
// ctx.drawImage(res.path, 0, 0, 250, 250)
// ctx.stroke()
// ctx.draw()
// console.log(ctx)
// const that = this
// setTimeout(function () {
// wx.canvasToTempFilePath({
// x: 0,
// y: 0,
// width: 200,
// height: 370,
// destWidth: 1035,
// destHeight: 1560,
// canvasId: 'shareCanvas',
// success: function (res) {
// console.log(res, '保存')
// //保存到手机相册
// wx.saveImageToPhotosAlbum({
// filePath: res.tempFilePath,
// success: res => {
// console.log(res)
// }
// })
// }
// })
// }, 1000)
// },
// fail: function (res) {
// //失败回调
// }
// })
}
}
.qweasd {
width: 100rpx;
height: 100rpx;
background: red;
position: fixed;
top: 1rpx;
left: 1rpx;
z-index: 99999999999999999999999999999999999999999;
}
第二种:使用环境 mpvue ---转载
npm i vnode2canvas --save
First of all, you need to register vnode2Canvas
import Vue from 'vue'
import vnode2Canvas from 'vnode2Canvas'
Vue.use(vnode2Canvas)
vnode2Canvas
will render canvas by function renderCanvas
option:
export default {
// define render options
canvasOptions: {
width: window.innerWidth, // canvas width
height: window.innerHeight // canvas height
},
renderCanvas (createElement) {
// ....
}
}
after that vnode2Canvas
will register a property named renderInstance
on vue instance:
renderInstance = {
_ctx
_canvas
...
}
A rolling list based on scroller to support lazy list loading.
usage:
new Vue({
el: '#app',
data: {
dataJSON: [
// ...
]
},
methods: {
getStyle (type, i) {
return {
img: {
left: 10,
top: 10 + 110 * i,
width: 100,
height: 100,
fill: '#000'
},
title: {
left: 120,
top: 10 + 110 * i,
fill: '#000',
fontSize: 18,
width: 150,
ellipse: true
},
desc: {
left: 120,
top: 50 + 110 * i,
fill: '#999'
},
date: {
left: 120,
top: 80 + 110 * i,
fill: '#999'
}
}[type]
}
},
canvasOptions () {
return {
width: window.innerWidth,
height: window.innerHeight
}
},
renderCanvas(h) {
return h('scrollView', {
style: {
scrollHeight: this.dataJSON.length * 110,
width: window.innerWidth,
height: window.innerHeight
}
}, this.dataJSON.map((item, i) => {
return h('view',
[
h('image', {
props: {
src: item.img
},
style: this.getStyle('img', i)
}),
h('text', {
style: this.getStyle('title', i),
}, item.title),
h('text', {
style: this.getStyle('desc', i)
}, item.desc),
h('text', {
style: this.getStyle('date', i)
}, new Date().toLocaleDateString())
])
}))
}
})
Support the following events:
click
mouseup
mousedown
usage
// ...
renderCanvas(h) {
return h('view', {
on: {
click: (e, item) => {
alert('click Text')
}
}
},
'click event'
)
}
// ...
If you think write CSS in JS is not comfortable, you can also load your external CSS file through a webpack loader.
canvas-style-loader
// webpack
const canvasStyleLoader = require('canvas-style-loader')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
// To avoid conflicts with CSS styles, you need to specify loading paths.
include: [
path.join(__dirname, './src')
],
use: {loader: 'canvasStyleLoader'}
}
]
}
};
// index.css
image {
left: 10px;
width: 100px;
height: 100px;
}
.title {
left: 120px;
width: 100px;
height: 100px;
fill: "#000";
font-size: 18px;
}
.desc {
left: 120px;
fill: '#999'
}
.date {
left: 120px;
fill: '#999'
}
import './index.css'
// ...
renderCanvas(h) {
return h('view', this.dataJSON.map((item, i) => {
return h('view', [
h('image', {
props: {
src: item.img
},
style: {
top: 10 + 110 * i
}
}),
h('text', {
class: 'title',
style: {
top: 10 + 120 * i
}
}, item.title),
h('text', {
class: 'desc',
style: {
top: 50 + 120 * i
}
}, item.desc),
h('text', {
class: 'date',
style: {
top: 80 + 110 * i,
}
}, new Date().toLocaleDateString())
])
}))
}