当前位置: 首页 > wzjs >正文

收录网站工具名者观看网站

收录网站工具,名者观看网站,php网站模板使用,wordpress免费托管序言 嘿,打工人混迹职场这么久,图片处理肯定都没少碰。不过咱说实话,大部分时候都是直接 “抄近道”,用现成的三方组件😏。就像我,主打一个会用工具,毕竟善用工具可是咱人类的 “超能力”&…

序言

嘿,打工人混迹职场这么久,图片处理肯定都没少碰。不过咱说实话,大部分时候都是直接 “抄近道”,用现成的三方组件😏。就像我,主打一个会用工具,毕竟善用工具可是咱人类的 “超能力”,不会用那可就真成 “原始人” 啦🤣。最近在搞微信小程序开发时,遇到个需求:用户上传图片得能裁剪。我瞅了瞅 UI 给的效果图,好家伙,找遍了都没发现合适的组件,这下没办法,社畜的 “使命感” 上身,只能自己动手,丰衣足食咯😅。

UI图

在这里插入图片描述

咱来拆解一下在微信小程序里实现这功能的流程。首先从上个页面调用小程序选择图片的 API——chooseMedia,这就好比打开了一个 “图片宝库”,通过它能拿到用户选好图片后的临时路径(下面咱就简称 path 啦)。接着带着这个 path “奔赴” 当前页面,然后用Canvas这个神奇的 “画布” 把图片画出来,之后还要让图片能实现移动、缩放这些 “炫酷操作”。

使用 Canvas 画出图片

选择图片这块咱就不细究啦,不是本文的 “主角”,咱直接从拿到 path 之后讲起。

第一步得初始化 Canvas,给它设定宽高。在页面加载完毕时,利用createSelectorQuery这个 “小助手”,拿到 Canvas 的宽高以及 node,然后把这些数据存好,后续其他功能计算时可得靠它们 “大显身手”。

初始化 Canvas
<canvas id="canvas" type="2d" style="width: 100%; height: 100%;"></canvas>
initCanvas() {return new Promise((resolve, reject) => {const query = wx.createSelectorQuery()query.select('#canvas').fields({ node: true, size: true }).exec((res) => {const { node, width, height } = res[0]node.width = widthnode.height = heightconst ctx = node.getContext('2d')this.setData({ 'canvas.target': node,'canvas.ctx': ctx,'canvas.width': width,'canvas.height': height})resolve()})})},

可能有的小伙伴要问了:已经设了宽高 100%,为啥还要再设置 node 呢🧐?这是因为不明确设置宽高属性,它就会用默认值,这就像你没给导航设定目的地,它可能就带你去 “奇怪的地方”,绘图效果自然就 “跑偏” 了。但 Canvas 尺寸又不是固定不变的,没法直接简单设置,所以初始化时这一步很关键哦。

初始化图片到Canvas

接下来把图片 “请” 到 Canvas 上。注意啦,图片得在 Canvas 正中间,还得完整地展示在可见区域,可不能按原图尺寸随意 “摆放”,所以得做些简单的 “数学运算”。

initImage() {return new Promise((resolve, reject) => {const { path, canvas: { target: canvas } } = this.datalet image = canvas.createImage();image.src = pathimage.onload = () => {const { ctx, width: canvasWidth, height: canvasHeight } = this.data.canvasconst scale = image.width / image.heightlet width = canvasWidthlet height = canvasWidth / scaleif (height > canvasHeight) {height = canvasHeightwidth = canvasHeight * scale}const x = (canvasWidth - width) / 2;const y = (canvasHeight - height) / 2;ctx.drawImage(image, x, y, width, height);this.setData({'image.target': image,'image.width': width,'image.height': height,'image.x': x,'image.y': y,'image.scale': scale})resolve()}})},

先用 Canvas 对象创建一个图片对象,再把 path “赋予” 它。等图片加载好,就能获取到图片尺寸,进而算出宽高比。因为要完整展示图片,所以图片高度最大就是 Canvas 的高度,宽度最大是 Canvas 的宽度。通过宽高比,就能算出当绘制宽度是 Canvas 宽度时对应的高度。然后把这个计算出的高度和 Canvas 高度对比,如果超了,就以 Canvas 高度为绘制高度,再算出相应宽度。

尺寸确定好后,最后算图片绘制的中心位置。以 Canvas 左上角为 (0,0),X 轴坐标就是 Canvas 宽度减去图片宽度再除以 2,Y 轴坐标同理。最后调用drawImage方法,图片就 “乖乖” 初始化绘制好啦。别忘了把图片相关数据存起来,后续功能还得靠它们 “帮忙” 呢。

绘制裁剪区域

再接着就是绘制裁剪区域,从 UI 图能看出,裁剪区域是正中心的一个长方形。咱先确定好这个长方形尺寸并存起来,然后利用这个尺寸在 Canvas 四周画上四个黑色遮罩长方形,这招就像 “围点打援”,简单又有效😎。

// 裁剪区域的相关数据
crop: {scale: 5 / 7,width: 200,height: 0,x: 0,y: 0,
},
// 裁剪区域尺寸等信息
getCropInfo() {const {canvas: { width: canvasWidth, height: canvasHeight },crop: { width: cropWidth, scale: cropScale }} = this.dataconst result = {scale: cropScale,width: cropWidth,height: cropWidth / cropScale,x: (canvasWidth - cropWidth) / 2,y: (canvasHeight - cropWidth / cropScale) / 2}this.setData({'crop.height': cropWidth / cropScale,'crop.x': (canvasWidth - cropWidth) / 2,'crop.y': (canvasHeight - cropWidth / cropScale) / 2,})return result},// 绘制裁剪区域drawCrop() {const { ctx, width: canvasWidth, height: canvasHeight } = this.data.canvasconst { width: cropWidth, height: cropHeight, x, y} = this.data.crop// 该方式会出现 一次绘制成功一次绘制不成功的情况// ctx.rect(0, 0, canvasWidth, canvasHeight);// ctx.rect(x, y, cropWidth, cropHeight);// ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';// ctx.fill('evenodd');ctx.rect(0, 0, canvasWidth, y);ctx.rect(0, y + cropHeight, canvasWidth, y);ctx.rect(0, y, x, cropHeight);ctx.rect(x + cropWidth, y, x, cropHeight);ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';ctx.fill()},

到这儿,基本雏形已经有啦。不过关于拖拽、缩放这些更精彩的操作,由于篇幅限制,咱下篇再继续 “揭秘”😜。

在这里插入图片描述

🦀🦀感谢看官看到这里,如果觉得文章不错的话🙌,点个关注不迷路⭐。
诚邀您加入我的微信技术交流群🎉,群里都是志同道合的开发者👨‍💻,大家能一起交流分享摸鱼🐟。期待与您在群里相见🚀,咱们携手在开发路上共同进步✨ !
👉点我

感谢各位大侠一路相伴,实在感激! 不瞒您说,在下还有几个开源项目 📦,它们就像精心培育的幼苗 🌱,急需您的浇灌。要是您瞧着还不错,麻烦动动手指,给它们点亮几颗 Star ⭐,您的支持就是它们成长的最大动力,在此谢过各位大侠啦!

  • Nova UI组件库:https://github.com/gmingchen/nova-ui
  • 基于 Vue3 + Element-plus 管理后台基础功能框架
  • 预览:https://admin.gumingchen.icu
    • Github:https://github.com/gmingchen/agile-admin
    • Gitee:https://gitee.com/shychen/agile-admin
    • 基础版后端:https://github.com/gmingchen/java-spring-boot-admin
    • 文档:http://admin.gumingchen.icu/doc/
  • 基于 Vue3 + Element-plus + websocket 即时聊天系统
    • 预览:https://chatterbox.gumingchen.icu/
    • Github:https://github.com/gmingchen/chatterbox
    • Gitee:https://gitee.com/shychen/chatterbox
  • 基于 node 开发的后端服务:https://github.com/gmingchen/node-server

文章转载自:

http://8PfHuS31.wqmyh.cn
http://PnFadSfk.wqmyh.cn
http://KCSFZf99.wqmyh.cn
http://JAVknPhq.wqmyh.cn
http://danKVCsu.wqmyh.cn
http://j9dpfk75.wqmyh.cn
http://1E2z4LhG.wqmyh.cn
http://kFPZxfr2.wqmyh.cn
http://eHj5RfzY.wqmyh.cn
http://6u4j5KsW.wqmyh.cn
http://gcDehuTE.wqmyh.cn
http://YQx6TfiU.wqmyh.cn
http://6SXMWz1L.wqmyh.cn
http://wUxPAevB.wqmyh.cn
http://8SdzaAqj.wqmyh.cn
http://79fy0mnc.wqmyh.cn
http://4rG4yYHv.wqmyh.cn
http://n9XMgGvW.wqmyh.cn
http://mGjdYLRj.wqmyh.cn
http://g49uIw2x.wqmyh.cn
http://Z6w2sWBb.wqmyh.cn
http://hEixEFuz.wqmyh.cn
http://qlMzckgJ.wqmyh.cn
http://JzQBeQfU.wqmyh.cn
http://UgFT8u76.wqmyh.cn
http://4veHNcUa.wqmyh.cn
http://DxB6AixZ.wqmyh.cn
http://jhBD2XB2.wqmyh.cn
http://EYcQYbHW.wqmyh.cn
http://l06XjRmp.wqmyh.cn
http://www.dtcms.com/wzjs/777371.html

相关文章:

  • 展示型企业网站建设wordpress添加全屏广告
  • 做公益网站有什么要求市场营销策划属于什么行业
  • 石家庄建站源码网站开发尾款如何做账
  • 网站定制分享商城类网站模板
  • 廊坊网站建设-纵横网络 网站正规的网站制作哪个好
  • 上海金桥建设监理有限公司网站网站开发 太原
  • 宁波网站推广排名淘宝如何刷关键词增加权重
  • 天津大型网站建设报价公司页面seo优化
  • 个人网站 cmswordpress数据备份还原
  • 网站制作的地方网站推广 软件
  • 苏州市建设局老网站企业网站打不开了
  • 网站模版 免费下载wordpress 有道云笔记
  • 为什么网站打开老是提示建设中wordpress 主题 相册
  • dede视频网站模板石家庄369招聘信息网
  • 网站页面如何设计接网站 建设
  • 网站建设方案打包网站建设培训班学费
  • 平度网站建设html5网站的优点
  • 网站建设项目招标书平面设计的网站
  • 奥派电子商务网站建设论文私有云可以做网站
  • ui是什么设计优化方案答案
  • 网站建设怎样找客户巴顿品牌设计
  • 创业谷网站建设方案公司建设网站流程
  • 做网站的外包能学到什么做淘宝客需要建网站吗
  • 德国设计网站大全网站建网站建设企业电话
  • 济南精品建站外包公司价格做列表的网站
  • 旅游攻略网站DW怎么做电商网站
  • 如何上传网站到凡科网下载河北公众号官方版安装
  • 宁金诚信建设网站织梦转WordPress插件
  • 拼客多网站多少钱可以做网站组建
  • 莒县建设局门户网站浙江东阳市网站建设公司