微信小程序canvas画图--海报图

34 篇文章 0 订阅
7 篇文章 0 订阅

第一种:适用于各种canvas

<template>

<div>

<div class="qweasd">

 

</div>

<div style="width:100%; ">

<canvas canvas-id="shareCanvas"

style="margin:0 auto;margin-top:100rpx;boder-radius:10rpx;background:rgba(255,255,255,1);"

:style=" { width:width+'px',height:height}">

</canvas>

</div>

<button @click="test">保存图片到手机相册</button>

</div>

</template>

 

<script>

// 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) {

// //失败回调

// }

// })

}

}

</script>

 

<style lang="scss">

.qweasd {

width: 100rpx;

height: 100rpx;

background: red;

position: fixed;

top: 1rpx;

left: 1rpx;

z-index: 99999999999999999999999999999999999999999;

}

</style>


 

 

第二种:使用环境 mpvue  ---转载

npm i vnode2canvas --save

use in Vue

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
  ...
}

1. render scroll list

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())
      ])
    }))
  }
})

2. events

Support the following events:

  1. click
  2. mouseup
  3. mousedown
  4. to be continue...

usage

  // ...
  renderCanvas(h) {
    return h('view', {
        on: {
          click: (e, item) => {
            alert('click Text')
          }
        }
      },
      'click event'
    )
  }
  // ...

3. use css file for webpack loader

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())
    ])
  }))
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值