uniapp H5图片编辑器(安卓/iOS适用)
箭头绘制参考了:https://blog.csdn.net/qq_45939676/article/details/127425426 这位大佬的文章
gitee地址: https://gitee.com/philippines-kisses-snow/uniapp-image-edit.git
组件预览
功能介绍
- 剪切
- 添加文本
- 涂鸦
- 绘制图形(支持箭头,圆形,矩形)
- 旋转
实现思路
- 将屏幕分为两部分:图片编辑部分、操作栏部分
- 图片编辑部分当中创建一个图片容器,容器大小为:图片大小*缩放比例,在容器当中使用
<image />
标签显示图片内容,<image />
的大小占满父容器 - 创建一个
<canvas />
,canvas的大小为图片容器的大小,创建后用于保存图片编辑后的内容,并导出图片,再将image上的图片替换为canvas导出的图片,利用css将这个仅用于保存的canvas标签设置为不可见
一、 剪切
这里只设置了四个夹角用于拖动:左上角、右上角、左下角、右下角
剪切蒙版使用定位,相当于图片容器进行定位,那么蒙版的大小就是可以通过left、top、right、bottom
的定位控制
- 设置蒙版颜色和边框,给蒙版的四个角设置拖动点,添加4个元素,定位到四个角,给这4个元素添加边框,使边框刚好包裹图片的菱角
- 给这四个元素添加拖动事件,并记录每次拖动的起始点,注:在touchmove当中需要更新起始点为当前位置的坐标font>
<view @touchmove.stop="cropTouchMove($event, CROP_TYPE.TOP_LEFT)" @touchstart.stop="cropTouchStart" class="top-left"></view>
<view @touchmove.stop="cropTouchMove($event, CROP_TYPE.TOP_RIGHT)" @touchstart.stop="cropTouchStart" class="top-right"></view>
<view @touchmove.stop="cropTouchMove($event, CROP_TYPE.BOTTOM_RIGHT)" @touchstart.stop="cropTouchStart" class="bottom-right"></view>
<view @touchmove.stop="cropTouchMove($event, CROP_TYPE.BOTTOM_LEFT)" @touchstart.stop="cropTouchStart" class="bottom-left"></view>
- 根据始末位置的坐标差计算定位
例如:移动左上角时:
起始点是(x = 0, y = 0)
当前点为(x = 2, y = 2)
移动差:(diffx = 2, diffy = 2)
由于移动点为左上角,蒙版的定位只有top、left会变化:
top变为:top + diffy
left变为: left + diffx,同理其他几个点类似:
右上角:top变为:top + diffy,right变为: right - diffx
左下角:bottom变为:bottom - diffy,left变为: left + diffx
右下角:bottom变为:bottom - diffy,right变为: right - diffx
出界判断:
0 <= top <= 图片容器高
0 <= left <= 图片容器宽
0 <= right <= 图片容器宽
0 <= bottom <= 图片容器高
最小剪切框大小限制:
图片宽 - right - left >= 最小宽
图片高 - bottom - top >= 最小高
- 导出,剪切完成后通过canvas的
drawImage
将图片渲染到canvas上,然后导出时,根据剪切蒙版的定位坐标计算出蒙版宽高,以蒙版左上角坐标开始导出蒙版宽高的图片即可
二、添加文本
文本添加与剪切类似,在图片容器内添加一个文本容器,并相对于图片容器定位,大小占满图片容器,创建一个文本数组用于保存文本框的属性:内容、位置,在文本容器内循环遍历文本数组,删除时只需删除对应索引的文本即可,保存时遍历数组,将文本循环绘制到canvas上,最后保存即可,双击图片可以新建一个文本框
// 绘制时的文本换行处理:
/**
* 绘制文本
* @param {Object} _this 组件实例
* @param {String} canvasID canvasID
* @param {String} text 文本字符串
* @param {Number} fontH 单行字体高度
* @param {Number} maxW 最大文本域宽
* @param {Number} startX 开始x坐标
* @param {Number} startY 开始y坐标
*/
export function drawText(_this, canvasID, textArea, fontSize, fontH, maxW, startX, startY) {
const ctx = uni.createCanvasContext(canvasID, _this)
const text = textArea.text
ctx.setFontSize(fontSize)
ctx.fillStyle = textArea.color
let rowW = 0
let rowTexts = []
let startIndex = 0
// 将一段长文本拆分为多段
for(let i = 0; i < text.length; i++) {
rowW += ctx.measureText(text[i]).width
if(rowW > maxW) {
rowTexts.push(text.substr(startIndex, i))
startIndex = i
rowW = 0
}
}
rowTexts.push(text.substr(startIndex))
// 分段绘制
rowTexts.forEach((str, index) => {
const y = index === 0 ? startY : index*fontH + startY
ctx.fillText(str, startX, y);
ctx.draw(true)
})
}
三、涂鸦
由于涂鸦实时性要求较高,图形不规则且连贯,需要使用canvas进行实时绘制
- 在图片容器内创建一个canvas,canvas大小为图片容器大小
- 涂鸦时直接在canvas上绘制即可(具体绘制过程的代码就不贴了,可在git当中查看)
- 保存时需导出该涂鸦图片,使用保存用的canvas绘制这两张图片,先绘制原图,再绘制涂鸦,导出即可
四、图形
在图片容器当中创建两个canvas(其中一个可与绘制涂鸦的canvas复用),获取起始点与当前点坐标在最外层的canvas上绘制相应图形,在滑动结束后将图形信息用数组保存起来,遍历数组绘制到下层的canvas上,清空最外层的canvas
箭头绘制需在箭头终点绘制两侧箭头边,具体计算可查看代码和参考的文章
uniapp H5图片编辑器(安卓/iOS适用)的更多相关文章
- 移动端H5制作安卓和IOS的坑 持续更新...
移动端H5制作安卓和IOS的坑 持续更新... 前言:最近参加公司的H5页面创意竞赛,又遇到不少页面在不同系统上的坑.踩坑之余,觉得很多之前遇到的知识点都忘了,索性开一篇博文,把这些坑都统一归纳起来, ...
- H5与安卓、IOS的交互,判断微信、移动设备、安卓、ios
一.通过用户代理可以判断网页当前所在的环境 var browser={ versions:function(){ var u = navigator.userAgent, app = navigato ...
- h5与安卓、ios交互
1.安卓交互 h5调用安卓方法 window.webview.xxx() 安卓调用h5方法, 方法需要在全局注册 window['showUnreadMsg'] = () => { this.$ ...
- 点击复制文字到剪贴板兼容性安卓ios
一般那种活动H5分享可能会用到点击复制文字到剪贴板,很简单的功能 于是搜了一搜:js复制文字到剪贴板,可用结果大致分为两类: 一类是js原生方法,这种方法兼容性不好,不兼容ios: https://d ...
- 史上最简单JS复制功能,兼容安卓ios!
1.JS复制原理: 被复制内容的元素不能被其他元素遮盖,否则无效. (设置opacity透明为0,不可以设置display:none); 2.常规的复制方法 function copyUrl2() ...
- .net 安卓IOS跨平台des加解密双向的(可以互相加解密)
#region 跨平台加解密(c# 安卓 IOS) // public static string sKey = "12345678"; // /// // /// 解密 // / ...
- 安卓ios和angularjs相互调用解决首次调用ios传递标题失败的问题
1.angular 调用客户端方法放在 try catch中 try { js_invoke.showShareDialog(angular.toJson(obj)); // 在这里放客户端的方法即 ...
- 安卓ios各版本及分辨率占比
Google Play 安装统计数据 只有安卓的 https://developer.android.com/about/dashboards/index.html?hl=zh-cn 腾讯移动分析 安 ...
- H5移动端IOS/Android兼容性总结,持续更新中…
H5移动端IOS/Android兼容性总结,持续更新中… 1. IOS不识别日期 new Date("2018-07-01 08:00:00")在Android下正常显示可以直接进 ...
- uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据
h5端的uni-app项目 需求:uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据 百度的方法如下: uni.switchTab({ url: '/p ...
随机推荐
- 核函数(kernel function)
在接触反演.算法等方面的知识后,经常听到"核"这个字,它不像对原始变量的线性变换,也不像类似于机器学习中激活函数那样的非线性变换,对原始数据进行变换,就可以将复杂的问题简单化.接下 ...
- 【pytest】@pytest.fixture与@pytest.mark.parametrize结合实现参数化
背景:测试数据既要在fixture方法中使用,同时也在测试用例中使用 使用方法:在使用parametrize的时候添加"indirect=True"参数.pytest可以实现将参数 ...
- Mysql 查询最近一年的数量sql
按月查询分月数量 , 某个月份没有的显示为0 SELECT@s := @s + 1 AS `index`,DATE_FORMAT( DATE_SUB( CURDATE(), INTERVAL @s M ...
- vue中关于get传参数为数组的解决方法
按理来说,get请求方式是没有数组的,get请求方式带参数都是字符串,需要和后端协商是用某个标识符分割开,例如"|" ",". 当然如果需要数组的话,也能解 ...
- 运行不出来真的QAQ
学C的时候最大的苦恼是编译不通过和运行不正确 学了C++之后就开始有编译过了但运行不出来的情况了TAT
- 收集的sql经典语句
经典SQL语句大全 一.基础1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql serve ...
- 面向对象3(Java)
多态 基本介绍 即同一方法可以根据发送对象的不同而采用多种不同的行为方式 一个对象的实际类型是确定的,但是可以指向对象的引用类型可以很多 多态存在的条件:a.有继承关系:b.子类重写父类方法:c.父类 ...
- nodejs的增删改查
1.新建一个jwttest.router.js 引入toast const {success,fail} = require("../toast"); const jwt = re ...
- if判断while循环
- 第12组 Beta冲刺 总结
1.基本情况: 组长博客链接:https://www.cnblogs.com/yaningscnblogs/p/14050343.html 答辩总结:答辩中,对于老师提出的意见,我们认为能够帮助我们更 ...