箭头绘制参考了:https://blog.csdn.net/qq_45939676/article/details/127425426 这位大佬的文章

gitee地址: https://gitee.com/philippines-kisses-snow/uniapp-image-edit.git

组件预览

功能介绍

  1. 剪切
  2. 添加文本
  3. 涂鸦
  4. 绘制图形(支持箭头,圆形,矩形)
  5. 旋转

实现思路

  1. 将屏幕分为两部分:图片编辑部分、操作栏部分
  2. 图片编辑部分当中创建一个图片容器,容器大小为:图片大小*缩放比例,在容器当中使用<image />标签显示图片内容,<image />的大小占满父容器
  3. 创建一个<canvas />,canvas的大小为图片容器的大小,创建后用于保存图片编辑后的内容,并导出图片,再将image上的图片替换为canvas导出的图片,利用css将这个仅用于保存的canvas标签设置为不可见

一、 剪切

这里只设置了四个夹角用于拖动:左上角、右上角、左下角、右下角

剪切蒙版使用定位,相当于图片容器进行定位,那么蒙版的大小就是可以通过left、top、right、bottom的定位控制

  1. 设置蒙版颜色和边框,给蒙版的四个角设置拖动点,添加4个元素,定位到四个角,给这4个元素添加边框,使边框刚好包裹图片的菱角
  2. 给这四个元素添加拖动事件,并记录每次拖动的起始点,注:在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>
  1. 根据始末位置的坐标差计算定位
例如:移动左上角时:
起始点是(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 >= 最小高
  1. 导出,剪切完成后通过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进行实时绘制

  1. 在图片容器内创建一个canvas,canvas大小为图片容器大小
  2. 涂鸦时直接在canvas上绘制即可(具体绘制过程的代码就不贴了,可在git当中查看)
  3. 保存时需导出该涂鸦图片,使用保存用的canvas绘制这两张图片,先绘制原图,再绘制涂鸦,导出即可

四、图形

在图片容器当中创建两个canvas(其中一个可与绘制涂鸦的canvas复用),获取起始点与当前点坐标在最外层的canvas上绘制相应图形,在滑动结束后将图形信息用数组保存起来,遍历数组绘制到下层的canvas上,清空最外层的canvas

箭头绘制需在箭头终点绘制两侧箭头边,具体计算可查看代码和参考的文章

uniapp H5图片编辑器(安卓/iOS适用)的更多相关文章

  1. 移动端H5制作安卓和IOS的坑 持续更新...

    移动端H5制作安卓和IOS的坑 持续更新... 前言:最近参加公司的H5页面创意竞赛,又遇到不少页面在不同系统上的坑.踩坑之余,觉得很多之前遇到的知识点都忘了,索性开一篇博文,把这些坑都统一归纳起来, ...

  2. H5与安卓、IOS的交互,判断微信、移动设备、安卓、ios

    一.通过用户代理可以判断网页当前所在的环境 var browser={ versions:function(){ var u = navigator.userAgent, app = navigato ...

  3. h5与安卓、ios交互

    1.安卓交互 h5调用安卓方法 window.webview.xxx() 安卓调用h5方法, 方法需要在全局注册 window['showUnreadMsg'] = () => { this.$ ...

  4. 点击复制文字到剪贴板兼容性安卓ios

    一般那种活动H5分享可能会用到点击复制文字到剪贴板,很简单的功能 于是搜了一搜:js复制文字到剪贴板,可用结果大致分为两类: 一类是js原生方法,这种方法兼容性不好,不兼容ios: https://d ...

  5. 史上最简单JS复制功能,兼容安卓ios!

    1.JS复制原理: 被复制内容的元素不能被其他元素遮盖,否则无效.  (设置opacity透明为0,不可以设置display:none); 2.常规的复制方法 function copyUrl2() ...

  6. .net 安卓IOS跨平台des加解密双向的(可以互相加解密)

    #region 跨平台加解密(c# 安卓 IOS) // public static string sKey = "12345678"; // /// // /// 解密 // / ...

  7. 安卓ios和angularjs相互调用解决首次调用ios传递标题失败的问题

    1.angular 调用客户端方法放在 try catch中 try { js_invoke.showShareDialog(angular.toJson(obj));  // 在这里放客户端的方法即 ...

  8. 安卓ios各版本及分辨率占比

    Google Play 安装统计数据 只有安卓的 https://developer.android.com/about/dashboards/index.html?hl=zh-cn 腾讯移动分析 安 ...

  9. H5移动端IOS/Android兼容性总结,持续更新中…

    H5移动端IOS/Android兼容性总结,持续更新中… 1. IOS不识别日期 new Date("2018-07-01 08:00:00")在Android下正常显示可以直接进 ...

  10. uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据

    h5端的uni-app项目 需求:uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据 百度的方法如下: uni.switchTab({ url: '/p ...

随机推荐

  1. HTML完整语法学习

    https://www.cnblogs.com/douluo/archive/2021/11/20/15582217.html

  2. 【Jenkins】jenkins 配置腾讯企业邮箱

    首页]-->[系统管理]-->[系统设置] //////////////////////////////////////////////////////////////////////// ...

  3. 服务器性能测试工具ab

    ab指令 ab -n 1000 -c 20 http://127.0.0.1/

  4. 使用dumpbin查看dll文件中的api

    一.找到vs自带的dumpbin 我的目录如下: C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14 ...

  5. python 添加文件模板,默认添加作者时间等必要信息

    1.模板设置 配置路径:Setting-Editor-File and Code Templates-Python-Script 2.示例输入 代码如下(示例): #!/usr/bin/env pyt ...

  6. Phpstorm 最新永久激活教程

    使用ja-netfilter激活Jetbrains系列软件 注意:无限试用脚本已经失效.本教程适合2021.3.*之上的高版本,使用ja-netfilter插件进行激活操作,永久有效 激活步骤: 第一 ...

  7. 如何安装vm虚拟机软件并用该软件建立虚拟机

    一.安装vm虚拟机软件 1.双击打开虚拟机应用程序 找到VM应用程序所在的位置,双击安装 2.根据向导安装 根据提示点击下一步 点击安装之后耐心等待一会,会出现需要输入许可证的的界面,这时候不要关闭界 ...

  8. 匿名Lambda函数,C++

    1 // To Compile and Run: g++ -std=c++11 lambda.cc -Wall -O3 && ./a.out 2 3 4 #include <io ...

  9. 微信小程序—标题栏

    <template> <view :style="{paddingTop: statusBarHeight + 'px',background:bg}" clas ...

  10. 【Unity】检测目标是否在视线范围内(附视线范围扇形画法)

    检测目标是否在视线范围内(附视线范围扇形画法) using UnityEngine; public class Test_CanSeeTarget : MonoBehaviour { public G ...