uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制

这篇具有很好参考价值的文章主要介绍了uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

总结一下:

要进行海报绘制离不开canvas,我们是先进行图片,文字的拖拽、旋转等操作
最后再对canvas进行绘制,完成海报绘制。

  1. 背景区域设置为 position: relative,方便图片在当前区域中拖动等处理。
  2. 添加图片,监听图片在背景区域下的 touchstart touchmove touchend 事件
  3. 拖动图片,在touchmove中,对图片进行位置(后续坐标-初始坐标)、角度(勾股定理计算点到圆心距离,利用角度计算公式计算)、放缩比例(勾股定理计算点到圆心的半径距离,拖动停止的半径除以初始的半径,获得放缩比例scale)的计算
  4. 最终canvas绘制,利用dom中的空canvas,将图片依次绘制到canvas中,并获取链接

部分主要代码如下:

const ctx = uni.createCanvasContext("myCanvas", this);
ctx.drawImage(this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);

const ctx = uni.createCanvasContext("myCanvas", this);
ctx.drawImage(this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
ctx.save();
ctx.beginPath();

// 画背景色(白色)
// ctx.setFillStyle('#fff');
// ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
for (let i=0; i<items.length; i++) {
	const cur = items[i]
	ctx.save();
	ctx.translate(0, 0);
	ctx.beginPath();
	if(cur.image) {
		ctx.translate(cur.x, cur.y); // 圆心坐标
		ctx.rotate(cur.angle * Math.PI / 180); // 图片旋转的角度
		ctx.translate(-(cur.width * cur.scale / 2), -(cur.height * cur.scale / 2)) // 图片的缩放
		ctx.drawImage(cur.image, 0, 0, cur.width * cur.scale, cur.height * cur.scale); // 图片绘制
	}
	if (cur.text) {
		ctx.font = `${cur.font}px arial`;
		ctx.fillStyle = cur.fillStyle;
		ctx.fillText(cur.text, cur.left, cur.top + Number(cur.font));
		console.log(cur.left, cur.top + Number(cur.font))
	}
	ctx.restore();
}
ctx.draw(true, () => {
	// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (this.cutT / this.cropperH) * (this.imageH / pixelRatio)
	var canvasW = ((this.cropperW - this.cutL - this.cutR) / this.cropperW) * IMG_REAL_W;
	var canvasH = ((this.cropperH - this.cutT - this.cutB) / this.cropperH) * IMG_REAL_H;
	var canvasL = (this.cutL / this.cropperW) * IMG_REAL_W;
	var canvasT = (this.cutT / this.cropperH) * IMG_REAL_H;
	uni.canvasToTempFilePath({
			x: canvasL,
			y: canvasT,
			width: canvasW,
			height: canvasH,
			// destWidth: canvasW,
			// destHeight: canvasH,
			quality: +this.quality,
			fileType: this.fileType,
			canvasId: "myCanvas",
			success: (res) => {
				uni.hideLoading();
				// 成功获得地址的地方
				// this.$emit("getImg", res.tempFilePath);
				this.saveImg(res.tempFilePath)
				this.isShow = false;
			},
			fail: (err) => {
				uni.hideLoading();
				uni.showToast({
					title: "图片截取失败!",
					icon: "none",
				});
			},
		},
		this
	);
});
<!-- 海报背景区域,采用style动态调整,cropperInitW,cropperInitH一般为满屏 -->
			<view class="uni-corpper"
				:style="'width:' + cropperInitW + 'px;height:' + cropperInitH + 'px;background:#000'">
				<!-- 海报绘制区域,采用style动态调整,按照图片的长宽比例动态计算 cropperW等-->
				<view class="uni-corpper-content" :style="
						'width:' +
							cropperW +
							'px;height:' +
							cropperH +
							'px;left:' +
							cropperL +
							'px;top:' +
							cropperT +
							'px'
					">
					<!-- 背景图片区域 cropperW等同上 -->
					<image :src="imageSrc" :style="'width:' + cropperW + 'px;height:' + cropperH + 'px;' + 'border: 3px solid #ff0000;'"></image>
					<!-- 海报上其他图片处理,for循环,itemList通过点击添加 -->
					<block v-for="item in itemList" :key="item.id">
					<!-- 动态设置图片区域的缩放比例,还有pisition的左右位置,选中时z-index变大 -->
						<view class='touchWrap' :style="{transform: 'scale(' + item.scale + ')', top: item.top + 'px', left: item.left + 'px', 'z-index':item.active ? 100 : 1}">
							<view class='imgWrap' :class="item.active ? 'touchActive' : ''" :style="{transform: 'rotate(' + item.angle + 'deg)', border: item.active ? 4 * item.oScale : 0 + 'rpx #fff dashed'}">
								<image 
									v-if="item.image"
									:src='item.image' 
									:style="{width: item.width + 'px', height: item.height + 'px'}" 
									<!-- 图片点击时,记录点击图片当前位置 -->
									@touchstart="(e) => WraptouchStart(e, item)"
									<!-- 图片拖动时,记录图片当前位置,并实时计算图片大小、旋转角度等,并存储至itemList中 -->
									@touchmove="(e) => WraptouchMove(e, item)"
									<!--一般不做处理 -->
									@touchend="(e) => WraptouchEnd(e, item)"
									mode="widthFix"
								>
								</image>
								<!-- 删除按钮 -->
								<image 
									class='x' 
									src='/static/close.png' 
									:style="{transform: 'scale(' + item.oScale + ')', 'transform-origin': center}"
									@click="(e) => deleteItem(e, item)"
								>
								</image>
								<!-- 图片放缩按钮 -->
								<image 
									v-if="item.image"
									class='o' 
									src='/static/scale.png' 
									:style="{transform: 'scale(' + item.oScale + ')', 'transform-origin': center}"
									<!-- 图片点击时,记录点击图片当前坐标,半径 -->
									@touchstart="(e) => oTouchStart(e, item)"
									<!-- 图片点击时,记录点击图片当前坐标,计算新的半径(得到scale缩放比例)计算角度差,获取当前角度 -->
									@touchmove="(e) => oTouchMove(e, item)"
									@touchend="(e) => WraptouchEnd(e, item)"
								>
								</image>
							</view>
						</view>
					</block>
				</view>
							<canvas canvas-id="myCanvas" :style="
				'position:absolute;border: 2px solid red; width:' +
					imageW +
					'px;height:' +
					imageH +
					'px;top:-9999px;left:-9999px;'
			">
			</canvas>
			</view>
// 点击图片或文字
			WraptouchStart(e, it) {
				currentChoose = it
				// 循环图片数组获取点击的图片信息
				for (let i = 0; i < items.length; i++) {
					items[i].active = false;
					if (it.id == items[i].id) {
						index = i;
						items[index].active = true;
					}
				}
				// this.setData({
				//   itemList: items
				// })
				this.setList(items, 'itemList')
				// 获取点击的坐标值 lx ly是图片点击时的位置值
				items[index].lx = e.touches[0].clientX;
				items[index].ly = e.touches[0].clientY;
			},
			// 拖动图片
			WraptouchMove(e) {
				// 获取点击的坐标值 _lx _ly 是图片移动的位置值
				items[index]._lx = e.touches[0].clientX;
				items[index]._ly = e.touches[0].clientY;
				// left 是_lx 减去 lx,_ly 减去 ly,也就是现在位置,减去原来的位置。
				items[index].left += items[index]._lx - items[index].lx;
				items[index].top += items[index]._ly - items[index].ly;
				// 同理更新图片中心坐标点,用于旋转
				items[index].x += items[index]._lx - items[index].lx;
				items[index].y += items[index]._ly - items[index].ly;
				// 停止了以后,把lx的值赋值为现在的位置
				items[index].lx = e.touches[0].clientX;
				items[index].ly = e.touches[0].clientY;
				
				// this.setData({
				//   itemList: items
				// })
				this.setList(items, 'itemList')
			},
			// 放开图片
			WraptouchEnd(e, it) {
				touchNum ++
				clearTimeout(timer)
				timer = null
				timer = setTimeout(this.timeSta, 250)
			},
			// 计算坐标点到圆心的距离
			getDistancs(cx, cy, pointer_x, pointer_y) {
				var ox = pointer_x - cx;
				var oy = pointer_y - cy;
				return Math.sqrt(
					ox * ox + oy * oy
				);
			},
			/*
			*参数cx和cy为图片圆心坐标
			*参数pointer_x和pointer_y为手点击的坐标
			*返回值为手点击的坐标到圆心的角度
			*/
			countDeg(cx, cy, pointer_x, pointer_y) {
				var ox = pointer_x - cx;
				var oy = pointer_y - cy;
				var to = Math.abs(ox / oy); // 勾股定理,计算当前点距离中心点的距离。
				var angle = Math.atan(to) / (2 * Math.PI) * 360; // 计算当前角度
				if (ox < 0 && oy < 0) //相对在左上角,第四象限,js中坐标系是从左上角开始的,这里的象限是正常坐标系  
				{
					angle = -angle;
				} else if (ox <= 0 && oy >= 0) //左下角,3象限  
				{
					angle = -(180 - angle)
				} else if (ox > 0 && oy < 0) //右上角,1象限  
				{
					angle = angle;
				} else if (ox > 0 && oy > 0) //右下角,2象限  
				{
					angle = 180 - angle;
				}
				return angle; // 返回角度
			},

体验:
uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制,uni-app,微信小程序,notepad++文章来源地址https://www.toymoban.com/news/detail-707312.html

到了这里,关于uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app微信小程序-利用canvas给图片添加水印

    选择图片 → 将图片绘制到 canvas 中并绘制水印 →将添加水印的图片绘制到 canvas 中 → 将 canvas 画布转换为图片地址 → 上传/展示操作 注意:微信小程序在选择照片或者唤起相机之前需要获取相应的 权限 利用 uni.getSetting 查看用户是否调用相机的权限(有就选择图片,没有就

    2024年02月06日
    浏览(55)
  • uni-app:使用 Painter 在微信小程序将当前页面保存为图片

    手机截屏 Painter 实现 方式一:Painter Painter 是一个微信小程序组件,具体介绍和 API 请参考:GitHub文档。 在 GitHub 下载下来之后只需要将 components 下的 painter 文件夹放到项目根目录下的 wxcomponents 文件夹即可。然后就是如何在 uni-app 中使用微信小程序形式的组件,其实很简单,

    2024年02月12日
    浏览(65)
  • uni-app 微信小程序 图文生成图片 wxml-to-canvas

    在做的小程序要增加一个将文字与图片生成图片不可修改的功能,第一次做,在网上找了不少资料。参考了wxml-to-canvas | 微信开放文档  ,又看了一些相关事例,尝试写了一下。   需要准备的文件及配置项: 1、先把代码片段下载到本地 2、创建wxcomponents目录,把代码片段中的

    2024年02月09日
    浏览(46)
  • uni-app uni-file-picker文件上传实现拍摄从相册选择获取图片上传文档服务器(H5上传-微信小程序上传)

    前言 最近在使用uni-app写H5移动端,有一个从手机拍摄从相册选择获取图片上传到文档服务器功能。 查阅uni-app发现关于上传图片,uni-file-picker文件上传,uni.chooseImage,uni.uploadFile H5上传时它和pc端原理差不多,都是file对象上传,PC端是通过new file对象,uni-app是直接提供了 微信

    2024年02月15日
    浏览(88)
  • 微信小程序uni-app

    小程序 是一种不需要下载、安装即可使用的应用,它实现了应用触手可及的梦想,用户扫一扫或者搜一下就能打开应用,也实现了用完即走的理念,用户不用安装太多应用,应用随处可用,但又无须安装卸载。 微信开发文档 1、工作原理 网页开发,渲染线程和脚本是互斥的

    2024年02月10日
    浏览(119)
  • 微信小程序授权(uni-app)

    概述 为了避免重复开发,自己封装了一个通用用户授权回调方法,只需要传入需要授权的scope,权限中文描述、回调函数,就可以实现一整套小程序是否授权、打开授权设置,调用后续操作函数的工作 功能 可以根据自己的实际应用进行微调 目前使用的uni-app版本,可以根据自

    2024年02月16日
    浏览(81)
  • 语法速通 uni-app随笔【uni-app】【微信小程序】【vue】

    其中, pages 目录/ index 目录【必有】: index.js 编写业务逻辑 【初始数据,生命周期函数】 index.json 编写配置 index.wxml 编写模板 【可理解为本页html】 index.wxss 【可理解为本页css】 直接输入敲回车,连尖括号都不需要就可以标签补全 1)初始数据写死 在 index.wxml 引入变

    2024年02月12日
    浏览(165)
  • uni-app 微信小程序 激励视频广告

    封装激励视频-Ad.js 调用上面写的方法:

    2024年02月12日
    浏览(76)
  • 【uni-app微信小程序】实现支付功能

    实现微信支付功能需要在小程序后台配置支付相关信息,并且在前端代码中调用微信支付API进行支付操作。好的, uni-app微信小程序实现支付功能整体流程 大致如下: 注册微信公众平台,并完成开发者资质认证; 在微信商户平台注册商户账号,并完成商户资质认证; 在商户

    2024年02月13日
    浏览(95)
  • uni-app微信小程序使用echarts

    前言:本来是使用的ucharts,但因为无法监听图例点击交互,满足不了需求,所以只能放弃。 首先,下载echart组件。可以先随便建个文件夹,然后 npm init。接着下载依赖 然后找到 node_modulesmpvue-echarts下的文件,如图 只留下src,其他的删掉(没有用到)。然后复制 mpvue-echart

    2024年02月10日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包