wxml:
  

<view  catchtouchmove="preventTouchMove" wx:if="{{canvas_haoBao}}">
  <view class='warp_' style="overflow-y: scroll;">
      <view style='' style='position: absolute;z-index: 2;webkit-transform: translate(-50%,-50%);transform: translate(-50%,-50%);top: 50%;left: 50%;'>
          <canvas canvas-id="myCanvass" style="width:750rpx;height:1100rpx;" />
          <view style='padding-bottom: 0;box-sizing: border-box;width:100%'>
              <!-- <view class='note'>已保存到相册,快去分享给好友吧</view> -->
              <view bindtap='saveImg' class='btn'>保存到手机相册</view>
          </view>
          <view class='canvas_close_' catchtap='isShowHaoBao' style="position: absolute;top: -30rpx;right: 30rpx;">×</view>
      </view>
      <view class='pop_bg_fix'></view>
  </view>
</view>
 
wxss:
.warp_ .btn{width: 68%;height: 88rpx;line-height: 88rpx;font-size: 28rpx;border-radius: 90rpx;background: #e8474d;text-align: center;color: #fff;margin: auto;}
.warp_ image{border-radius: 0 !important;}
.warp_ .note{text-align: center;color: #fff;margin-bottom: 28rpx;font-size: 28rpx;margin-top: 60rpx;}
.pop_bg_fix{position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background: rgba(0, 0, 0, .6);}
.warp_{width: 100vw;height: 100vh;box-sizing: border-box;line-height: 1.5;position: fixed;top: 0;left: 0;z-index: 9999991;}
.canvas_close_{margin: 30rpx auto 0;width: 50rpx;height: 50rpx;background: #999;text-align: center;line-height: 50rpx;font-size: 50rpx;color: #fff;border-radius: 50%;}
image{width: 100%;height: 100%;}
 
wxjs:
 
Page({
onLoad: function (options) {
    this.canvasImg() 
  },
canvasImgs() {
    let that = this;
    var res = wx.getSystemInfoSync()
    var rpx = res.windowWidth / 375
    console.log(rpx)
    that.setData({
      rpx: res.windowWidth / 375
    })
    const ctx = wx.createCanvasContext('myCanvass');
    //ctx.setFillStyle('#5c8ef3'); //为创建的canvans上下文添充颜色  如果没有设置 fillStyle,默认颜色为 black。
    // ctx.fillRect(0, 10 * rpx, 750 * rpx, 600 * rpx)
    // ctx.drawImage(this.data.img,  0 * rpx, 0 * rpx, 266 * rpx, 133 * rpx);
    ctx.save(); // 先保存状态 已便于画完圆再用
    // 制作圆角矩形
    // this.roundRect(ctx, 10 * rpx, 20 * rpx, 355 * rpx, 540 * rpx, 10 * rpx);
    // this.roundRect(ctx, 10 * rpx, 500 * rpx, 355 * rpx, 10 * rpx, 20 * rpx);  
    // ctx.drawImage(this.data.img, 0 * rpx, 130 * rpx, 266 * rpx, 130 * rpx);
    //二维码
    ctx.drawImage("/image/gonglue_pic5.png", 55 * rpx, 40 * rpx, 260 * rpx, 420 * rpx);
    //底部
    this.roundRect(ctx, 55 * rpx, 460 * rpx, 260 * rpx, 60 * rpx, 0 * rpx);
    var avatarurl_width = 45 * rpx;    //绘制的头像宽度
    var avatarurl_heigth = 45 * rpx;   //绘制的头像高度
    var avatarurl_x = 65 * rpx;   //绘制的头像在画布上的位置
    var avatarurl_y = 466 * rpx;   //绘制的头像在画布上的位置
    ctx.save();
    ctx.beginPath(); //开始绘制
    //先画个圆   前两个参数确定了圆心 (x,y) 坐标  第三个参数是圆的半径  四参数是绘图方向  默认是false,即顺时针
    ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
    ctx.clip();//画好了圆 剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因
    
    ctx.drawImage('/image/gonglue_pic5.png', avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片,必须是https图片
    ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制
    ctx.draw(); //可将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
    
    ctx.setFillStyle("#333");
    ctx.setFontSize(10 * rpx); //字大小
    ctx.setTextAlign('left'); //是否居中显示,参考点画布中线
    ctx.fillText('小桥流水', 120 * rpx, 480 * rpx);    
    ctx.setFillStyle("#999");
    ctx.setFontSize(10 * rpx); //字大小
    ctx.setTextAlign('left'); //是否居中显示,参考点画布中线
    ctx.fillText('邀您一起加入芬香', 120 * rpx, 495 * rpx);
    ctx.setFillStyle("#999");
    ctx.setFontSize(10 * rpx); //字大小
    ctx.setTextAlign('left'); //是否居中显示,参考点画布中线
    ctx.fillText('分享东京优惠好货', 120 * rpx, 508 * rpx);
    ctx.drawImage("/image/ma.png", 245 * rpx, 440 * rpx, 60 * rpx, 60 * rpx)
    ctx.setFillStyle("#999");
    ctx.setFontSize(10 * rpx); //字大小
    ctx.setTextAlign('left'); //是否居中显示,参考点画布中线
    ctx.fillText('长安识别', 255 * rpx, 510 * rpx);
    that.setData({
      canvas_hidden: false
    })
    ctx.draw(true, function () {
      setTimeout(function () {
        wx.hideLoading()
        // that.setData({
        //     canvas_hidden: false
        // })
      }, 1000)
    });
    setTimeout(function () {
      // that.saveImg()
    }, 1100)
    // ctx.draw();
  },
  // 多行文本
  dealWords: function (options) {
    options.ctx.setFontSize(options.fontSize); //设置字体大小
    var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth); //实际总共能分多少行
    var count = allRow >= options.maxLine ? options.maxLine : allRow; //实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数
    var endPos = 0; //当前字符串的截断点
    for (var j = 0; j < count; j++) {
      var nowStr = options.word.slice(endPos); //当前剩余的字符串
      var rowWid = 0; //每一行当前宽度  
      if (options.ctx.measureText(nowStr).width > options.maxWidth) { //如果当前的字符串宽度大于最大宽度,然后开始截取
        for (var m = 0; m < nowStr.length; m++) {
          rowWid += options.ctx.measureText(nowStr[m]).width; //当前字符串总宽度
          if (rowWid > options.maxWidth) {
            if (j === options.maxLine - 1) { //如果是最后一行
              options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 18); //(j+1)*18这是每一行的高度    
            } else {
              options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
            }
            endPos += m; //下次截断点
            break;
          }
        }
      } else { //如果当前的字符串宽度小于最大宽度就直接输出
        options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
      }
    }
  },
  /**
   *     制作圆角
   * @param {CanvasContext} ctx canvas上下文
   * @param {number} x 圆角矩形选区的左上角 x坐标
   * @param {number} y 圆角矩形选区的左上角 y坐标
   * @param {number} w 圆角矩形选区的宽度
   * @param {number} h 圆角矩形选区的高度
   * @param {number} r 圆角的半径
   */
  roundRect(ctx, x, y, w, h, r) {
    ctx.save();
    // 开始绘制
    ctx.beginPath()
    // 因为边缘描边存在锯齿,最好指定使用 transparent 填充
    // 这里是使用 fill 还是 stroke都可以,二选一即可
    ctx.setFillStyle('#fff')
    // ctx.setStrokeStyle('red')
    // 左上角
    ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
    // border-top
    ctx.moveTo(x + r, y)
    ctx.lineTo(x + w - r, y)
    ctx.lineTo(x + w, y + r)
    // 右上角
    ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
    // border-right
    ctx.lineTo(x + w, y + h - r)
    ctx.lineTo(x + w - r, y + h)
    // 右下角
    ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
    // border-bottom
    ctx.lineTo(x + r, y + h)
    ctx.lineTo(x, y + h - r)
    // 左下角
    ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
    // border-left
    ctx.lineTo(x, y + r)
    ctx.lineTo(x + r, y)
    // 这里是使用 fill 还是 stroke都可以,二选一即可,但是需要与上面对应
    ctx.fill()
    // ctx.stroke()
    ctx.closePath()
    // 剪切
    ctx.clip()
    ctx.restore();
  },
  saveImg() {
    let that = this;
    var res = wx.getSystemInfoSync()
    var rpx = res.windowWidth / 375
    that.setData({
      rpx: res.windowWidth / 375
    })
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 375 * rpx, //画布宽高
      height: 1000 * rpx,
      destWidth: 750 * rpx, //画布宽高*dpr 以iphone6为准
      destHeight: 2000 * rpx, //放大2倍以上,解决保存的图片模糊的问题
      canvasId: 'myCanvass',
      success: function (res) {
        //console.log(res.tempFilePath) //生成的临时图片路径
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function (res) {
            App.util._toast("您的分享海报已存入手机相册,赶快去分享给好友吧!")
          },
          fail: function (err) {
            //console.log(err)
            if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
              // 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
              wx.showModal({
                title: '提示',
                content: '需要您授权保存相册',
                showCancel: false,
                success: modalSuccess => {
                  wx.openSetting({
                    success(settingdata) {
                      // console.log("settingdata", settingdata)
                      if (settingdata.authSetting['scope.writePhotosAlbum']) {
                        wx.showModal({
                          title: '提示',
                          content: '授权成功,请重新生成海报',
                          showCancel: false,
                        })
                      } else {
                        wx.showModal({
                          title: '提示',
                          content: '获取权限失败,将无法保存到相册哦~',
                          showCancel: false,
                        })
                      }
                    },
                    fail(failData) {
                      //console.log("failData", failData)
                    },
                    complete(finishData) {
                      // console.log("finishData", finishData)
                    }
                  })
                }
              })
            }
          }
        })
      }
    })
  },
})

微信小程序画布(1)的更多相关文章

  1. 微信小程序-画布组件

    canvas 画布. 注: canvas 标签默认宽度300px.高度225px 同一页面中的 canvas-id 不可重复,如果使用一个已经出现过的 canvas-id,该 canvas 标签对应的 ...

  2. 微信小程序 画布drawImage实现图片截取

    大多数图片都大小不一,选择框的尺寸也是宽高相等的,就会有图片被压缩 解决方法: 1.可以使用画布对图片先进行截取,保存截取图片(用户自己选取,或者指定图片中心区域截取),但是对于多张图片手动截取,会影 ...

  3. 微信小程序 画布arc截取圆形图片

    画布提供了一种可以创建圆的方法 arc(x, y, r, s, e, counterclockwise) x,y:圆心 r:圆的半径 s:起始弧度 (0) e:终止弧度 (1.5 * Math.PI) ...

  4. 微信小程序导航:官方工具+精品教程+DEMO集合(1月7更新)

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=14764346784612:简易教程:https://mp.weixin.qq.com/debug ...

  5. 微信小程序裁剪图片成圆形

    代码地址如下:http://www.demodashi.com/demo/14453.html 前言 最近在开发小程序,产品经理提了一个需求,要求微信小程序换头像,用户剪裁图片必须是圆形,也在gith ...

  6. 微信小程序之裁剪图片成圆形

    前言 最近在开发小程序,产品经理提了一个需求,要求微信小程序换头像,用户剪裁图片必须是圆形,也在github上看了一些例子,一般剪裁图片用的都是方形,所以自己打算写一个小组件,可以把图片剪裁成圆形,主 ...

  7. 微信小程序--canvas画布实现图片的编辑

    技术:微信小程序   概述 上传图片,编辑图片大小,添加文字,改变文字颜色等 详细 代码下载:http://www.demodashi.com/demo/14789.html 概述 微信小程序--ca ...

  8. 微信小程序 在canvas画布上划动,页面禁止滑动

    要实现微信小程序 在canvas画布上划动,页面禁止滑动,不仅要设置disable-scroll="true",还要要给canvas绑定一个触摸事件才能生效. <canvas ...

  9. 微信小程序_(组件)canvas画布

    canvas画布效果 官方文档:传送门 Page({ canvasIdErrorCallback: function (e) { console.error(e.detail.errMsg) }, o ...

随机推荐

  1. Spring Boot熟稔于心的20个常识

    1.什么是 Spring Boot? Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供 ...

  2. 你还不知道Vue的生命周期吗?带你从Vue源码了解Vue2.x的生命周期(初始化阶段)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...

  3. 金三银四科学找工作,用python大数据分析一线城市1000多份岗位招聘需求

    文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 每年的三四月份是招聘高峰,也常被大家称为金三银四黄金招聘期,这时候上一 ...

  4. 多源第k短路 (ford + 重新定义编号) / 出发点、终点确定的第k短路 (Spfa+ 启发搜索)

    第k短路 Description 一天,HighLights实在是闲的不行,他选取了n个地点,n各地点之间共有m条路径,他想找到这m条路径组成的第k短路,你能帮助他嘛? Input 第一行三个正整数, ...

  5. SpringBoot系列之RabbitMQ使用实用教程

    SpringBoot系列之RabbitMQ使用实用教程 @ 目录 1. 消息队列概述 1.1 MQ的概述 1.2 MQ目的地形式 2. 消息队列实现方式 2.1 常见MQ框架 2.2 MQ实现方式 3 ...

  6. vue使用axios发送post请求时的坑及解决原理

    前言:在做项目的时候正好同事碰到了这个问题,问为什么用axios在发送请求的时候没有成功,请求不到数据,反而是报错了,下图就是报错请求本尊 vue里代码如下: this.$http.post('/ge ...

  7. Java学习笔记--Comparable & Comparator

    一.    Comparable<T>: Comparable是类内部的比较器,用于创建类的时候实现此接口,同时实现比较方法:对于不能修改源码的类则无法应用此方式进行比较排序等. 源码为: ...

  8. Docker多网卡

    # 查看所有网络 docker network ls # 如果要查看更加详细的虚拟网卡,如下指令 docker network inspect [NetWorkEthName | NetWorkEth ...

  9. go 结构开发规范

    机构规范: // 当前程序的包名 package main //导入其他的包 import "fmt" //常量的定义 const PI=3.14 //全局变量的声明和赋值 var ...

  10. Mac 系统root

    没错,你没看错,就是root mac系统安装件的时候,你有没有遇到过这种情况 总之,就是安装不上软件,肿么办? 网上解觉办法是: 进入系统偏好设置,设置为允许任何人,可是进去后这样: 别着急,打开命令 ...