微信小程序实现九宫格切图,保存功能!
效果如下图:
代码如下:
<view class='sudoku'>
<scroll-view scroll-x scroll-y class='canvas-box'>
<canvas canvas-id='canvasIn' id='canvas' class='canvas canvas-in' style='{{canvasWH}}'></canvas>
<!-- wx:if='{{canvasIn}}' -->
<!-- <canvas canvas-id='canvasOut' id='canvasOut' class='canvas canvas-out' style='{{canvasWH}}'></canvas> -->
</scroll-view>
<cover-view class='imgs'>
<cover-view class='imgs-box'>
<cover-image class='img' data-idx='{{index+1}}' src='{{item}}' style='{{maxHeight}}' wx:for='{{imgUrls}}' wx:key='{{index}}' bindtap='saveImg'></cover-image>
</cover-view>
</cover-view>
<cover-view class='btns-box'>
<button bindtap='uploadImg' class='btn btn-cut'>上传</button>
<button bindtap='saveAll' class='btn btn-save'>保存</button>
</cover-view>
</view>
let _this
Page({ /**
* 页面的初始数据
*/
data: {
canvasWH: '',
imgW: 0,
imgH: 0,
uploadFlag: false,
imgUrls: [],
maxHeight: ''
}, /* 上传图片 */
uploadImg() {
const query = wx.createSelectorQuery()
query.select('#canvas').boundingClientRect(function(res) {
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
// sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success(res) {
// 图片大小限制为 最大2M
const imgSize = res.tempFiles[0].size
console.log(res, imgSize, '已选择图片大小') if (imgSize > 1000000) {
wx.showModal({
title: '温馨提示',
content: '图片最大不能超过1M',
showCancel: false
})
return
} const ctx = wx.createCanvasContext('canvasIn')
const canvasW = res.width
const canvasH = res.height
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvasW, canvasH)
ctx.draw() // 获取图片信息
wx.getImageInfo({
src: res.tempFilePaths[0],
success(imgInfo) {
console.log(imgInfo, 'imgInfo')
const imgW = imgInfo.width
const imgH = imgInfo.height _this.setData({
canvasWH: `width: ${imgW}px;height: ${imgH}px`,
imgW,
imgH
}) // 获取图片的大小
ctx.drawImage(res.tempFilePaths[0], 0, 0, imgW, imgH)
ctx.draw()
// 展示新图片
_this.showMiniImg()
},
fail(err) {
console.log(err, '图片信息获取失败')
wx.showModal({
title: '温馨提示',
content: '暂不支持此图片格式',
showCancel: false
})
}
})
},
fail (err) {
console.log(err, '图片选择失败')
}
})
})
query.exec()
}, /* 展示小图 */
showMiniImg() {
let x = 0
let y = 0
let count = 0
let imgUrls = []
const {
imgW,
imgH
} = _this.data const cutW = imgW / 3
const cutH = imgH / 3 const cfgSave = {
x: 0,
y: 0,
width: cutW,
height: cutH,
destWidth: cutW,
destHeight: cutH,
canvasId: 'canvasIn'
}
_this.cutFlag = true const timer = setInterval(() => {
if (_this.cutFlag) {
_this.cutFlag = false
console.log(count, 'cutFlag')
switch (count) {
case 0:
x = 0
y = 0
break
case 1:
x = 1
y = 0
break
case 2:
x = 2
y = 0
break
case 3:
x = 0
y = 1
break
case 4:
x = 1
y = 1
break
case 5:
x = 2
y = 1
break
case 6:
x = 0
y = 2
break
case 7:
x = 1
y = 2
break
case 8:
x = 2
y = 2
break
default:
break
}
cfgSave.x = cutW * x
cfgSave.y = cutH * y wx.canvasToTempFilePath({
...cfgSave,
success(res) {
console.log(res, '剪切') _this.cutFlag = true
count++
wx.showLoading({
title: `裁剪中 ${count}/9`,
mask: true
})
imgUrls.push(res.tempFilePath)
if (count == 9) {
if (imgUrls.length < 9) {
imgUrls = []
cut()
return
}
wx.hideLoading()
_this.setData({
uploadFlag: true,
imgUrls
})
clearInterval(timer)
}
},
fail (err) {
console.log(err , '剪切图片失败')
}
})
}
}, 100)
}, /* 保存图片(单图 / 所有) */
saveImgHandle(e) {
const {
imgW,
imgH,
imgUrls
} = _this.data const cutW = imgW / 3
const cutH = imgH / 3 const cfgSave = {
x: 0,
y: 0,
width: cutW,
height: cutH,
destWidth: cutW,
destHeight: cutH,
canvasId: 'canvasIn',
} if (e) { //保存单张图片
switch (e.currentTarget.dataset.idx) {
case 1:
cfgSave.x = cutW * 0
cfgSave.y = cutH * 0
break
case 2:
cfgSave.x = cutW * 1
cfgSave.y = cutH * 0
break
case 3:
cfgSave.x = cutW * 2
cfgSave.y = cutH * 0
break
case 4:
cfgSave.x = cutW * 0
cfgSave.y = cutH * 1
break
case 5:
cfgSave.x = cutW * 1
cfgSave.y = cutH * 1
break
case 6:
cfgSave.x = cutW * 2
cfgSave.y = cutH * 1
break
case 7:
cfgSave.x = cutW * 0
cfgSave.y = cutH * 2
break
case 8:
cfgSave.x = cutW * 1
cfgSave.y = cutH * 2
break
case 9:
cfgSave.x = cutW * 2
cfgSave.y = cutH * 2
break
default:
break
}
wx.canvasToTempFilePath({
...cfgSave,
success(res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(resPhoto) {
wx.showToast({
title: '保存成功'
})
}
})
}
})
} else { //保存所有
let pathArr = []
let x = 0
let y = 0
let count = 0
_this.saveFlag = true const timer = setInterval(() => {
if (_this.saveFlag) { _this.saveFlag = false
console.log(count, 'saveFlag')
switch (count) {
case 0:
x = 0
y = 0
break
case 1:
x = 1
y = 0
break
case 2:
x = 2
y = 0
break
case 3:
x = 0
y = 1
break
case 4:
x = 1
y = 1
break
case 5:
x = 2
y = 1
break
case 6:
x = 0
y = 2
break
case 7:
x = 1
y = 2
break
case 8:
x = 2
y = 2
break
default:
break
}
cfgSave.x = cutW * x
cfgSave.y = cutH * y
wx.canvasToTempFilePath({
...cfgSave,
success(res) {
console.log(res, '保存所有') pathArr.push(res.tempFilePath)
count++
wx.showLoading({
title: `保存中${count}/9`,
})
_this.saveFlag = true
if (count == 9) {
clearInterval(timer)
console.log(pathArr)
// 保存到相册
for (let i = 0; i < pathArr.length; i++) {
wx.saveImageToPhotosAlbum({
filePath: pathArr[i],
success(resPhoto) {
_this.saveFlag = true
if (i == pathArr.length - 1) {
wx.hideLoading()
wx.showToast({
title: '保存成功'
})
}
}
})
}
}
}
})
}
}, 100)
}
}, /* 保存单张图片 */
saveImg(e) {
const {
uploadFlag
} = _this.data
// 判断是否已上传图片
if (uploadFlag) {
wx.showModal({
title: '温馨提示',
content: '要将该图片保存到相册吗?',
success(confirm) {
if (confirm.confirm) {
_this.photoAuthorization(e)
}
}
}) } else {
wx.showModal({
title: '温馨提示',
content: '请先上传图片',
showCancel: false
})
} }, /* 一键保存 */
saveAll() {
const {
uploadFlag
} = _this.data
// 判断是否已上传图片
if (uploadFlag) {
_this.photoAuthorization()
} else {
wx.showModal({
title: '温馨提示',
content: '请先上传图片',
showCancel: false
})
}
}, /* 设置显示图片的最大高度为屏幕高 */
setMaxHeight() {
wx.getSystemInfo({
success: function(res) {
console.log(res)
const windowH = res.windowHeight
const maxHeight = parseInt(windowH / 3)
_this.setData({
maxHeight: `max-height: ${maxHeight}px`
})
},
})
}, /* 相册授权 */
photoAuthorization(event) {
wx.getSetting({
success(res) {
if (res.authSetting['scope.writePhotosAlbum']) {
// 已授权
if (event) {
_this.saveImgHandle(event)
} else {
_this.saveImgHandle()
}
} else {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
// 已授权
if (event) {
_this.saveImgHandle(event)
} else {
_this.saveImgHandle()
}
},
fail() {
// 未授权
wx.showModal({
title: '温馨提示',
content: '需要获取相册权限',
success(resOpenSetting) {
if (resOpenSetting.confirm) {
wx.openSetting({
success(res) {
if (res.authSetting['scope.writePhotosAlbum']) {
// 已授权
if (event) {
_this.saveImgHandle(event)
} else {
_this.saveImgHandle()
}
} else {
wx.showModal({
title: '温馨提示',
content: '未获取到授权信息',
showCancel: false
})
}
}
})
}
}
})
}
})
}
}
})
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
_this = this
_this.setMaxHeight()
}, /**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() { }, /**
* 生命周期函数--监听页面显示
*/
onShow: function() { }, /**
* 生命周期函数--监听页面隐藏
*/
onHide: function() { }, /**
* 生命周期函数--监听页面卸载
*/
onUnload: function() { }, /**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() { }, /**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() { }, /**
* 用户点击右上角分享
*/
onShareAppMessage: function() { }
})
page {
height: %;
background-color: #fff;
overflow: hidden;
} .sudoku {
height: %;
} .canvas-box {
position: relative;
width: %;
height: %;
overflow: auto;
} .canvas {
min-width: %;
height: %;
position: absolute;
top: ;
} .canvas-in {
z-index: ;
} .canvas-out {
z-index: ;
background-color: #fff;
} .imgs{
width: %;
height: %;
position: absolute;
top: ;
z-index: ;
background-color: #fff;
} .imgs-box{
width: %;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
padding: 8rpx;
box-sizing: border-box;
} .img{
flex-shrink: ;
width: 33.3%;
padding: 5rpx;
box-sizing: border-box;
} .btns-box {
position: fixed;
right: 30rpx;
bottom: 120rpx;
z-index: ;
display: flex;
justify-content: space-evenly;
flex-direction: column;
height: 300rpx;
} .btn {
color: #fff;
width: 100rpx;
height: 100rpx;
border: none;
border-radius: %;
} .wx-button-cover-view-wrapper {
width: %;
height: %;
display: flex;
justify-content: center;
align-items: center;
} .wx-button-cover-view-inner {
width: %;
height: %;
display: flex;
justify-content: center;
align-items: center;
} .btn::after {
border: none;
} .btn-cut {
background-color: rgba(, , , 0.5);
} .btn-save {
background-color: rgba(, , , 0.5);
}
微信小程序实现九宫格切图,保存功能!的更多相关文章
- 微信小程序的轮播图swiper问题
微信小程序的轮播图swiper,调用后,怎样覆盖系统的 点,达到自己想要的效果 不多说,先上一图望大家多给意见: 这个是效果图: 微信小程序效果图就成这样子: <view class=" ...
- 微信小程序登陆流程图时序图
微信小程序登录 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 微信小程序登录流程时序图 说明 调用 wx.login() 获取 临时登录凭证cod ...
- 微信小程序 获取用户信息并保存登录状态
微信小程序 获取用户信息并保存登录状态:http://www.360doc.com/content/18/0124/11/9200790_724662071.shtml
- 微信小程序0.11.122100版本新功能解析
微信小程序0.11.122100版本新功能解析 新版本就不再吐槽了,整的自己跟个愤青似的.人老了,喷不动了,把机会留给年轻人吧.下午随着新版本开放,微信居然破天荒的开放了开发者论坛.我很是担心官方 ...
- 如何自定义微信小程序swiper轮播图面板指示点的样式
https://www.cnblogs.com/myboogle/p/6278163.html 微信小程序的swiper组件是滑块视图容器,也就是说平常我们看到的轮播图就可以用它来做,不过这个组件有很 ...
- 微信小程序之雪碧图(css script)
今天有朋友问我关于微信小程序中如何在不占用大量网络带宽的情况下快速加载图片,我给他推荐了两种方式 1.雪碧图(css script),有过前端经验的朋友应该都有接触过. 2.懒加载. 由于时间关系我就 ...
- 微信小程序之tabbar切卡
最近在研究小程序的时候,遇到了一个问题,就是tabbar切卡,在android上有fragment,在RN上也有提供一个第三方的组件来用,微信小程序,好像没有专门的一个组件来实现这个功能,度娘了大半天 ...
- 自定义微信小程序swiper轮播图面板指示点的样式
微信小程序的swiper组件是滑块视图容器,也就是说平常我们看到的轮播图就可以用它来做,不过这个组件有很多样式是固定的,但是,有时候我们的设计稿的面板指示点是需要个性化的,那么如何去修改swiper组 ...
- 【自定义轮播图】微信小程序自定义轮播图无缝滚动
先试试效果,可以通过设置参数调整样式 微信小程序中的轮播图可以直接使用swiper组件,如下: <swiper indicator-dots="{{indicatorDots}}&qu ...
随机推荐
- Linux遇到的问题-记录
Linux遇到的问题 2019-04-09以前: Linux&Win双系统下时间显示不正常的问题 一般安装了双系统(Linux+Windows)就很容易出现问题,Windows是直接取硬件时间 ...
- Servlet与Tomcat运行示例
Servlet与Tomcat运行示例 本文将写一个servlet,然后将其部署到Tomcat的全过程.本文参考<深入拆解Tomcat_Jetty>内容. 一.基于web.xml开发步骤 下 ...
- Android组件化路由实践
Android应用组件化各个组件页面之间要实现跳转使用路由是一个很好的选择.本文将实现一个比较轻量级的路由组件,主要涉及以下知识: Annotation (声明路由目标信息) AnnotationPr ...
- 【SQL server初级】数据库性能优化三:程序操作优化
数据库优化包含以下三部分,数据库自身的优化,数据库表优化,程序操作优化.此文为第三部分 数据库性能优化三:程序操作优化 概述:程序访问优化也可以认为是访问SQL语句的优化,一个好的SQL语句是可以减少 ...
- python beautiful soup
官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ 使用前需要先安装模块,并安装解析器 pip install beautif ...
- Laravel Entrust 权限管理扩展包的使用笔记
简介 Entrust 是一个简洁而灵活的基于角色进行权限管理的 Laravel 扩展包.针对 Laravel 5,官方推荐的安装版本是 5.2.x-dev.它的详细使用方法请查看 Entrust Gi ...
- JavaSE----02.Java语言基础
02.Java语言基础 1.关键字 Java关键字是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量.Java的关键字对Java的编译器有特殊的意义,他们用来表示一 ...
- reduce方法应用技巧
定义和用法 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值. 注意: reduce() 对于空数组是不会执行回调函数的. 浏览器支持 方法 Chro ...
- Github配合Jenkins,实现vue等前端项目的自动构建与发布
本篇文章前端项目以vue为例(其实前端工程化项目的操作方法都相同),部署在Linux系统上(centos). 之前做前端项目的部署,一直都是手动运行打包命令,打包完.再使用FTP.Xshell等这类的 ...
- execute,executeQuery,executeUpdate
Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true.如果结果不是ResultSet,比如inse ...