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

canvas根据坐标点位画图形-canvas拖拽编辑单个图形形状

  1. 首先在选中图形的时候需要用鼠标右击来弹出选择框,实现第一个编辑节点功能
    在这里插入图片描述
  • 在components文件夹下新建右键菜单
    在这里插入图片描述
  • RightMenu文件:
<template><div v-show="show" class="right-menu" :style="'top:'+this.y+'px;left:'+this.x+'px'"><div @click="handelMenu('editPoint')">编辑节点</div><div @click="handelMenu('stretch')">拉伸</div><div @click="handelMenu('rotate')">旋转</div><div @click="handelMenu('copy')">复制</div><div @click="handelMenu('paste')">粘贴</div><div @click="handelMenu('delete')">删除</div></div>
</template><script>export default {data() {return {show: false,x: 0,y: 0,}},methods: {showModal(x,y) {this.x = x;this.y = y;this.show = true;},handelMenu(e) {this.hideMenu();this.$emit('backRightMenu',e);},hideMenu() {this.show = false;}}}
</script><style scoped>.right-menu {width: 100px;position: relative;background: #fff;min-height: 50px;}.right-menu>div {height: 30px;line-height: 30px;border-bottom: 1px solid rgb(228, 235, 249);padding: 0 10px;font-size: 13px;cursor: pointer;}
</style>
  • 在页面中使用:
<right-menu ref="RightMenu" @backRightMenu="backRightMenu"></right-menu>import RightMenu from '@/components/RightMenu/index';components: {RightMenu
},
  • 在data中定义所需要的变量
rightMenuType: '', //可操作图形状态
isRightMenu: false, //是否可以操作图形
  1. 鼠标右击的时候打开右键菜单
//鼠标右击
rightMenu(e) {if (this.type === 'move' && this.activeData.length > 0 && this.rightMenuType === '') {this.$refs.RightMenu.showModal(e.offsetX, e.offsetY);} else {return;}
},
  1. 点击选择选项接收值
//右键菜单返回
backRightMenu(e) {this.rightMenuType = e;this.isRightMenu = true;//编辑图形switch (e) {case 'editPoint':this.redrawMap();break;}
}
  1. redrawMap重绘过程中判断如果在编辑图形的状态,就选中图形并且图形顶点高亮
if(this.activeData.length > 0 && this.isRightMenu) {//编辑图形switch (this.rightMenuType) {case 'editPoint':drawMap.drawRectangle(this.activeData, 'editPoint');break;}
}
  • 效果如下:
    在这里插入图片描述
  1. 接下来实现吸附顶点,首先鼠标移动过程中判断是否吸附顶点,吸附状态下拖动点位可以更改图形点位坐标
// 开启吸附功能 记录是否处于吸附状态
if (this.activeData.length > 0 && ['editPoint'].includes(this.rightMenuType)) {this.activeData.map((item, idx) => {let result = mathUtils.attractPixel([x, y], item)if(result.isAttract && this.isMouseClick) {if(idx === 0 || idx === this.activeData.length - 1) {this.$set(this.activeData,this.activeData.length - 1,[x,y]);}this.$set(this.activeData,idx,[x,y]);}})
}
  • 涉及的算法:
// 计算两点距离
dealLength(start, end) {var a = end.x - start.x;var b = end.y - start.y;return Math.sqrt(a * a + b * b);
},
// 鼠标点击位置和目标点相距<=吸附半径则吸附到目标点
attractPixel(point1, pointTarget, pixelArea = adsorptionDistance) {const len = this.dealLength({x: point1[0],y: point1[1]}, {x: pointTarget[0],y: pointTarget[1]})const finalPoint = len <= pixelArea ? pointTarget : point1const isAttract = len <= pixelAreareturn {finalPoint,isAttract}
},
  • 效果如下:
    在这里插入图片描述
  1. 接下来实现在鼠标按下过程中如果触碰了图形的边线,就给点击边线的位置插入一个点位,形成多边形
//鼠标按下判断选中边线按下插入节点
if (this.activeData.length > 0 && ['editPoint'].includes(this.rightMenuType)) {const pointData = mathUtils.attractOnCheckLine({x,y}, this.activeData);if(pointData && pointData.overIdx >= 0) {this.activeData.splice(pointData.overIdx + 1, 0, [x, y])}
}
  • 效果如下:
    在这里插入图片描述
  • 涉及算法:
// 计算当前点到所有线段的垂点,小于5px,则吸附
attractOnCheckLine(point, coordinates) {for (var i = 0; i < coordinates.length; i++) {if (this.checkPoint(coordinates[i], point)) {return {x: coordinates[i][0],y: coordinates[i][1],idx: i};}}for (var i = 0; i < coordinates.length - 1; i++) {var pt = this.pointToSegDist(point.x, point.y, coordinates[i][0], coordinates[i][1],coordinates[i + 1][0], coordinates[i + 1][1], Math.pow(adsorptionDistance, 2));if (pt) {pt.overIdx = ireturn pt;}}return null;
},
checkPoint(target, point) {if (point.x >= target[0] - adsorptionDistance &&point.x <= target[0] + adsorptionDistance &&point.y >= target[1] - adsorptionDistance &&point.y <= target[1] + adsorptionDistance) {return true;} else {return false;}
},
pointToSegDist(x, y, x1, y1, x2, y2, dist) {var cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);if (cross <= 0) return null;var d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);if (cross >= d2) return null;var r = cross / d2;var px = x1 + (x2 - x1) * r;var py = y1 + (y2 - y1) * r;var dis = (x - px) * (x - px) + (py - y) * (py - y);if (dis <= dist) { // adsorptionDistance * adsorptionDistancereturn {x: px,y: py};}
},
  • 接下来插入的点位也可以进行拖拽了,大功告成!!!
    在这里插入图片描述

本节其他文件附下,复制可用:

  • 首页
<template><div id="app"><div class="nav-top"><div :class="{'nav-sel':type==='move'}" @click="setType('move')">选择</div><div :class="{'nav-sel':type==='rectangle'}" @click="setType('rectangle')">矩形</div><div :class="{'nav-sel':type==='circle'}" @click="setType('circle')">圆形</div></div><div class="draw-box" ref="drawBox"><canvas class="canvas-style" ref="canvasMap" @click="mapClick" @mousedown="mapMousedown"@mousemove="mapMousemove" @mouseup="mapMouseUp" @dblclick="mapDbclick"@mousewheel.prevent="mapMouseWheel" @contextmenu.prevent="rightMenu"></canvas></div><right-menu ref="RightMenu" @backRightMenu="backRightMenu"></right-menu></div>
</template><script>import drawMap from '@/utils/drawMap.js';import mathUtils from '@/utils/mathUtils.js';import RightMenu from '@/components/RightMenu/index';export default {name: 'app',data() {return {type: 'rectangle', //当前可编辑图形的状态mouseStartPos: [], //鼠标点击的位置mouseMovePos: [0, 0], //鼠标移动位置与图形中心点位置的差值mouseClickArr: [], //当前已点击的坐标记录drawAllData: [], //当前所有保存的数据activeData: [], //当前选中的图形坐标数据isMouseClick: false, //是否按住鼠标左键nowScale: 100, //初始化滚动大小lastScale: 100, //最后一次滚动大小rightMenuType: '', //可操作图形状态isRightMenu: false, //是否可以操作图形}},components: {RightMenu},mounted() {//初始化画板const initData = {id: this.$refs.canvasMap,w: this.$refs.drawBox.clientWidth,h: this.$refs.drawBox.clientHeight}drawMap.initMap(initData);this.redrawMap();},methods: {//单击地图mapClick(e) {let x = e.offsetXlet y = e.offsetY//非操作点击空白//点击地图加入点位switch (this.type) {case 'rectangle':this.mouseClickArr.push([x, y])if (this.mouseClickArr.length === 3) {this.drawRectangle(this.mouseClickArr)this.redrawMap()this.mouseClickArr = []}break;}},//鼠标按下mapMousedown(e) {let x = e.offsetXlet y = e.offsetYif (e.button === 2) {// 鼠标右击this.redrawMap()return}this.mouseStartPos = [e.offsetX, e.offsetY]this.isMouseClick = true; //鼠标左键已按下,可以进行平移操作//鼠标按下判断选中边线按下插入节点if (this.activeData.length > 0 && ['editPoint'].includes(this.rightMenuType)) {const pointData = mathUtils.attractOnCheckLine({x,y}, this.activeData);if(pointData && pointData.overIdx >= 0) {this.activeData.splice(pointData.overIdx + 1, 0, [x, y])}}if (this.type === 'move' && this.isMouseClick) {let activePoint = []if (this.drawAllData.length > 0) {for (const [i, item] of this.drawAllData.entries()) {mathUtils.pointInPolygonORLine(this.mouseStartPos, item) === true ? activePoint = item : []}}if (this.activeData.length > 0 && !mathUtils.pointInPolygonORLine(this.mouseStartPos, this.activeData)) {this.drawAllData = this.drawAllData.concat([this.activeData])this.activeData = [];} else if (this.activeData.length === 0) {this.activeData = activePoint;this.drawAllData = this.drawAllData.filter(item => {return item !== this.activeData})}this.redrawMap();}},//鼠标移动mapMousemove(e) {let x = e.offsetXlet y = e.offsetY// 开启吸附功能 记录是否处于吸附状态if (this.activeData.length > 0 && ['editPoint'].includes(this.rightMenuType)) {this.activeData.map((item, idx) => {let result = mathUtils.attractPixel([x, y], item)if(result.isAttract && this.isMouseClick) {if(idx === 0 || idx === this.activeData.length - 1) {this.$set(this.activeData,this.activeData.length - 1,[x,y]);}this.$set(this.activeData,idx,[x,y]);}})}//鼠标移动中判断当前是否状态是move,activeData当前选中是否有数据,isMouseClick当前是否可以移动 isRightMenu当前是否不能编辑图形if (this.type === 'move' && this.activeData.length > 0 && this.isMouseClick && !this.isRightMenu) {//获取图形中心位置const center = mathUtils.getPolygonCenter(this.activeData);//计算点击位置与图形中心位置的差值,如果差值大于0或小于0代表移动了this.mouseMovePos = [x - center[0], y - center[1]]//移动图形this.movePoint(this.mouseMovePos, this.activeData)}this.redrawMap({x,y})},//鼠标抬起mapMouseUp(e) {this.isMouseClick = false; //禁止移动this.mouseStartPos = []; //抬起后开始点击位置清空this.mouseMovePos = [0, 0]; //清空两次点位的差值,按下后重新计算},//鼠标双击mapDbclick(e) {console.log('鼠标双击', e);},//鼠标滚轮mapMouseWheel(e) {if (this.activeData.length === 0) return;const wheelDelta = e.wheelDelta //滚轮上下滚动的数值,默认为0,正数为向上滚动,负数为向下滚动const interval = this.nowScale <= 50 ? 25 : 50if (wheelDelta > 0) {if (this.nowScale >= 1600) {this.nowScale = 1600return}this.nowScale = parseInt(this.nowScale + 1 * this.nowScale / interval)} else {if (this.nowScale <= 25) {this.nowScale = 25return}this.nowScale = parseInt(this.nowScale - 1 * this.nowScale / interval)}this.redrawMap()},//鼠标右击rightMenu(e) {if (this.type === 'move' && this.activeData.length > 0 && this.rightMenuType === '') {this.$refs.RightMenu.showModal(e.offsetX, e.offsetY);} else {return;}},async redrawMap(point) {//canvas重绘drawMap.redrawMap();//保存滚动后的数据this.savePointData();//实时画鼠标点位point && point.x && drawMap.drawCircle({x: point.x,y: point.y,r: 4,fillStyle: '#fff'})//绘制已经保存的房间数据if (this.drawAllData.length > 0) {for (const [i, item] of this.drawAllData.entries()) {drawMap.drawRectangle(item);}}//绘制正在编辑的数据if (this.activeData.length > 0) {drawMap.drawRectangle(this.activeData, true);}//实时的画各类图形point && point.x && this.drawNowDrawing(point.x, point.y);if(this.activeData.length > 0 && this.isRightMenu) {//编辑图形switch (this.rightMenuType) {case 'editPoint':drawMap.drawRectangle(this.activeData, 'editPoint');break;case 'stretch':break;case 'rotate':break;case 'copy':break;case 'paste':break;case 'delete':break;}}},//保存数据savePointData() {if (this.activeData.length > 0) {const oCenter = mathUtils.getPolygonCenter(this.activeData);this.activeData = mathUtils.scalePoint(this.activeData, this.nowScale / this.lastScale, oCenter);this.lastScale = this.nowScale} else {this.nowScale = 100;this.lastScale = 100;}},//实时画图形drawNowDrawing(x, y) {switch (this.type) {case 'rectangle':if (this.mouseClickArr.length >= 1) {const mouseClick = this.mouseClickArr.length === 1 ? [[x, y],[x, y]] : [[x, y]]const newArr = this.mouseClickArr.concat(mouseClick)this.drawRectangle(newArr)}break;}},//画矩形drawRectangle(arr) {// 画矩形,点选三个点完成一个矩形const vPoint = mathUtils.calculateVerticalPoint(arr);// 根据第一点算的为第四点 根据第二点算的为第三点const point4 = mathUtils.calculatePoint(vPoint, arr[0], arr[2]);const point3 = mathUtils.calculatePoint(vPoint, arr[1], arr[2]);const rectangleData = [arr[0], arr[1], point3, point4, arr[0]];if (this.mouseClickArr.length === 3) {this.drawAllData = this.drawAllData.concat([rectangleData])}drawMap.drawRectangle(rectangleData);},//图形平移,通过差值计算点位坐标movePoint(movePos, data) {this.activeData = data.map(item => {return [item[0] + movePos[0], item[1] + movePos[1]]})},//设置可编辑类型setType(e) {this.type = e},//右键菜单返回backRightMenu(e) {this.rightMenuType = e;this.isRightMenu = true;//编辑图形switch (e) {case 'editPoint':this.redrawMap();break;case 'stretch':break;case 'rotate':break;case 'copy':break;case 'paste':break;case 'delete':break;}}}}
</script><style>html,body {margin: 0;padding: 0;}.nav-top {display: flex;align-items: center;}.nav-top>div {padding: 10px;border: 1px solid;border-radius: 8px;margin-right: 20px;cursor: pointer;}.nav-top .nav-sel {border: 2px solid #18c1f6;}.draw-box {width: 100vw;height: calc(100vh - 64px);background: #F1F2F6;position: fixed;bottom: 0;}.hidden-icon {position: absolute;top: 0;z-index: -100;left: 0;visibility: hidden;}.del-icon {width: 16px;transform: translate(-8px, -8px);user-select: none;}
</style>
  • mathUtils.js
import * as turf from "@/utils/turf.es";let adsorptionDistance = 6
const mathUtils = {// 计算两点距离dealLength(start, end) {var a = end.x - start.x;var b = end.y - start.y;return Math.sqrt(a * a + b * b);},// 计算点到线垂点的方法calculateVerticalPoint(arr) {const point = arr[2]var x1 = arr[0][0];var y1 = arr[0][1];var x2 = arr[1][0];var y2 = arr[1][1]if (x1 == x2 && y1 == y2) {return [point[0], point[1]];}var m = point[0];var n = point[1];var a = y2 - y1;var b = x1 - x2;var c = x2 * y1 - x1 * y2;var x3 = (b * b * m - a * b * n - a * c) / (a * a + b * b);var y3 = (a * a * n - a * b * m - b * c) / (a * a + b * b);return [Math.round(x3 * 100) / 100, Math.round(y3 * 100) / 100];},// 根据垂点计算平行点calculatePoint(vPoint, point, point2) {const x = point[0] - vPoint[0] + point2[0]const y = point[1] - vPoint[1] + point2[1]return [x, y]},// 判断点是否在多边形内部或者线上pointInPolygonORLine(point, polygon) {var pt = turf.point(point);var poly = turf.polygon([polygon]);return turf.booleanPointInPolygon(pt, poly)},// 获取多边形的中心点getPolygonCenter(arr) {var polygon = turf.polygon([arr]);var center = turf.centerOfMass(polygon);return center.geometry.coordinates},// 获取缩放后的坐标scalePoint(oGeo, scale, oCenter) {const newGeo = []const moveX = oCenter[0] * scale - oCenter[0]const moveY = oCenter[1] * scale - oCenter[1]for (var item of oGeo) {const x = item[0] * scale - moveXconst y = item[1] * scale - moveYnewGeo.push([x, y])}return newGeo},// 鼠标点击位置和目标点相距<=吸附半径则吸附到目标点attractPixel(point1, pointTarget, pixelArea = adsorptionDistance) {const len = this.dealLength({x: point1[0],y: point1[1]}, {x: pointTarget[0],y: pointTarget[1]})const finalPoint = len <= pixelArea ? pointTarget : point1const isAttract = len <= pixelAreareturn {finalPoint,isAttract}},// 计算当前点到所有线段的垂点,小于5px,则吸附attractOnCheckLine(point, coordinates) {for (var i = 0; i < coordinates.length; i++) {if (this.checkPoint(coordinates[i], point)) {return {x: coordinates[i][0],y: coordinates[i][1],idx: i};}}for (var i = 0; i < coordinates.length - 1; i++) {var pt = this.pointToSegDist(point.x, point.y, coordinates[i][0], coordinates[i][1],coordinates[i + 1][0], coordinates[i + 1][1], Math.pow(adsorptionDistance, 2));if (pt) {pt.overIdx = ireturn pt;}}return null;},checkPoint(target, point) {if (point.x >= target[0] - adsorptionDistance &&point.x <= target[0] + adsorptionDistance &&point.y >= target[1] - adsorptionDistance &&point.y <= target[1] + adsorptionDistance) {return true;} else {return false;}},pointToSegDist(x, y, x1, y1, x2, y2, dist) {var cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);if (cross <= 0) return null;var d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);if (cross >= d2) return null;var r = cross / d2;var px = x1 + (x2 - x1) * r;var py = y1 + (y2 - y1) * r;var dis = (x - px) * (x - px) + (py - y) * (py - y);if (dis <= dist) { // adsorptionDistance * adsorptionDistancereturn {x: px,y: py};}},
}export default mathUtils;
  • drawMap.js
let ctxDom, mapCtx; //初始化必要参数const drawMap = {//初始化地图initMap({id,w,h} = obj) {ctxDom = idid.width = wid.height = hmapCtx = id.getContext("2d");},//地图重绘redrawMap() {mapCtx.clearRect(0, 0, ctxDom.width, ctxDom.height);},//画圆drawCircle({x,y,r,strokeStyle = '#1289ff80', //边框色fillStyle = '#fff0', //填充色} = obj) {mapCtx.beginPath();mapCtx.fillStyle = fillStyle;mapCtx.setLineDash([]);mapCtx.strokeStyle = strokeStylemapCtx.arc(x, y, r, 0, 2 * Math.PI);mapCtx.closePath();mapCtx.stroke();mapCtx.fill();},drawRectangle(arr, isCheck) {mapCtx.strokeStyle = isCheck ? '#1289ff' : '#1289ff80';mapCtx.fillStyle = isCheck ? '#ffffff80' : '#fff0';mapCtx.lineWidth = 2;mapCtx.setLineDash([]);mapCtx.lineJoin = 'bevel';mapCtx.beginPath();mapCtx.moveTo(arr[0][0], arr[0][1]);for (let i = 1; i < arr.length; i++) {mapCtx.lineTo(arr[i][0], arr[i][1]);}mapCtx.stroke();mapCtx.fill();if (isCheck == 'editPoint') {for (let i = 0; i < arr.length; i++) {this.drawCircle({x: arr[i][0],y: arr[i][1],r: 3,strokeStyle: '#1289ff80',fillStyle: '#fff'})}}},
}export default drawMap

组件页请参考顶部!!!

相关文章:

canvas根据坐标点位画图形-canvas拖拽编辑单个图形形状

首先在选中图形的时候需要用鼠标右击来弹出选择框&#xff0c;实现第一个编辑节点功能 在components文件夹下新建右键菜单 RightMenu文件&#xff1a; <template><div v-show"show" class"right-menu" :style"top:this.ypx;left:this.xpx…...

JavaEE 初阶 — 确认应答机制

文章目录确认应答机制&#xff08;安全机制&#xff09;1 什么是后发先至问题1 如何解决后发先至问题确认应答机制&#xff08;安全机制&#xff09; 确认应答 是实现可靠传输的最核心机制。 这里指的 可靠传输 不是说 100% 可以把消息发给接收方&#xff0c;而是尽力而为&…...

0207 事件

事件监听事件监听版本事件类型事件概念事件在编程时系统内发生的动作或者发生的事情例子点击按钮鼠标经过拖拽鼠标事件监听&#xff08;注册事件&#xff0c;绑定事件&#xff09;让程序员检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函数做出响应…...

SpringBoot整合Swagger

目录 一、swagger介绍 二、springboot集成swagger 1、创建一个springboot-web项目 2、导入相关依赖 3、编写一个Hellow工程 4、配置swagger --->config 5、启动springboot工程 6、配置swagger信息 7、配置swagger扫描接口 8、如何设置Swagger在生产环境中使用&…...

20230210英语学习

Why Do So Many Cats Have White ‘Socks’ on Their Paws? 为什么好多猫咪脚上都“穿着白袜子”&#xff1f; If you see a house cat, the odds are high that it will have white paws, a look that many owners affectionately call "socks."But socks are rar…...

【图像处理OpenCV(C++版)】——4.5 全局直方图均衡化

前言&#xff1a; &#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; &#x1f31f;&#x1f31f;&#x1f31f; 本专栏主要结合OpenCV和C来实现一些基本的图像处理算法并详细解释各参数含义&#xff0c;适用于平时学习、工作快…...

2022年API安全研究报告

目录 导读 2022年API安全风险概况 2022年平均每月遭受攻击的API数量超21万...

【内网安全-横向移动】基于SMB协议-PsExec

目录 一、SMB协议 1、简述&#xff1a; 2、工具&#xff1a; 二、PsExec 1、简述&#xff1a; 2、使用&#xff1a; 1、常用参数&#xff1a; 2、情况&#xff1a; 3、插件 三、PsExec&#xff08;impacket&#xff09; 1、简述&#xff1a; 1、impacket&#xff1…...

whistle 一个神奇的前端调试工具(抓包\代理工具)

在进行前端开发过程中&#xff0c;我们常常需要对一些接口进行处理&#xff0c;以及当后端接口没有弄好需要我们mock一些假数据&#xff0c;针对这些场景&#xff0c;我们就可以使用whistle 来解决。首先&#xff0c;我们要知道能满足我们需求的工具有很多&#xff0c;例如&…...

node.js下载和vite项目创建以及可能遇到的错误

目录 一、node.js的下载 1、去官网下载 节点.js (nodejs.org) 2、下载过程 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a; 第五步: 二、vite项目的创建&#xff08;使用的工具是Hbuilder x&#xff09; 第一步&#xff1a; 出现报错…...

如何使用python画一个爱心

1 问题 如何使用python画一个爱心。 2 方法 桌面新建一个文本文档&#xff0c;文件后缀改为.py&#xff0c;输入相关代码ctrls保存&#xff0c;关闭&#xff0c;最后双击运行。 代码清单 1 from turtle import * def curvemove(): for i in range(200): right(1) …...

1 Flutter UI Container和 Text 和图片组件

一 Text 组件Text 文本组件的一些属性如下body: const Text("this is leonardo fibonacci",// 文本对齐的方式textAlign: TextAlign.center,// 文本方向textDirection: TextDirection.rtl,// 字体显示最大的行数maxLines: 2,// 文字超出屏幕之后的显示方式 ellipsi…...

【Hello Linux】 Linux基础命令(持续更新中)

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍Linux的基础命令 Linux基础命令ls指令lsls -als -dls -ils -sls -lls -nls -Fls -rls -tls -Rls -1总结思维导图pwd指令whoami指令…...

记录一下slf4j2打印一直不成功

整理一个之前的老项目问题&#xff0c;发现日志一直打印不出来&#xff0c;本地启动发现了第一个问题日志如下&#xff1a;此处可发现&#xff0c;jar包冲突问题&#xff0c;去掉冲突的jar包即可&#xff0c;此处不做过多赘述。然后发现了重新启动项目&#xff0c;发现jar包冲突…...

【安全知识】——对Linux密码文件的处理

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 一切为了她座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日emo&#xff1a;他既乐观又悲观&#xff0c;生活也一无是处昨天在挖掘…...

动手深度学习笔记(四十七)8.3. 语言模型和数据集

动手深度学习笔记(四十七)8.3. 语言模型和数据集 8.3. 语言模型和数据集8.3. 语言模型和数据集 在 8.2节中, 我们了解了如何将文本数据映射为词元, 以及将这些词元可以视为一系列离散的观测,例如单词或字符。 假设长度为 T T T的文本序列中的词元依次为 x 1 , x...

URL编码和Base64编码

URL编码和Base64编码前言一、URL编码1. URLEncoder和URLDecoder2. URL编码规则3. Javascript 原生提供三对 Url编码 的函数3.1 三对函数的不同点二、Base64编码1. Base64编码规则2. Base64编码使用3. JavaScript 原生提供两个 Base64 相关的方法总结前言 数据操作过程中&#…...

Flink 滚动窗口、滑动窗口详解

1 滚动窗口(Tumbling Windows) 滚动窗口有固定的大小&#xff0c;是一种对数据进行“均匀切片”的划分方式。窗口之间没有重叠&#xff0c;也不会有间隔&#xff0c;是“首尾相接”的状态。如果我们把多个窗口的创建&#xff0c;看作一个窗口的运动&#xff0c;那就好像它在不…...

想要精通算法和SQL的成长之路 - 柱状图中最大的矩形

想要精通算法和SQL的成长之路 - 柱状图中最大的矩形前言一. 柱状图中最大的矩形前言 想要精通算法和SQL的成长之路 - 系列导航 一. 柱状图中最大的矩形 原题链接 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。求…...

网络安全实验室5.上传关

5.上传关 1.请上传一张jpg格式的图片 url&#xff1a;http://lab1.xseclab.com/upload1_a4daf6890f1166fd88f386f098b182af/ 上传一张后缀名为jpg的图片&#xff0c;上传抓包修改后缀名为别的&#xff0c;s或者直接删掉&#xff0c;放包 得到key is IKHJL9786#$%^& 2.请…...

JavaScript 严格模式(use strict)

文章目录JavaScript 严格模式(use strict)使用 "use strict" 指令严格模式声明严格模式的限制保留关键字JavaScript 严格模式(use strict) JavaScript 严格模式&#xff08;strict mode&#xff09;即在严格的条件下运行。 使用 “use strict” 指令 “use strict”…...

硬件设计—高性能ADC前端电路

高性能模数转换器&#xff08;ADC&#xff09;一般对系统的性能有非常高的要求&#xff0c;而AD芯片的“前端”的输入电路设计对ADC系统的的性能有非常大的影响。以下主要介绍了ADC芯片前端输入使用放大器和变压器各自的优势。 1、放大器和变压器根本区别 放大器是有源器件&am…...

详讲常见的字符函数

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;C语言航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&a…...

for循环中异步请求问题:循环里面使用异步函数,如何等所有的异步函数都执行完再进行下一步

场景是这样的&#xff1a; 在一个列表循环里&#xff0c;对数据进行赋值&#xff0c;调用接口&#xff0c;循环外后面的代码需等待所有请求执行完成后再去执行。 1. Promise.all实现 Promise.all() 方法接收一个 promise 的 iterable 类型&#xff08;注&#xff1a;Array&am…...

【iOS-系统框架】

文章目录前言47.熟悉系统框架CoreFoundation框架其他框架要点48. 多用块枚举&#xff0c;少用for循环for循环NSEnumerator遍历快速遍历基于块的遍历方式要点49.对自定义其内存管理语义的collection使用无缝桥接要点50.构建缓存时选用NSCache而非NSDictionaryNSCacheNSCache实例…...

Android APK 签名打包原理分析(二)【Android签名原理】

说到签名,从这个词来理解,正常个人需要签名的时候,一般是用来证明这是某个人的特属认证。 大家是否有印象?还记得我们之前在学习、总结网络相关知识的时候,说到过,客户端和服务端虽然通信数据上,可以采用对称加密和非对称加密组合去进行数据的加密,但是这时还有一个问题…...

linux判断文件不存在退出jenkins编译流程

# linux判断文件不存在退出jenkins编译流程 file"${WORKSPACE}/mc/jenkins_arm64.sh" if [ ! -f "$file" ]; then echo "jenkins_arm64.sh not exist" exit 0 fi dir(charge){checkout([$class: GitSCM, branches: [[name: …...

shell脚本(语法)

一、什么是shell脚本 1.1、shell 的两层含义&#xff1a;既是一种应用程序,又是一种程序设计语言 1.1.1、shell是一种应用程序 交互式地解释、执行用户输入的命令&#xff0c;将用户的操作翻译成机器可以识别的语言&#xff0c;完成相应功能称之为 shell 命令解析器。 shell 是…...

java高频面试题(2023最新)

目录一.java基础1.八大基础类型2.java三大特性3.重载和重写的区别4.pubilc、protected、(dafault)不写、private修饰符的作用范围5.和equals的区别6.hashcode()值相同&#xff0c;equals就一定为true7.short s 1&#xff1b;s s 1&#xff1b;(程序1)和 short s 1&#xff…...

视觉感知(二):车位线检测

1. 简介 本期为大家带来车位线检测相关知识点,以及算法工程落地的全流程演示。车位线检测是自动泊车领域必不可缺的一环,顾名思义就是采用环视鱼眼相机对路面上的车位线进行检测,从而识别出车位进行泊车。 较为常规的做法是使用四颗鱼眼相机环视拼接然后在鸟瞰图上做停车位…...

自助建站平台设计器/seo是什么品牌

链接地址&#xff1a;http://bailian.openjudge.cn/practice/2736/ 题目&#xff1a; 总时间限制:1000ms内存限制:65536kB描述求2个大的正整数相减的差输入第1行是测试数据的组数n&#xff0c;每组测试数据占2行&#xff0c;第1行是被减数a&#xff0c;第2行是减数b(a > b)。…...

wordpress网站logo/兰州模板网站seo价格

发现好多人都在解决一个问题那就是&#xff0c;如何实现android相机的自动对焦&#xff0c;而且是连续自动对焦的。当然直接调用系统相机就不用说了&#xff0c;那个很简单的。下面我们主要来看看如如何自己实现一个相机&#xff0c;并且实现自动连续对焦。 根据网上的资料有如…...

wap网站模板下载/外贸是做什么的

1. Size Classes 是属于iOS 8以后的系统的特性&#xff0c;iOS 8之前是用不了的。&#xff08;Auto Layout&#xff09; 2. Size Classes 可以针对所有苹果的页面&#xff08;包括横屏&#xff0c;竖屏&#xff09;进行屏幕适配&#xff0c;但是刚开始编写程序之前&#xff0c…...

wordpress微信拦截/百度seo指数查询

在Java中&#xff0c;内存泄露和其它内存相关问题在性能和可扩展性方面表现的最为突出。我们有充分的理由去具体地讨论他们。Java内存模型——或者更确切的说垃圾回收器——已经攻克了很多内存问题。然而同一时候&#xff0c;也带来了新的问题。特别是在有着大量并行用户的J2EE…...

深圳网站建设公司大全/考研培训班哪个机构比较好

本文实例讲述了PHP图像处理类库MagickWand用法。分享给大家供大家参考。具体分析如下&#xff1a;MagickWand 是PHP的一个扩展程序&#xff0c;通过它建立起与ImageMagick的交互&#xff0c;进行图片的处理。它是默认的GD图象函数库的绝佳替代方案。从安全性和易用性来说&#…...

在哪个网站做服装代理批发/百度新闻app

第1关:代换-置换网络 任务描述 在密码学中,代换-置换网络(或译作置换排列网络,英语:Substitution-Permutation Network,缩写作 SP-network 或 SPN)是乘积密码和分组加密的一种,美国数学家克劳德香农在1949年为了找到利用简单的代换-置换方式进行加密的安全加密方式,发…...