微信小程序?qū)崿F(xiàn)照片裁剪
本文實(shí)例為大家分享了微信小程序?qū)崿F(xiàn)照片裁剪的具體代碼,供大家參考,具體內(nèi)容如下
前段時(shí)間用小程序的canvas、movable-area、movable-view封裝了一個(gè)按比例裁剪照片的組件,無(wú)需引用任何插件。廢話不多說(shuō),直接貼代碼:
組件代碼
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 // 在組件定義時(shí)的選項(xiàng)中啟用多slot支持 ? }, ? properties: { ? ? // 這里定義了innerText屬性,屬性值可以在組件使用時(shí)指定 ? ? //寬高比 ? ? 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: { ? ? // 這里是一個(gè)自定義方法 ? ? //選擇照片 ? ? 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標(biāo)簽的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(); ? ? ? ? ? ? ? //確保不同大小的圖片,切圖不會(huì)變形 ? ? ? ? ? ? ? $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(); ? ? // ? }) ? ? // }, ? ? //裁剪框移動(dòng)事件 ? ? 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) ? ? }, ? ? //動(dòng)態(tài)設(shè)置裁剪框大小,確定高度不得超過(guò)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}
引用頁(yè)代碼
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({ ? /** ? ?* 頁(yè)面的初始數(shù)據(jù) ? ?*/ ? data: { ? ? cut_src:'', ? ? cutWidth:0, ? ? cutHeight:0, ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載 ? ?*/ ? 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重合,通過(guò)movable-view來(lái)確定裁剪區(qū)域。為了確保圖片加載不變形,選擇完圖片后,需要?jiǎng)討B(tài)設(shè)置canvas、movable-area的高度及movable-view的寬高。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用JavaScript實(shí)現(xiàn)簡(jiǎn)單圖像放大鏡效果
圖像放大鏡在很多網(wǎng)站中都扮演著重要的角色,大多數(shù)開(kāi)發(fā)人員使用?jquery?來(lái)創(chuàng)建圖像放大鏡。在本教程中,我將向大家展示如何使用?HTML、CSS?和?JavaScript?制作一個(gè)簡(jiǎn)單的圖像放大鏡,需要的可以參考一下2022-08-08Canvas實(shí)現(xiàn)二娃翠花回家之路小游戲demo解析
這篇文章主要為大家介紹了Canvas實(shí)現(xiàn)二娃翠花回家之路小游戲demo解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04js實(shí)現(xiàn)按一下刪除鍵刪除整個(gè)單詞附demo
使用代碼實(shí)現(xiàn)當(dāng)刪除單詞時(shí)就一次性刪除整個(gè)單詞,有個(gè)demo,相信大家看過(guò)之后就知道是什么意思了2014-09-09layui使用templet格式化表格數(shù)據(jù)的方法
今天小編就為大家分享一篇layui使用templet格式化表格數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JS獲取表格內(nèi)指定單元格html內(nèi)容的方法
這篇文章主要介紹了JS獲取表格內(nèi)指定單元格html內(nèi)容的方法,涉及javascript中innerHTML屬性的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03詳解html-webpack-plugin插件(用法總結(jié))
這篇文章主要介紹了詳解html-webpack-plugin插件(用法總結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09不同js異步函數(shù)同步的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇不同js異步函數(shù)同步的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05