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

襄阳网站建设关于飞鱼企装网

襄阳网站建设关于飞鱼,企装网,天水网站制作,没有公司可以注册网站吗基于VueCanvas实现的画板绘画以及保存功能 本文内容设计到的画板的js部分内容来源于灵感来源引用地址#xff0c;然后我在此基础上#xff0c;根据自己的需求做了修改#xff0c;增加了其他功能。 下面展示了完整的前后端代码 这里写目录标题 基于VueCanvas实现的画板绘…基于VueCanvas实现的画板绘画以及保存功能 本文内容设计到的画板的js部分内容来源于灵感来源引用地址然后我在此基础上根据自己的需求做了修改增加了其他功能。 下面展示了完整的前后端代码 这里写目录标题 基于VueCanvas实现的画板绘画以及保存功能1. board-js.js2. 前端的vue文件3. 后端Controller 1. board-js.js 这个代码接收一个容器参数创建了一个画板类里面实现了画板会用到的基本方法保存到单独的js文件在vue文件中导入创建一个画板对象。 Canvas直接使用canvas.toDataURL()保存的图片是没有背景的因为默认的是png所以需要开始绘画之前先填充背景下面代码做出了修改在init函数中。 代码中用到的Canvas的原生API的作用可以参考这里Canvas参考手册 export default class BoardCanvas {constructor(container) {// 容器this.container container// canvas画布this.canvas this.createCanvas(container)// 绘制工具this.ctx this.canvas.getContext(2d)// 起始点位置this.startX 0this.stateY 0// 画布历史栈this.pathSegmentHistory []this.index 0// 初始化this.init()}// 创建画布createCanvas(container) {const canvas document.createElement(canvas)canvas.width container.clientWidthcanvas.height container.clientHeightcanvas.style.display blockcanvas.style.backgroundColor whitecontainer.appendChild(canvas)return canvas}// 初始化init() {this.addPathSegment()this.setContext2DStyle()//下面两行原文件是没有的如果没有会导致保存的图片没有背景只有绘画轨迹this.ctx.fillStyle #ffffff;this.ctx.fillRect(0, 0,this.canvas.width, this.canvas.height);this.canvas.addEventListener(contextmenu, e e.preventDefault())this.canvas.addEventListener(mousedown, this.mousedownEvent.bind(this))window.document.addEventListener(keydown, this.keydownEvent.bind(this))}// 设置画笔样式setContext2DStyle() {this.ctx.strokeStyle blackthis.ctx.lineWidth 3this.ctx.lineCap roundthis.ctx.lineJoin round}// 鼠标事件mousedownEvent(e) {const that thisconst ctx this.ctxctx.beginPath()ctx.moveTo(e.offsetX, e.offsetY)ctx.stroke()this.canvas.onmousemove function (e) {ctx.lineTo(e.offsetX, e.offsetY)ctx.stroke()}this.canvas.onmouseup this.canvas.onmouseout function () {that.addPathSegment()this.onmousemove nullthis.onmouseup nullthis.onmouseout null}}// 键盘事件keydownEvent(e) {if(!e.ctrlKey) returnswitch(e.keyCode) {case 90:this.undo()breakcase 89:this.redo()break}}// 添加路径片段addPathSegment() {const data this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height)// 删除当前索引后的路径片段然后追加一个新的路径片段更新索引this.pathSegmentHistory.splice(this.index 1)this.pathSegmentHistory.push(data)this.index this.pathSegmentHistory.length - 1}// 撤销undo() {if(this.index 0) returnthis.index--this.ctx.putImageData(this.pathSegmentHistory[this.index], 0, 0)}// 恢复redo() {if(this.index this.pathSegmentHistory.length - 1) returnthis.indexthis.ctx.putImageData(this.pathSegmentHistory[this.index], 0, 0)}//获取画布内容getImage() {return this.canvas.toDataURL();}//清空画板cleanboard(){this.ctx.fillStyle #ffffff;this.ctx.fillRect(0, 0,this.canvas.width, this.canvas.height);} } 2. 前端的vue文件 templateel-container directionvertical styleheight: 100%;width: 100%!--头顶布局用户操作提示语--el-header height10%h2在空白处进行绘画/h2/el-header!--中间布局 --div styledisplay:flex;justify-content:center;align-items:center;!--中间画板--div classdrawing-boardstylewidth:66%;height:600px;border: 1px black solid;margin-left: 10pxdiv idcontainer refcontainer stylewidth: 100%; height: 100%/div/div/div!--底部按钮--el-footer styleheight: 300px;margin-top: 25pxel-button typeprimary round clicksavedrawing保存/el-button/el-footer/el-container /template//这里使用的vue的setup语法糖所以data和method不需要封装直接用 script setup import { ref, onMounted } from vue import Board from /js/drawing-board.js import axios from axios;const container ref(null) let drawboard null; onMounted(() {// 新建一个画板drawboardnew Board(container.value) }) function savedrawing() {const drawdata drawboard.getImage(); let formdata new FormData();const timestamp (new Date()).valueOf();let filename timestamp;formdata.append(drawPictureId,filename);formdata.append(drawPictureData,drawdata.substring(22));axios({method:post,url:/savedrawdata,baseURL:http://localhost:9999,data:formdata,contentType:false,processData:false}).then(response{if(response.status200){alert(保存成功!)}}).catch(error{console.log(error);}) } /script3. 后端Controller Controller文件中前端使用FormData格式传递参数就相当于是个map键值对所以在参数这里使用 RequestParam() ,取出表单中的值括号中的字符串是在前端传入的表示将该key对应的value赋值给后面的String 参数。 其次这里注意Canvas得到的图片是经过base64编码过的所以先解码成字节数组 RequestMapping(/savedrawdata)public ResponseEntity? savedrawdata(RequestParam(drawPictureId)String drawPictureId,RequestParam(drawPictureData)String drawPictureData){try {// 解码前端传过来的base64编码byte[] imageBytes Base64.decodeBase64(drawPictureData);// 将字节流转为图片缓冲流BufferedImage bufferedImage ImageIO.read(new ByteArrayInputStream(imageBytes));// 保存为pngFile output new File(F:\\image\\ drawPictureId .png);ImageIO.write(bufferedImage, png, output);} catch (IOException e) {e.printStackTrace();}System.out.println(rawPictureId);System.out.println(drawPictureId);return ResponseEntity.ok(HttpStatus.OK);}
http://www.pierceye.com/news/954675/

相关文章:

  • 偏门网站建设做的网站被挂马
  • 三五互联网站自己做一个网站需要什么
  • wordpress博客网站深圳建工集团
  • 罗永浩做的网站房产网站设计方案
  • 创建个人网站多少钱模板速成网站
  • 晋江做网站的公司哪家好企业网站报价
  • 百度权重查询网站旅游公司的网站怎么做
  • 品牌网站建设小蝌蚪2a西安中交建设集团网站
  • 潍坊网页网站制作优畅 wordpress
  • 搜狗收录网站网站制作费用预算表
  • dede网站安全长沙营销型
  • 那些做电影视频网站的赚钱吗邯郸网站建设方案
  • 在线做app的网站wordpress 产品分类
  • seo网站建设规划网站模板视频教程
  • 沈阳网站制作策划wordpress 文章页调用
  • 网站开发和网络工程师方法网站目录
  • 用dw做网站的好处网页美工培训中心
  • 中文域名注册 .网站网站英文地图怎么做
  • 汽车行业网站建设维护服务wordpress改投票系统
  • 网站快照长期不更新wordpress 顶部高度
  • 雨颜色网站建设电器类网站设计
  • 网站建设模块化实现企业网站建设范文
  • 网站培训班有哪些课程中国工程建设标准化协会官方网站
  • 医院网站建设 费用做商业网站
  • 网站设计考虑因素wordpress录入表单写数据库
  • 个人博客网站设计网站优化方式有哪些
  • 网站建设文化教程网站开发建设成本
  • 洛阳做网站公司汉狮价格wordpress移动端悬浮导航
  • 免费网站的代码wordpress给分类添加自定义栏目
  • 网站建设额怎么自己做网站app