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

苏州手机网站建设公司江门关键词排名工具

苏州手机网站建设公司,江门关键词排名工具,公司如何注册网站,乾县网站建设头像剪切上传 文章说明核心Api示例源码效果展示源码下载 文章说明 本文主要为了学习头像裁剪功能,以及熟悉canvas绘图和转文件的相关操作,参考教程(Web渡一前端–图片裁剪上传原理) 核心Api 主要就一个在canvas绘图的操作 context…

头像剪切上传

    • 文章说明
    • 核心Api
    • 示例源码
    • 效果展示
    • 源码下载

文章说明

本文主要为了学习头像裁剪功能,以及熟悉canvas绘图和转文件的相关操作,参考教程(Web渡一前端–图片裁剪上传原理)

核心Api

主要就一个在canvas绘图的操作
context.drawImage(image, imgX, imgY, rectangleWidth, rectangleHeight, 0, 0, canvas.width, canvas.height);

以及canvas转为file对象的操作
let formData = new FormData();
const file = new File([blob], data.selectFileName, {type: data.selectFileType})
formData.append(“file”, file);

关于其中的绘制区域的大小缩放以及移动,也算是一个小难点;一般也有另一种裁剪区域风格,即四条线风格,可通过代码进行理解

示例源码

AvatarUpload.vue

<template><div class="container"><div class="img-container"><div class="select-file" @click="selectFile" v-if="!data.selectFile"><p>jpg/png file with a size less than 5MB<em>click to upload</em></p></div><img alt="" :src="data.src" class="img" v-if="data.selectFile" draggable="false":style="{'height' : data.imgHeight }"/><div class="rectangle" v-if="data.selectFile" @mousedown="dragStart($event)" @mousemove="changePos($event)"@mousewheel="wheel($event)"></div></div><canvas width="100" height="100" class="canvas"></canvas><el-button type="primary" class="upload-button" @click="uploadAvatar">上传</el-button></div>
</template><script>
import {onBeforeUnmount, onMounted, reactive} from "vue";
import {axiosRequest, message} from "@/util/api";
import {MethodType} from "@/util/constant";export default {setup: function () {const data = reactive({src: null,imgHeight: "300px",selectFile: false,selectFileName: "",selectFileType: "",});async function selectFile() {const pickerOpts = {types: [{description: "Images",accept: {"image/*": [".png", ".jpeg", ".jpg"],},},],excludeAcceptAllOption: true,multiple: false,};try {const fileHandle = await window.showOpenFilePicker(pickerOpts);const file = await fileHandle[0].getFile();data.selectFileName = file.name;data.selectFileType = file.type;const reader = new FileReader();reader.readAsDataURL(file);reader.onload = function (e) {data.src = e.target.result;data.selectFile = true;image = new Image();image.src = e.target.result;setTimeout(() => {data.imgHeight = image.height + "px";rectangle = imgContainer.getElementsByClassName("rectangle")[0];rectangleWidth = rectangle.clientWidth;rectangleHeight = rectangle.clientHeight;context.drawImage(image, (image.width / 2 - rectangleWidth / 2), (image.height / 2 - rectangleHeight / 2), rectangleWidth, rectangleHeight, 0, 0, canvas.width, canvas.height);}, 0);};} catch (e) {if (!(e.name === 'AbortError' && e.message === 'The user aborted a request.')) {throw e;}}}let isDragging = false;let mouseUpListener;let containerX;let containerY;let imgContainer;let imgWidth;let imgHeight;let rectangle;let initialX;let initialY;let rectangleWidth;let rectangleHeight;let imgX;let imgY;let headerHeight;let canvas;let context;let image;function dragStart(e) {isDragging = true;containerX = imgContainer.offsetLeft;containerY = imgContainer.offsetTop;imgWidth = imgContainer.clientWidth;imgHeight = imgContainer.clientHeight;initialX = e.offsetX;initialY = e.offsetY;rectangle = imgContainer.getElementsByClassName("rectangle")[0];rectangleWidth = rectangle.clientWidth;rectangleHeight = rectangle.clientHeight;}function changePos(e) {if (!isDragging) {return;}const x = e.clientX - containerX - initialX + rectangleWidth / 2;const y = e.clientY - containerY - initialY - headerHeight + rectangleHeight / 2;if (x >= rectangleWidth / 2 + 3 && x < imgWidth - rectangleWidth / 2 - 2) {imgX = x - rectangleWidth / 2;rectangle.style.left = x + "px";centerX = imgX + rectangleWidth / 2;context.drawImage(image, imgX, imgY, rectangleWidth, rectangleHeight, 0, 0, canvas.width, canvas.height);}if (y >= rectangleHeight / 2 + 3 && y < imgHeight - rectangleHeight / 2 - 4) {imgY = y - rectangleHeight / 2;rectangle.style.top = y + "px";centerY = imgY + rectangleHeight / 2;context.drawImage(image, imgX, imgY, rectangleWidth, rectangleHeight, 0, 0, canvas.width, canvas.height);}}onMounted(() => {mouseUpListener = () => {isDragging = false;}document.addEventListener("mouseup", mouseUpListener);const containerList = document.getElementsByClassName("container");const container = containerList[containerList.length - 1];headerHeight = container.parentNode["getBoundingClientRect"]().y;imgContainer = container.getElementsByClassName("img-container")[0];canvas = container.getElementsByClassName("canvas")[0];context = canvas.getContext("2d");});onBeforeUnmount(() => {document.removeEventListener("mouseup", mouseUpListener);});const gap = 2;const minRange = 20;let centerX;let centerY;function wheel(e) {if (!centerX) {centerX = image.width / 2;}if (!centerY) {centerY = image.height / 2;}if (e.deltaY > 0) {if (rectangleWidth + gap >= image.width || rectangleHeight + gap >= image.height) {return;}if ((centerX - rectangleWidth / 2 - gap < 0) || (centerY - rectangleHeight / 2 - gap < 0)) {return;}rectangleWidth += gap;rectangleHeight += gap;rectangle.style.width = rectangleWidth + "px";rectangle.style.height = rectangleHeight + "px";} else {if (rectangleWidth - gap < minRange || rectangleHeight - gap < minRange) {return;}rectangleWidth -= gap;rectangleHeight -= gap;rectangle.style.width = rectangleWidth + "px";rectangle.style.height = rectangleHeight + "px";}context.drawImage(image, (centerX - rectangleWidth / 2), (centerY - rectangleHeight / 2), rectangleWidth, rectangleHeight, 0, 0, canvas.width, canvas.height);}function uploadAvatar() {if (!data.selectFile) {message("请先选择图片", "info");return;}canvas.toBlob((blob) => {let formData = new FormData();const file = new File([blob], data.selectFileName, {type: data.selectFileType})formData.append("file", file);axiosRequest(MethodType.post, "/user/uploadAvatar", formData, (res) => {message(res.data.msg, "info");});}, data.selectFileType);}return {data,selectFile,dragStart,changePos,wheel,uploadAvatar,}}
}
</script><style scoped>
.container {margin: 0 auto;padding-top: 100px;width: fit-content;user-select: none;display: flex;justify-content: center;align-items: center;
}.img-container {position: relative;width: fit-content;
}.rectangle {width: 100px;height: 100px;border: 1px dashed #409eff;position: absolute;left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);z-index: 999;box-shadow: #888888 0 0 1px 1px;cursor: pointer;
}.select-file {width: 500px;height: 300px;border: 1px dashed #dcdfe6;border-radius: 20px;display: flex;justify-content: center;align-items: center;
}.select-file:hover {border: 1px dashed #409eff;cursor: pointer;
}.select-file p {font-size: 14px;color: #606266;
}.select-file p em {color: #409eff;font-style: normal;margin-left: 5px;
}.img {border-radius: 20px;border: 1px dashed #409eff;
}.canvas {margin-left: 100px;border: 1px dashed #409eff;float: left;border-radius: 50%;
}.upload-button {position: absolute;width: 180px;height: 50px;top: 460px;font-size: 20px;
}
</style>

效果展示

在这里插入图片描述

关于裁剪区域的风格,设置为四条线可移动那种,需要改动一些代码,考虑后续补充

源码下载

参见Gitee链接(WEB-OS-SYSTEM)

http://www.hkea.cn/news/674639/

相关文章:

  • 公司网站怎么做分录it培训机构学费一般多少
  • 如何将自己做的网页做成网站绍兴seo
  • 河南省住房与城乡建设厅网站首页怎么做属于自己的网站
  • 移动端网站开发推广效果最好的平台
  • 用二级页面做网站的源代码自助建站系统破解版
  • 网站上怎么做动画广告推广策略包括哪些内容
  • 广州网站优化公司大亚湾发布
  • 广州网站开发招聘百度经验悬赏令
  • 吴江建设局网站郑州粒米seo外包
  • 建设工程合同纠纷与劳务合同纠纷seo培训教程视频
  • 找网站建设公司哪家最好沈阳市网站
  • sh域名做的好的网站什么是营销
  • 网站平台怎么做推广一站式网络推广服务
  • 百度对新网站排名问题兰州seo快速优化报价
  • 网站建设常用代码湘潭网络推广
  • 做网站上传图片一直错误好用搜索引擎排名
  • 钟祥网站建设网络推广的含义
  • 新闻类网站源码青岛官网seo
  • 网站优化哪里可以做百度营销客户端
  • 常德建设局网站北京优化网站方法
  • 用ip做网站优化手机流畅度的软件
  • 为网站添加统计媒介
  • 商业设计网站推荐互联网营销师证书是国家认可的吗
  • 做网站的是干嘛的怎样把自己的产品放到网上销售
  • 品牌型网站制作价格2022年小学生新闻摘抄十条
  • 政府网站群集约化建设网络暴力事件
  • 可以做卷子的网站游戏app拉新平台
  • 长沙优化网站关键词社区营销
  • 个人网站制作价格表重庆关键词优化
  • 网站开发ideseo优化网站模板