Draggable text box scales more than expected - javascript

I made a text box and boxes on the corners for resizing. The first time I drag, it works perfectly fine, but after the 1st time, the dragging amount seems to multiply. (Don't mind the position of the dragging nodes). If you drag once, it scales fine with the mouse. It seems as if every time after that, when you drag, it scales farther and farther from the user's mouse, causing an 'uncontrollable' scale. I reset the values of the prevX and prevY values at the end of the move function. I'm not sure if that's the issue though. The issue, I believe, is with the scaling with getBoundingClientRect() in the resize portion. Moving the textbox, however, works perfectly fine. Here is my code:
var textBox = document.querySelector(".text-box");
var textArea = document.querySelector('.text-field');
textArea.focused = false;
textBox.addEventListener('mousedown', mousedown);
let isResizing = false;
let isTyping = false;
textArea.addEventListener('dblclick', type)
function type(){
if (!isTyping){
isTyping = true;
textArea.style.cursor = 'text';
}else {
isTyping = false;
textArea.style.cursor = 'default';
}
}
document.body.onclick = function(e){
if (e.target != textArea){
isTyping = false;
e.target.style.cursor = 'default';
}
}
function mousedown(e){
if (e.target == textArea){
e.target.style.cursor = 'default';
}
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
let prevX = e.clientX;
let prevY = e.clientY;
function mousemove(e){
if(!isResizing && !isTyping){
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
const rect = textBox.getBoundingClientRect();
textBox.style.left = rect.left - newX + "px";
textBox.style.top = rect.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
}
}
function mouseup(){
window.removeEventListener('mousemove', mousemove);
window.removeEventListener('mouseup', mouseup);
}
const handles = document.querySelectorAll('.handle');
let currentHandle;
for(let handle of handles){
handle.addEventListener('mousedown', mousedown);
function mousedown(e){
currentHandle = e.target;
isResizing = true;
let prevX = e.clientX;
let prevY = e.clientY;
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
function mousemove(e){
const rect = textBox.getBoundingClientRect();
if (currentHandle.classList.contains("se")) {
textBox.style.width = rect.width - (prevX - e.clientX) + "px";
textBox.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentHandle.classList.contains("sw")) {
textBox.style.width = rect.width + (prevX - e.clientX) + "px";
textBox.style.height = rect.height - (prevY - e.clientY) + "px";
textBox.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentHandle.classList.contains("ne")) {
textBox.style.width = rect.width - (prevX - e.clientX) + "px";
textBox.style.height = rect.height + (prevY - e.clientY) + "px";
textBox.style.top = rect.top - (prevY - e.clientY) + "px";
} else {
textBox.style.width = rect.width + (prevX - e.clientX) + "px";
textBox.style.height = rect.height + (prevY - e.clientY) + "px";
textBox.style.top = rect.top - (prevY - e.clientY) + "px";
textBox.style.left = rect.left - (prevX - e.clientX) + "px";
}
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup(){
window.removeEventListener('mousemove', mousemove);
window.removeEventListener('mouseup', mouseup);
textArea.focused = false;
isResizing = false;
}
}
}
}
.text-box{
height: 50px;
width: 150px;
position: absolute;
}
.handle{
position: absolute;
width: 5px;
height: 5px;
background-color: blue;
z-index: 2;
}
.ne{
top: -1px;
right: -1px;
cursor: ne-resize;
}
.nw{
top: -1px;
left: -1px;
cursor: nw-resize;
}
.sw{
bottom: -1px;
left: -1px;
cursor: sw-resize;
}
.se{
bottom: -1px;
right: -1px;
cursor: se-resize;
}
.text-field {
width: 100%;
height: 100%;
resize: none;
cursor: default;
}
<div class="text-box">
<textarea class="text-field">Click to add text...</textarea>
<div class="handle ne"></div>
<div class="handle nw"></div>
<div class="handle sw"></div>
<div class="handle se"></div>
</div>

It is just as Chris said on the comment, (However I tried many things before understanding the issue...)
One way very simple to solve it is to take out your for loop from inside your mousedown function.
var textBox = document.querySelector(".text-box");
var textArea = document.querySelector('.text-field');
textArea.focused = false;
textBox.addEventListener('mousedown', mousedown);
let isResizing = false;
let isTyping = false;
textArea.addEventListener('dblclick', type)
function type(){
if (!isTyping){
isTyping = true;
textArea.style.cursor = 'text';
}else {
isTyping = false;
textArea.style.cursor = 'default';
}
}
document.body.onclick = function(e){
if (e.target != textArea){
isTyping = false;
e.target.style.cursor = 'default';
}
}
function mousedown(e){
if (e.target == textArea){
e.target.style.cursor = 'default';
}
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
let prevX = e.clientX;
let prevY = e.clientY;
function mousemove(e){
if(!isResizing && !isTyping){
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
const rect = textBox.getBoundingClientRect();
textBox.style.left = rect.left - newX + "px";
textBox.style.top = rect.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
}
}
function mouseup(){
window.removeEventListener('mousemove', mousemove);
window.removeEventListener('mouseup', mouseup);
}
}
const handles = document.querySelectorAll('.handle');
let currentHandle;
for(let handle of handles){
handle.addEventListener('mousedown', mousedown);
function mousedown(e){
currentHandle = e.target;
isResizing = true;
let prevX = e.clientX;
let prevY = e.clientY;
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
function mousemove(e){
const rect = textBox.getBoundingClientRect();
if (currentHandle.classList.contains("se")) {
textBox.style.width = rect.width - (prevX - e.clientX) + "px";
textBox.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentHandle.classList.contains("sw")) {
textBox.style.width = rect.width + (prevX - e.clientX) + "px";
textBox.style.height = rect.height - (prevY - e.clientY) + "px";
textBox.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentHandle.classList.contains("ne")) {
textBox.style.width = rect.width - (prevX - e.clientX) + "px";
textBox.style.height = rect.height + (prevY - e.clientY) + "px";
textBox.style.top = rect.top - (prevY - e.clientY) + "px";
} else {
textBox.style.width = rect.width + (prevX - e.clientX) + "px";
textBox.style.height = rect.height + (prevY - e.clientY) + "px";
textBox.style.top = rect.top - (prevY - e.clientY) + "px";
textBox.style.left = rect.left - (prevX - e.clientX) + "px";
}
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup(){
window.removeEventListener('mousemove', mousemove);
window.removeEventListener('mouseup', mouseup);
textArea.focused = false;
isResizing = false;
}
}
}
Just one more thing, I added these lines to your code, to not remove the resize cursor when clicking the handler:
document.body.onclick = function(e){
if (e.target != textArea){
if(e.target.classList.contains('handle')){
isTyping = false
}
else{
isTyping = false;
e.target.style.cursor = 'default';
}
}
}

Related

Div won't drag correctly after being scaled

If anyone could help me figure out how to make scaled draggable elements, I'd really appreciate any guidance.
Drag works fine when transform: scale(1), but doesn't work correctly when something like transform: scale(1.1).
I tried dividing left and top by the scaler while dragging but didn't work.
const el = document.querySelector(".item");
let isResizing = false;
el.addEventListener("mousedown", mousedown);
function mousedown(e) {
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
let prevX = e.clientX;
let prevY = e.clientY;
function mousemove(e) {
if (!isResizing) {
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
const rect = el.getBoundingClientRect();
el.style.left = rect.left - newX + "px";
el.style.top = rect.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
}
}
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
}
}
const resizers = document.querySelectorAll(".resizer");
let currentResizer;
for (let resizer of resizers) {
resizer.addEventListener("mousedown", mousedown);
function mousedown(e) {
currentResizer = e.target;
isResizing = true;
let prevX = e.clientX;
let prevY = e.clientY;
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
function mousemove(e) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("se")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("sw")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("ne")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
isResizing = false;
}
}
}
.item {
height: 50px;
width: 50px;
position: absolute;
background: pink;
transform: scale(1.1);
}
.resizer {
position: absolute;
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #333;
z-index: 2;
}
.resizer.nw {
top: -1px;
left: -1px;
cursor: nw-resize;
}
.resizer.ne {
top: -1px;
right: -1px;
cursor: nw-resize;
}
.resizer.sw {
bottom: -1px;
left: -1px;
cursor: sw-resize;
}
.resizer.se {
bottom: -1px;
right: -1px;
cursor: se-resize;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<title>Scaled Div</title>
</head>
<body>
<div class="item">
<div class="resizer ne"></div>
<div class="resizer nw"></div>
<div class="resizer sw"></div>
<div class="resizer se"></div>
</div>
<script src="./main.js"></script>
</body>
</html>
Problem seems to be the mouse-down, conflicting between the x/y-values of the surrounding .item-div and the 4 Resize-Handlers, so the browser doesn't know which are the right resulting values ...
So a solution of this problem may be:
add a CSS border to the .item {...; border:1px solid grey ;}
.item {position:absolute; height:50px; width:50px; border:1px solid grey; background:pink}
and substract these (both-side) borders on the 4 resize-handlers:
...
el.style.width = rect.width +2+ (prevX - e.clientX) + "px"; //adding 2px
el.style.height = rect.height -2- (prevY - e.clientY) + "px"; //substr. 2px
... etc.
...
or instead of these 4 div-handlers using the default browser css-handlers:
.item { ...; resize:both; overflow:hidden}
...My error: "adding" 2px nevertheless should always substract 2px on all sides, so a mouse-down is not conflicting betw. surrounding div and handler-divs:
function mousemove(e) {
const rect = el.getBoundingClientRect(); //"rect" has no border, so add 2px for each side
if (currentResizer.classList.contains("se")) {
el.style.width = rect.width -2- (prevX - e.clientX) + "px"; //2 = border-width
el.style.height = rect.height -2- (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("sw")) {
el.style.width = rect.width -2+ (prevX - e.clientX) + "px";
el.style.height = rect.height -2- (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("ne")) {
el.style.width = rect.width -2- (prevX - e.clientX) + "px";
el.style.height = rect.height -2+ (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else { //nw
el.style.width = rect.width -2+ (prevX - e.clientX) + "px";
el.style.height = rect.height -2+ (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}

Prevent setAttribute from running twice

I'm trying to snap an element below another element and make it stay put. The function is ok, but it runs every time I move it 10px. So it moves 10px even further each time..
function move_box() {
if(el.offsetLeft = 10){
console.log('moved the element 10px to the left!');
el.setAttribute('class', 'snap_in'); // class with css (transform: translateY(10px)
let not_called = false;
console.log(not_called);
} else if (not_called = false){
console.log(not_called);
el.setAttribute('class', 'dont_move'); //class with css transform:translateY(0px);
}
}
}
use '==' instead of =
you are assigning not comparing
const el = document.querySelector('.item');
let not_called;
el.addEventListener('mousedown', mousedown);
function mousedown(e){
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
let prevX = e.clientX;
let prevY = e.clientY;
function mousemove(e) {
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
const rect = el.getBoundingClientRect();
el.style.left = rect.left - newX + "px";
el.style.top = rect.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup() {
window.removeEventListener('mousemove', mousemove);
window.removeEventListener('mouseup', mouseup);
console.log(el.offsetLeft);
console.log(el.offsetTop);
//let leftoffset = el.offsetLeft;
if (not_called == false){
console.log(not_called);
el.setAttribute('class', 'item');
}
else if(el.offsetLeft >= 180 && el.offsetLeft <= 220){
console.log('yes!');
el.setAttribute('class', 'snap_in');
not_called = false;
console.log(not_called);
}
}
}

resizable object not working properly native js

In my project user can create as many objects as he wants and resize them. But there is some bug that causes resizing go super fast. When user creates one object, resize it, then create second object and resize it too, after resizing second object come back to first and resizing this first object is faster than mouse movement speed.
//create
function create() {
const workArea = document.querySelector('.work-area');
let divParent = document.createElement("div");
divParent.className = "divParent";
let div = document.createElement("div");
div.className = "div";
divParent.appendChild(div);
workArea.appendChild(divParent);
var resizerNE = document.createElement("div");
resizerNE.className = "resizerNE";
resizerNE.classList.add("resizer");
var resizerSE = document.createElement("div");
resizerSE.className = "resizerSE";
resizerSE.classList.add("resizer");
var resizerSW = document.createElement("div");
resizerSW.className = "resizerSW";
resizerSW.classList.add("resizer");
var resizerNW = document.createElement("div");
resizerNW.className = "resizerNW";
resizerNW.classList.add("resizer");
divParent.appendChild(resizerNE);
divParent.appendChild(resizerSE);
divParent.appendChild(resizerSW);
divParent.appendChild(resizerNW);
//resize
let el;
const resizer = document.querySelectorAll(".resizer");
resizer.forEach(function(thisresizer) {
thisresizer.addEventListener("mousedown", function() {
el = this.parentNode;
});
});
let isResizing = false;
const resizers = document.querySelectorAll(".resizer");
let currentResizer;
for (let resizer of resizers) {
resizer.addEventListener("mousedown", mousedown);
function mousedown(e) {
currentResizer = e.target;
isResizing = true;
//console.log(el);
let prevX = e.clientX;
let prevY = e.clientY;
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
function mousemove(e) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("resizerSE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerSW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerNE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerNW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerN")) {
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerS")) {
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}
el.children[0].style.width = el.style.width;
el.children[0].style.height = el.style.height;
//console.log("prevX: " + prevX + " prevY: " + prevY);
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
isResizing = false;
}
}
}
}
.work-area{
width: 100%;
height: 100vh;
}
.divParent{
width: 100px;
height: 100px;
position: absolute;
background:black
}
.div{
background: #555555;
}
.resizer {
width: 12px;
height: 12px;
position: absolute;
z-index: 99999999;
border: 1px solid #2872c7;
border-radius: 10px;
background: #f2f2f2;
box-sizing: border-box;
display: block;
}
.resizerSE {
right: -6px;
bottom: -6px;
cursor: se-resize;
}
.resizerNE {
top: -6px;
right: -6px;
cursor: ne-resize;
}
.resizerSW {
left: -6px;
bottom: -6px;
cursor: sw-resize;
}
.resizerNW {
left: -6px;
top: -6px;
cursor: nw-resize;
}
<button onclick="create()">Create</button>
<div class="work-area">
</div>
finally 😌
i spend more than hour to find a way to overcome the problem🤣
Which is Every Time you create objects you add listeners to the previous resizers that's why every new object makes resizing the previous ones faster
in other words the browser moves more steps per mousemove event
only change is
const resizers = document.querySelectorAll(".resizer");
to
const resizers = divParent.querySelectorAll(".resizer");
also in my answer i rearranged your code making it simpler to read & smaller
//create
function create() {
const workArea = document.querySelector(".work-area");
let divParent = document.createElement("div");
divParent.className = "divParent";
workArea.appendChild(divParent);
NewDiv = cls => {
let elm = document.createElement("div");
elm.className = cls;
divParent.appendChild(elm);
};
let div = NewDiv("div");
let resizerNE = NewDiv("resizerNE resizer");
let resizerSE = NewDiv("resizerSE resizer");
let resizerSW = NewDiv("resizerSW resizer");
let resizerNW = NewDiv("resizerNW resizer");
//resize
let el;
let isResizing = false;
const resizers = divParent.querySelectorAll(".resizer");
let currentResizer;
let prevX;
let prevY;
function mousedown(e) {
el = this.parentNode;
currentResizer = e.target;
isResizing = true;
prevX = e.clientX;
prevY = e.clientY;
workArea.addEventListener("mousemove", mousemove);
workArea.addEventListener("mouseup", mouseup);
}
for (let resizer of resizers) {
resizer.addEventListener("mousedown", mousedown);
}
function mousemove(e) {
if (isResizing) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("resizerSE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerSW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerNE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerNW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerN")) {
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerS")) {
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}
el.children[0].style.width = el.style.width;
el.children[0].style.height = el.style.height;
//console.log("prevX: " + prevX + " prevY: " + prevY);
prevX = e.clientX;
prevY = e.clientY;
}
}
function mouseup() {
isResizing = false;
workArea.removeEventListener("mouseup", mouseup);
workArea.removeEventListener("mousemove", mousemove);
}
}
.work-area {
width: 100%;
height: 100vh;
}
.divParent {
width: 100px;
height: 100px;
position: absolute;
background: black;
}
.div {
background: #555555;
}
.resizer {
width: 12px;
height: 12px;
position: absolute;
z-index: 99999999;
border: 1px solid #2872c7;
border-radius: 10px;
background: #f2f2f2;
box-sizing: border-box;
display: block;
}
.resizerSE {
right: -6px;
bottom: -6px;
cursor: se-resize;
}
.resizerNE {
top: -6px;
right: -6px;
cursor: ne-resize;
}
.resizerSW {
left: -6px;
bottom: -6px;
cursor: sw-resize;
}
.resizerNW {
left: -6px;
top: -6px;
cursor: nw-resize;
}
<body>
<button onclick="create()">Create</button>
<div class="work-area"></div>
</body>

Draw parallelogram on canvas

There are so many examples to draw rectangles with mouse on canvas. For example, check this jsFiddle. Is it possible to draw parallelogram?
initDraw(document.getElementById('canvas'));
function initDraw(canvas) {
function setMousePosition(e) {
var ev = e || window.event; //Moz || IE
if (ev.pageX) { //Moz
mouse.x = ev.pageX + window.pageXOffset;
mouse.y = ev.pageY + window.pageYOffset;
} else if (ev.clientX) { //IE
mouse.x = ev.clientX + document.body.scrollLeft;
mouse.y = ev.clientY + document.body.scrollTop;
}
};
var mouse = {
x: 0,
y: 0,
startX: 0,
startY: 0
};
var element = null;
canvas.onmousemove = function(e) {
setMousePosition(e);
if (element !== null) {
element.style.width = Math.abs(mouse.x - mouse.startX) + 'px';
element.style.height = Math.abs(mouse.y - mouse.startY) + 'px';
element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px';
element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px';
}
}
canvas.onclick = function(e) {
if (element !== null) {
element = null;
canvas.style.cursor = "default";
console.log("finsihed.");
} else {
console.log("begun.");
mouse.startX = mouse.x;
mouse.startY = mouse.y;
element = document.createElement('div');
element.className = 'rectangle'
element.style.left = mouse.x + 'px';
element.style.top = mouse.y + 'px';
canvas.appendChild(element)
canvas.style.cursor = "crosshair";
}
}
}
#canvas {
width: 2000px;
height: 2000px;
border: 10px solid transparent;
}
.rectangle {
border: 1px solid #FF0000;
position: absolute;
}
<div id="canvas"></div>
I think this question is self explanatory.

drag and drop div element not work well

I've created a simple code to drag and drop div element but not work well.
When you drag the div element quickly to any direction top, left, right, down, the mouse cursor will leave the div element, Although I'm still press on the button .
HTML
<div id="box"></div>
CSS
div#box {
background-color:yellowgreen;
width:150px; height:100px;
border:1px solid #ffff66;
position:relative;
}
JavaScript
var elem = document.getElementById('box');
var PositionX = 0;
var PositionY = 0;
var MouseX = 0
var MouseY = 0;
var mouseDown = false;
elem.onmousedown = function(e) {
PositionX = elem.offsetLeft;
PositionY = elem.offsetTop;
MouseX = e.clientX;
MouseY = e.clientY;
mouseDown = true;
};
elem.onmousemove = function(e) {
if (mouseDown) {
elem.style.left = PositionX + e.clientX - MouseX + "px";
elem.style.top = PositionY + e.clientY - MouseY + "px";
}
};
elem.onmouseover = function(e) {
elem.style.cursor = 'move';
};
elem.onmouseup = function(e) {
mouseDown = false;
};
You can see online
Try changing this one line:
elem.onmousemove = function(e) {
to:
document.onmousemove = function(e) {
try this hope it would have your work done :
var elem= document.getElementbyId('<%=box.ClientID%>');
elem.onmousemove= function(e) {
if (mouseDown) {
elem.style.left = PositionX + e.clientX - MouseX + "px";
elem.style.top = PositionY + e.clientY - MouseY + "px";
}
};

Categories

Resources