上传图片文件并立即显示到页面使用 javascript实现鼠标拖动画矩形框以及实现固定区域内随意拖动

本文主要是介绍上传图片文件并立即显示到页面使用 javascript实现鼠标拖动画矩形框以及实现固定区域内随意拖动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

首先,你要设计好鼠标事件处理方法,主要是鼠标左键点击,左键释放,还有鼠标移动方法
其次,要了解容什么方式,画一个矩形,设计一个方法:DrawRectgle(左上角,右下角),并且要确定当调用这个方法时,要把原来已经画好的矩形清除掉(或者是根据左上,右下坐标,调整矩形的大小,这样的话,就不用清除原有的矩形)

在鼠标左键按下事件中,获取鼠标位置,保存为左上角坐标,设置开始画矩形的一个标志
在鼠标左键弹起事件中,恢复划矩形的标志为false
在鼠标移动事件中,需要判断是否同时还按下了鼠标左键,如果按下了,并且画矩形标志为true,就获取鼠标位置,保存为右下角坐标(针对鼠标向左上移动的场合,要把左上,右下位置交换一下),然后画一个矩形

// css部分
#canvas {background-color: #AAAAAA;position: relative;background-size:100% 100%;border: 2px solid blue;}#canvas>div {border: 2px solid green;position: absolute;background-color: #eaeaea;}
#canvas>div>span {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);font-family: simsun;font-size: 9pt;}// html部分
<div id="canvas" style="width:850px;height:477px"></div>// js部分
var canvasWidth= 850;
var canvasHeight = 477;
var allDivNum = 1;
CanvasExt = {drawRect: function(canvas) {//参数canvas--所画素材框的区域var that = this;// canvas 的矩形框var canvasRect = canvas.getBoundingClientRect();// 矩形框的左上角坐标var canvasLeft = canvasRect.left;var canvasTop = canvasRect.top;var x = 0;var y = 0;// 鼠标点击按下事件,画图准备$(document).on('mousedown', '#canvas', function(e) {// 解决修改时已存在素材框等,删除后再新增存在id重复问题var date = new Date().getTime();var id = "newDiv" + date + parseInt(Math.random()*10);var divEle = "";// x y为鼠标的落点x = e.clientX - canvasLeft;y = e.clientY - canvasTop;//创建divdivEle = document.createElement('div');divEle.setAttribute("id", id);canvas.append(divEle)divEle.style.top = y + "px";divEle.style.left = x + "px";// 绑定删除操作var menu = new BootstrapMenu('#' + id, {actions: [{name: '删除展示框',onClick: function() {del(id);}}]});var tx = 0;var ty = 0;var twidth = 0;var theight = 0;// 添加拖拽操作divEle.onmousedown = function(e) {e.stopPropagation();// 阻止时间冒泡var divEleRect = this.getBoundingClientRect();var divEleLeft = e.clientX - divEleRect.left;var divEleTop = e.clientY - divEleRect.top;this.onmousemove = function(e) {e.stopPropagation();tx = e.clientX - canvasLeft - divEleLeft;ty = e.clientY - canvasTop - divEleTop;// 重新获取当前对象的宽和高twidth = document.getElementById(id).style.width;twidth = parseInt(twidth);theight = document.getElementById(id).style.height;theight = parseInt(theight);// 边界检测if(tx <= 0) {tx = 0;this.style.left = 0 + "px";} else if(tx + twidth > canvasWidth) {tx = canvasWidth - twidth;this.style.left = (canvasWidth - twidth) + "px";} else {this.style.left = tx + "px";}if(ty <= 0) {ty = 0;this.style.top = 0 + "px";} else if((ty + theight) > canvasHeight) {y = canvasHeight - theight;this.style.top = (canvasHeight - theight) + "px";} else {this.style.top = ty + "px";}}this.onmouseup = function(e) {var id = $(this).attr("id");e.stopPropagation();this.onmousemove = null;}};//鼠标移动事件,画图var width = 0;var height = 0;canvas.onmousemove = function(e) {e.stopPropagation();// width height是鼠标移动末尾距鼠标起始位置的差值width = e.clientX - canvasLeft - x;height = e.clientY - canvasTop - y;divEle.style.width = width + "px";divEle.style.height = height + "px";var tw = e.clientX - canvasLeft;var th = e.clientY - canvasTop;if(tw >= (parseInt(canvasWidth)-7) || th >=             (parseInt(canvasHeight)-7)){ // 比canvas少3px,为了易于判断allDivNum++;divEle.innerHTML = "<span>素材框" + allDivNum + "</span>";canvas.onmousemove = null;canvas.onmouseup = null;return;}}canvas.onmouseup = function(e) {if(width < 10 || height < 10) {canvas.removeChild(divEle);} else {allDivNum++;divEle.innerHTML = "<span>素材框" + allDivNum + "</span>";}e.stopPropagation();canvas.onmousemove = null;}});}};
window.onload = function() {var canvas = document.getElementById("canvas");CanvasExt.drawRect(canvas);// 取消默认右击事件document.oncontextmenu = function(e) {e.preventDefault();}};

https://blog.csdn.net/qq_40302859/article/details/81945520

代码是会有冗余部分,自己改造一下

右键菜单用到的是BootstrapMenu.min.js

需要下载的可以移步https://download.csdn.net/download/qq_40302859/10620088

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
<title>JS实现用鼠标拖动画出矩形框_网页代码站(www.webdm.cn)</title>
<style type="text/css">
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0}
html{color:#000;overflow-y:scoll;overflow:-moz-scrollbars-vertical}
.div{position:absolute; border:1px dashed blue; width:0px; height:0px;left:0px; top:0px; overflow:hidden;}
.retc{position:absolute; border:1px solid #CCCCCC; overflow:hidden; background:#EFEFEF}
</style>
</head>
<body>	
</body>
<script language = "javascript">var wId = "w";var index = 0;var startX = 0, startY = 0;var flag = false;var retcLeft = "0px", retcTop = "0px", retcHeight = "0px", retcWidth = "0px";document.onmousedown = function(e){flag = true;try{var evt = window.event || e;var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;startX = evt.clientX + scrollLeft;startY = evt.clientY + scrollTop;index++;var div = document.createElement("div");div.id = wId + index;div.className = "div";div.style.marginLeft = startX + "px";div.style.marginTop = startY + "px";document.body.appendChild(div);}catch(e){//alert(e);}}document.onmouseup = function(){try{document.body.removeChild($(wId + index));var div = document.createElement("div");div.className = "retc";div.style.marginLeft = retcLeft;div.style.marginTop = retcTop;div.style.width = retcWidth;div.style.height = retcHeight;document.body.appendChild(div);}catch(e){//alert(e);}flag = false;}document.onmousemove = function(e){if(flag){try{var evt = window.event || e;var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;retcLeft = (startX - evt.clientX - scrollLeft > 0 ? evt.clientX + scrollLeft : startX) + "px";retcTop = (startY - evt.clientY - scrollTop > 0 ? evt.clientY + scrollTop : startY) + "px";retcHeight = Math.abs(startY - evt.clientY - scrollTop) + "px";retcWidth = Math.abs(startX - evt.clientX - scrollLeft) + "px";$(wId + index).style.marginLeft = retcLeft;$(wId + index).style.marginTop = retcTop;$(wId + index).style.width = retcWidth;$(wId + index).style.height = retcHeight;}catch(e){//alert(e);}	}}var $ = function(id){return document.getElementById(id);}
</script>
<br>
<p><a href="http://www.webdm.cn">网页代码站</a> - 最专业的网页代码下载网站 - 致力为中国站长提供有质量的网页代码!</p>
</html>

canvas实现鼠标拖拽矩形移动改变大小

项目的一个新需求,动态生成矩形框,鼠标点击拖动改变矩形框的位置,并可以调整大小。

之前做过一个小demo,需求类似,但是在canvas内只有一个矩形框,拖动移动,当时记得是用isPointInPath()直接判断鼠标是否点在了矩形框以内。新需求的矩形框个数为n,经过测试,isPointinPath实现过程中有bug,并不能精准定位到具体点击到canvas的某一个矩形框。经过一系列的头脑风暴,才想出了解决办法,才发现原来是最简单的方法,但是在思考的当初就被pass了,见代码:

html:

<body><canvas id="canvas" width="400" height="300"></canvas>
</body>

小demo,不做其他修饰,直接写逻辑吧。

js:
第一步,创建一个容器,以保存Canvas内绘制的元素点。Canvas是一种非保留性的绘图界面,即不会记录过去执行的绘图操作,而是保持最终结果(构成图像的彩色像素)。

如果想让Canvas变得具有交互性,比如用户可以选择、拖动画布上的图形。那么我们必须记录绘制的每一个对象,才能在将来灵活的修改并重绘它们,实现交互。

// canvas 矩形框集合var rects=[];function rectar(x,y,width,height){this.x = x;this.y = y;this.width = width;this.height = height;this.isSelected = false;};

绘制矩形框:

function drawRect() {// 清除画布,准备绘制context.clearRect(0, 0, canvas.width, canvas.height);// 遍历所有矩形框for(var i=0; i<rects.length; i++) {var rect = rects[i];// 绘制矩形context.strokeStyle="#FF0000";context.strokeRect(rect.x,rect.y,rect.width,rect.height,rect.color);if (rect.isSelected) {context.lineWidth = 50;}else {context.lineWidth = 10;}}}

这是一个绘制函数,因为在Canvas的所有操作,全部都是重新绘制的(先清除,在绘制),每次程序刷新画布时,会先使用 clearRect() 方法清除画布上的所有内容。但不用当心这样会造成画布闪烁,即画布上的圆圈一下子全部消失,然后一下子又重新出现。因为Canvas针对这个问题进行了优化,会在所有绘图逻辑执行完毕后才清除或绘制所有内容,保证最终结果的流畅。然后遍历矩形数组 其中的x,y,width,height来画矩形。

*这里我的项目是根据病变位置动态生成的矩形框,每一次生成矩形框,都要把它的位置信息添加到数组中,这里就直接创建矩形框了,可以根据自己需求改造

function addRandomRect() {var x=10;var y=10;var width=100;var height=100;// 创建一个新的矩形对象var rect=new rectar(x,y,width,height);// 把它保存在数组中rects.push(rect);// 重新绘制画布drawRect();};

*Canvas点击事件

var SelectedRect;var x1;var y1;var right=false;var widthstart,widthend;var heightstart,heightend;function canvasClick(e) {// 取得画布上被单击的点var clickX = e.pageX - canvas.offsetLeft;var clickY = e.pageY - canvas.offsetTop;// 查找被单击的矩形框for(var i=rects.length-1; i>=0; i--) {var rect = rects[i];widthstart=rect.x;widthend=rect.x+rect.width;heightstart=rect.y;heightend=rect.y+rect.height;// 判断这个点是否在矩形框中if ((clickX>=widthstart&&clickX<(widthend-20))&&(clickY>=heightstart)&&(clickY<(heightend-20))) {console.log(clickX);// 清除之前选择的矩形框if (SelectedRect != null) SelectedRect.isSelected = false;SelectedRect = rect;x1=clickX-SelectedRect.x;y1=clickY-SelectedRect.y;//选择新圆圈rect.isSelected = true;// 使圆圈允许拖拽isDragging = true;//更新显示drawRect();//停止搜索return;};/*设置拉伸的界限。*/// if ((clickX>=(widthend-20))&&(clickY>=(heightend-20)))// {//   SelectedRect = rect;//  right=true;//  }//18-02-01改if ((clickX>=(widthend-20)&&((clickX<=(widthend+20)))&&(clickY>=(heightend-20))&&(clickY>=(heightend+20))) {SelectedRect = rect;right=true; }} 
}

代码中23行为判断具体点击哪个元素的语句,其实很简单,当初绕了很久,很简单直接判断鼠标点击点是否在矩形框之内即可,无论是哪个矩形框,只要在矩形框之内,就把当前矩形框设置为点击的矩形框。29行判断鼠标点击点相对于矩形框的位置。42-49行,是鼠标拉伸改变大小的判断,可以设置矩形四个角拉伸,但我认为太复杂了,只保留了右下角拉伸的点击判断,操作更简单一些。

响应事件:

function dragRect(e) {// 判断矩形是否开始拖拽if (isDragging == true) {// 判断拖拽对象是否存在if (SelectedRect != null) {// 取得鼠标位置var x = e.pageX - canvas.offsetLeft;var y = e.pageY - canvas.offsetTop;// 将圆圈移动到鼠标位置SelectedRect.x= x-x1;SelectedRect.y= y-y1;// 更新画布drawRect();}}//判断是否开始拉伸if (right) {//设置拉伸最小的边界if ((e.pageX - canvas.offsetLeft-SelectedRect.x)>50) {SelectedRect.width=e.pageX - canvas.offsetLeft-SelectedRect.x;}else {SelectedRect.width=50;}console.log(SelectedRect.width);if((e.pageY - canvas.offsetTop-SelectedRect.y)>50){SelectedRect.height=e.pageY - canvas.offsetTop-SelectedRect.y;}else {SelectedRect.height=50;}drawRect();}};

以上就完成了对矩形框的基本操作,然后添加onmouseup的函数和调用函数:

var isDragging = false;function stopDragging() {isDragging = false;right=false;};function clearCanvas() {// 去除所有矩形rects = [];// 重新绘制画布.drawCircles();}window.onload = function() {canvas = document.getElementById("canvas");context = canvas.getContext("2d");canvas.onmousedown = canvasClick;canvas.onmouseup = stopDragging;canvas.onmouseout = stopDragging;canvas.onmousemove =dragRect;
; };

这篇关于上传图片文件并立即显示到页面使用 javascript实现鼠标拖动画矩形框以及实现固定区域内随意拖动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/805177

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数