zoukankan      html  css  js  c++  java
  • 微信小程序画布(图片圆角)

     
    测重点主要头像的圆角
    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="750rpx;height:1100rpx;" />
              <view style='padding-bottom: 0;box-sizing: border-box;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{ 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; 100vw;height: 100vh;background: rgba(0, 0, 0, .6);}
    
    .warp_{ 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; 50rpx;height: 50rpx;background: #999;text-align: center;line-height: 50rpx;font-size: 50rpx;color: #fff;border-radius: 50%;}
    image{ 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,
           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)
                        }
                      })
                    }
                  })
                }
              }
            })
          }
        })
      },
    })
    

      

     
  • 相关阅读:
    Codeforces 1265A Beautiful String
    1039 Course List for Student (25)
    1038 Recover the Smallest Number (30)
    1037 Magic Coupon (25)
    1024 Palindromic Number (25)
    1051 Pop Sequence (25)
    1019 General Palindromic Number (20)
    1031 Hello World for U (20)
    1012 The Best Rank (25)
    1011 World Cup Betting (20)
  • 原文地址:https://www.cnblogs.com/liweitao/p/12774295.html
Copyright © 2011-2022 走看看