微信小程序实现照片裁剪

 更新时间:2022年05月24日 12:40:53   作者:极品老大  
这篇文章主要为大家详细介绍了微信小程序实现照片裁剪,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了微信小程序实现照片裁剪的具体代码,供大家参考,具体内容如下

前段时间用小程序的canvas、movable-area、movable-view封装了一个按比例裁剪照片的组件,无需引用任何插件。废话不多说,直接贴代码:

组件代码

1.cut_photo.json

{
  "component": true
}

2.cut_photo.wxml

<view>
  <canvas class="fyj_canvas" canvas-id="myCanvas" style="width:100%;height:{{canvasHeight}}px">
    <movable-area class="fyj_movable_area text-center hidden" style="width:100%;height:{{canvasHeight}}px;">
      <movable-view wx:if="{{src}}" style="width:{{cutWidth}}px;height:{{cutHeight}}px" class="fyj_movable_view"
        x="{{x}}"
        y="{{y}}"
        direction="all"
        bindchange="movableChange"
      ></movable-view>
      <image  class="fyj_photo" id="fyj_photo" src="{{src}}" mode="widthFix"></image>
    </movable-area>
  </canvas>
  <view style="margin-top:20rpx;padding:0 20rpx;">
    <button class="pull-left" type="warn" size="mini" bindtap="getPhoto">选择照片/拍照</button>
    <button class="pull-right" type="primary" size="mini" bindtap="cut">裁剪</button>
    <view class="clearfix"></view>
  </view>
</view>

3.cut_photo.js

const app = getApp()
Component({
  options: {
    //multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    //宽高比
    aspectRatio: {
      type: Number,
      value: 5/7, 
    }
  },
  data: {
    screenWidth: wx.getSystemInfoSync().windowWidth,
    canvasHeight: 300,
    x: 0,
    y: 0,
    src: '',
    cut_src: '',
    cutWidth: 0,
    cutHeight: 0
  },
  attached: function () {
    
  },
  methods: {
    // 这里是一个自定义方法
    //选择照片
    getPhoto: function () {
      const $this = this;
      const ctx = wx.createCanvasContext('myCanvas',this)
      var obj = wx.createSelectorQuery();
      wx.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success(res) {
          //清空之前的剪切图
          $this.triggerEvent('getTempFilePath', { cut_src: '', cutWidth: $this.data.cutWidth, cutHeight: $this.data.cutHeight })
          // tempFilePath可以作为img标签的src属性显示图片
          const tempFilePaths = res.tempFilePaths[0];
          $this.setData({
            src: tempFilePaths,
            cut_src: '',
          });
          setTimeout(function () {
            wx.createSelectorQuery().in($this).select('#fyj_photo').boundingClientRect(function (rect) {
              console.log(rect);
              console.log(rect.height);
              $this.setData({
                canvasHeight: rect.height
              })
              ctx.drawImage(tempFilePaths, 0, 0, $this.data.screenWidth, $this.data.canvasHeight)
              ctx.draw();
              $this.setCut();
              //确保不同大小的图片,切图不会变形
              $this.setData({
                x: 0,
                y: 0
              });
            }).exec()
          }, 100)
          

        }
      })
        
    },
    //获取图片高度
    // getHeight:function(){
    //   const query = wx.createSelectorQuery().in(this)
    //   query.selectAll('#fyj_photo').boundingClientRect()
    //   query.exec(function (rect) {
    //     console.log(rect);
    //     console.log(rect[0].height);
    //     $this.setData({
    //       canvasHeight: rect[0].height
    //     })
    //     ctx.drawImage(tempFilePaths[0], 0, 0, $this.data.screenWidth, $this.data.canvasHeight)
    //     ctx.draw();
    //     $this.setCut();
    //   })
    // },
    //裁剪框移动事件
    movableChange: function (e) {
      console.log(e.detail);
      this.setData({
        x: e.detail.x,
        y: e.detail.y
      })
    },
    //截图
    cut: function () {
      const $this = this;
      console.log($this.data.cutHeight);
      wx.canvasToTempFilePath({
        x: $this.data.x,
        y: $this.data.y,
        width: $this.data.cutWidth,
        height: $this.data.cutHeight,
        destWidth: $this.data.cutWidth,
        destHeight: $this.data.cutHeight,
        canvasId: 'myCanvas',
        success(res) {
          console.log(res.tempFilePath);
          $this.setData({
            cut_src: res.tempFilePath
          })
          $this.triggerEvent('getTempFilePath', { cut_src: $this.data.cut_src, cutWidth: $this.data.cutWidth, cutHeight: $this.data.cutHeight})
        }
      },this)
    },
    //动态设置裁剪框大小,确定高度不得超过canvas的高度
    setCut: function () {
      const $this = this;
      this.setData({
        cutWidth: wx.getSystemInfoSync().windowWidth * 0.8,
        cutHeight: wx.getSystemInfoSync().windowWidth * 0.8/this.data.aspectRatio
      })
      if (this.data.cutHeight - 4 > this.data.canvasHeight) {
        console.log($this.data.cutHeight);
        console.log($this.data.canvasHeight);
        this.setData({
          cutHeight: this.data.canvasHeight - 4,
          cutWidth: (this.data.canvasHeight - 4)*this.data.aspectRatio
        })
      } else {
        this.setData({
          cutWidth: wx.getSystemInfoSync().windowWidth * 0.8,
          cutHeight: wx.getSystemInfoSync().windowWidth * 0.8/this.data.aspectRatio
        })
      }
      console.log($this.data.cutWidth);
      console.log($this.data.cutHeight);
    },
  }
})

4.cut_photo.wxss

.fyj_movable_area{width:100%;height:auto;position: relative;background:rgba(0,0,0,0.3)}
.fyj_movable_view{border:2px dashed #fff}
.fyj_photo{width:100%;}
.fyj_footer{margin-top:20rpx 0;}
.fyj_footerBtn{width:100%;display: inline-block;color:#fff;border-radius: 0;font-size:32rpx;}
.fyj_sure{background: #fc6b47;}
.pull-left{float:left;}
.pull-right{float:right}
.clearfix{clear:both}
.text-center{text-align: center}

引用页代码

1.page.json

{
  "navigationBarTitleText": "选择照片",
  "usingComponents": {
    "cut-photo": "/pages/cut_photo/cut_photo"
  }
}

2.page.wxml

<view>
<!-- aspectRatio 剪裁图片的宽高比 -->
  <cut-photo aspectRatio="0.5" bindgetTempFilePath="getCutsrc"></cut-photo>
  <view wx:if="{{cut_src}}" class="fyj_cutDiv text-center">
    <image style="width:{{cutWidth}}px;height:{{cutHeight}}px" class="fyj_cut_photo" src="{{cut_src}}" mode="widthFix"></image>
  </view>
  <view wx:if="{{cut_src}}"  class="fyj_footer text-center">
    <button class="fyj_footerBtn fyj_sure" bindtap='sure'>确定</button>
  </view>
</view>

3.page.js

const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    cut_src:'',
    cutWidth:0,
    cutHeight:0,
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
   
  },
  getCutsrc:function(e){
    console.log(e);
    this.setData({
      cut_src: e.detail.cut_src,
      cutWidth: e.detail.cutWidth,
      cutHeight: e.detail.cutHeight

    })
  }
})

4.page.wxss

.fyj_footer{margin-top:20rpx 0;}
.fyj_footerBtn{width:100%;display: inline-block;color:#fff;border-radius: 0;font-size:32rpx;}
.fyj_sure{background: #fc6b47;}
.fyj_cutDiv{margin:20rpx 0;}

大概思路

将canvas跟movable-area重合,通过movable-view来确定裁剪区域。为了确保图片加载不变形,选择完图片后,需要动态设置canvas、movable-area的高度及movable-view的宽高。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 使用JavaScript实现简单图像放大镜效果

    使用JavaScript实现简单图像放大镜效果

    图像放大镜在很多网站中都扮演着重要的角色,大多数开发人员使用 jquery 来创建图像放大镜。在本教程中,我将向大家展示如何使用 HTML、CSS 和 JavaScript 制作一个简单的图像放大镜,需要的可以参考一下
    2022-08-08
  • JS调用某段SQL语句的方法

    JS调用某段SQL语句的方法

    这篇文章主要为大家详细介绍了通过JS调用某段SQL语句的相关方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Canvas实现二娃翠花回家之路小游戏demo解析

    Canvas实现二娃翠花回家之路小游戏demo解析

    这篇文章主要为大家介绍了Canvas实现二娃翠花回家之路小游戏demo解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • js实现按一下删除键删除整个单词附demo

    js实现按一下删除键删除整个单词附demo

    使用代码实现当删除单词时就一次性删除整个单词,有个demo,相信大家看过之后就知道是什么意思了
    2014-09-09
  • 原生js拖拽实现图形伸缩效果

    原生js拖拽实现图形伸缩效果

    这篇文章主要为大家详细介绍了原生js拖拽实现图形的伸缩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • layui使用templet格式化表格数据的方法

    layui使用templet格式化表格数据的方法

    今天小编就为大家分享一篇layui使用templet格式化表格数据的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JS获取表格内指定单元格html内容的方法

    JS获取表格内指定单元格html内容的方法

    这篇文章主要介绍了JS获取表格内指定单元格html内容的方法,涉及javascript中innerHTML属性的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • 详解html-webpack-plugin插件(用法总结)

    详解html-webpack-plugin插件(用法总结)

    这篇文章主要介绍了详解html-webpack-plugin插件(用法总结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • JavaScript闭包详解

    JavaScript闭包详解

    一分钟理解JavaScript闭包,关于JavaScript闭包的内容介绍了很多,本文带着大家快速理解什么是JavaScript闭包,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 不同js异步函数同步的实现方法

    不同js异步函数同步的实现方法

    下面小编就为大家带来一篇不同js异步函数同步的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05

最新评论