Change a div size on right-click hold and drag - javascript

I try to make a div resizable on right-click hold and drag.
What I want is a mouse's right-click to change a div's dimentions on drag.
I have a problem which seems like to be that the previous size of the div is not updated.
On the second attempt to drag the div, it starts with it's previous state.
My code:
$(document).ready(function() {
// right click event
$("#displayWindow")
// when the mouse is pressed, the div is appended to the displayWindow
.mousedown(function(e) {
if (e.button == 2) {
$('#div1').remove();
// append the div start at the location that we click
$("#displayWindow").append("<div id='div1'></div>");
// get the coordinate where we clicked and set the div begin with that position
var clickedX = e.pageX;
var clickedY = e.pageY;
$('#div1').css('top', clickedY);
$('#div1').css('left', clickedX);
// holding on the mouse button, change the size of the div
$("#displayWindow").on("mousemove", function(e) {
if (e.button == 2) {
var mouseOnX = e.pageX;
var mouseOnY = e.pageY;
// allow user drag the selection box in 4 different direction
if (mouseOnX > clickedX && mouseOnY > clickedY) {
$('#div1').css('top', clickedY);
$('#div1').css('left', clickedX);
$('#div1').css('height', mouseOnY - clickedY);
$('#div1').css('width', mouseOnX - clickedX);
} else if (clickedX > mouseOnX && mouseOnY > clickedY) {
$('#div1').css('top', clickedY);
$('#div1').css('left', mouseOnX);
$('#div1').css('height', mouseOnY - clickedY);
$('#div1').css('width', clickedX - mouseOnX);
} else if (clickedX > mouseOnX && clickedY > mouseOnY) {
$('#div1').css('top', mouseOnY);
$('#div1').css('left', mouseOnX);
$('#div1').css('height', clickedY - mouseOnY);
$('#div1').css('width', clickedX - mouseOnX);
} else if (mouseOnX > clickedX && clickedY > mouseOnY) {
$('#div1').css('top', mouseOnY);
$('#div1').css('left', clickedX);
$('#div1').css('height', clickedY - mouseOnY);
$('#div1').css('width', mouseOnX - clickedX);
}
}
}); // end on, while we move the mouse
return false;
}
return true;
});
// when clicked again, the menu fade out, and the div disappear
$(document).click(function(e) {
if (e.button == 0) {
// remove the selection box div
$('#div1').remove();
}
});
// prevent the default contextmenu on the display window
document.getElementById('displayWindow').oncontextmenu = function() {
return false;
}
}); // end ready
#displayWindow {
background-color: white;
border: 1px solid;
height: 600px;
width: 800px;
}
#div1 {
background-color: lightgreen;
position: absolute;
opacity: 0.3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="displayWindow">
<svg height="130" width="150" style="position:absolute; left:200; top:200;" class="ui-widget-content">
<text fill="black" x=75 y=75 style="text-anchor: middle">1</text>
<path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue">
</svg>
</div>

Just add this inside the if (e.button == 2) {. To reset the element added previously.
$('#div1').removeAttr('style').remove();
// right click event
$("#displayWindow")
// when the mouse is pressed, the div is appended to the displayWindow
.mousedown(function(e) {
if (e.button == 2) {
$('#div1').removeAttr('style').remove();
// append the div start at the location that we click
$("#displayWindow").append("<div id='div1'></div>");
// get the coordinate where we clicked and set the div begin with that position
var clickedX = e.pageX;
var clickedY = e.pageY;
$('#div1').css('top', clickedY);
$('#div1').css('left', clickedX);
// holding on the mouse button, change the size of the div
$("#displayWindow").on("mousemove", function(e) {
if (e.button == 2) {
var mouseOnX = e.pageX;
var mouseOnY = e.pageY;
// allow user drag the selection box in 4 different direction
if (mouseOnX > clickedX && mouseOnY > clickedY) {
$('#div1').css('top', clickedY);
$('#div1').css('left', clickedX);
$('#div1').css('height', mouseOnY - clickedY);
$('#div1').css('width', mouseOnX - clickedX);
} else if (clickedX > mouseOnX && mouseOnY > clickedY) {
$('#div1').css('top', clickedY);
$('#div1').css('left', mouseOnX);
$('#div1').css('height', mouseOnY - clickedY);
$('#div1').css('width', clickedX - mouseOnX);
} else if (clickedX > mouseOnX && clickedY > mouseOnY) {
$('#div1').css('top', mouseOnY);
$('#div1').css('left', mouseOnX);
$('#div1').css('height', clickedY - mouseOnY);
$('#div1').css('width', clickedX - mouseOnX);
} else if (mouseOnX > clickedX && clickedY > mouseOnY) {
$('#div1').css('top', mouseOnY);
$('#div1').css('left', clickedX);
$('#div1').css('height', clickedY - mouseOnY);
$('#div1').css('width', mouseOnX - clickedX);
}
}
}); // end on, while we move the mouse
return false;
}
return true;
});
// when clicked again, the menu fade out, and the div disappear
$(document).click(function(e) {
if (e.button == 0) {
// remove the selection box div
$('#div1').remove();
}
});
// prevent the default contextmenu on the display window
document.getElementById('displayWindow').oncontextmenu = function() {
return false;
}
#displayWindow {
background-color: white;
border: 1px solid;
height: 400px;
width: 800px;
}
#div1 {
background-color: lightgreen;
position: absolute;
opacity: 0.3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="displayWindow">
<svg height="130" width="150" style="position:absolute; left:200; top:200;" class="ui-widget-content">
<text fill="black" x=75 y=75 style="text-anchor: middle">1</text>
<path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" fill="none" stroke="blue" />
</svg>
</div>

Related

Pointer Cursor on a specific part of an image html css

Now it is possible to click on the topleft corner of the image then it is changing.
What I want to do is that when the mouse comes over that specific part of the image the pointer cursor will be active. How can I fix this?
let col = document.querySelectorAll('img#lights-on,img#lights-off');
document.addEventListener("click", function(e) {
if (
e.target instanceof HTMLImageElement &&
e.offsetX >= 0 &&
e.offsetX <= 100 &&
e.offsetY >= 0 &&
e.offsetY <= 20) {
col.forEach(img => {
if (img && img.nodeType == 1) {
img.style.display =
( img.style.display == '' || img.style.display == 'block' ) ?
'none' : 'block';
}
})
}
});
img {
width: 300px;
border: 1px solid black;
}
<img
id="lights-off"
src="//www.collinsdictionary.com/images/thumb/apple_158989157_250.jpg"
style="display: none;">
<img
id="lights-on"
src="//upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Banana-Single.jpg/680px-Banana-Single.jpg">
Just you can add a mousemove event to the document like you did with the click event but add an else statement to remove the cursor if it's not in the place you want:
document.addEventListener("mousemove", function(e) {
if(
e.target instanceof HTMLImageElement &&
e.offsetX >= 0 &&
e.offsetX <= 100 &&
e.offsetY >= 0 &&
){
document.body.style.cursor = "pointer"
}
else{
document.body.style.cursor = ""
}
})

Drag and drop rotated images javascript

so i have a code that allows me to drag and drop an img tag. The drag and drop works fine but when i added a rotation function, the drag and drop started acting weird (the coordinates changed and when i drag the element the rotation reset). Also when i try dragging again, it goes back to its initial position, do you please have any idea on how i can fix this?
This is my code and thank you in advance:
let rotate=0
function rot_plus() {
rotate=rotate+10
$("#test").css('transform',"rotate("+rotate+"deg)")
}
function rot_minus() {
rotate=rotate-10
$("#test").css('transform',"rotate("+rotate+"deg)")
}
var active = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
let current_elem
var container = document.querySelector("#boite");
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if(e.target.id=="test"){
dragItem1=e.target.id
dragItem = document.querySelector("#"+e.target.id);
initialX=e.clientX-xOffset
initialY=e.clientY-yOffset
active = true;
}
}
function drag(e) {
if (active) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, dragItem);
}
}
function dragEnd(e) {
active = false;
initialX=currentX
initialY=currentY
selectedElement = null;
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0) rotate("+rotate+"deg)";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div id="boite">
<img src="https://static.vecteezy.com/system/resources/previews/009/342/282/original/cartoon-eyes-clipart-design-illustration-free-png.png" id="test" class="remove" style="position: absolute; width:150px; height:auto" >
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="46" fill="currentColor" class="bi bi-plus-circle" id="rotplus" style="margin-top:120px" onclick="rot_plus()" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg"width="46" height="46" fill="currentColor" class="bi bi-dash-circle" id="rotminus"
style="margin-top:120px" onclick="rot_minus()" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
</svg>
</div>
</body>
</html>
You are using $.css to change the transform in the rotation functions. But this removes the positional changes as both are defined in 'transform'. That is, to fix this you need to keep the position information when rotating.
To do this it is better not to use jquery as it will clean the information in transform. So what I did was just replicate the line where you define the position but instead of taking the positions defined in your function I take it directly from the variables where you store the values.
I also used a CSS to prevent items from being selected when dragging:
CSS:
#boite,
#boite * {
user-select: none;
}
JS:
function rot_plus() {
const el = lastItemDragged
rotate = rotate + 10;
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
function rot_minus() {
const el = lastItemDragged
rotate = rotate - 10;
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
function setTranslate(el) {
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
I also added the variable lastItemDragged to store the last item dragged (so that the rotation reaches the same)
full code:
let rotate = 0
function rot_plus() {
const el = lastItemDragged
rotate = rotate + 10;
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
function rot_minus() {
const el = lastItemDragged
rotate = rotate - 10;
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
var lastItemDragged = document.querySelector('#test')
var active = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
let current_elem
var container = document.querySelector("#boite");
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target.id == "test") {
dragItem1 = e.target.id
dragItem = document.querySelector("#" + e.target.id);
initialX = e.clientX - xOffset
initialY = e.clientY - yOffset
active = true;
}
}
function drag(e) {
if (active) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(dragItem);
}
}
function dragEnd(e) {
active = false;
initialX = currentX
initialY = currentY
selectedElement = null;
}
function setTranslate(el) {
el.style.transform = "translate3d(" + xOffset + "px, " + yOffset + "px, 0) rotate(" + rotate + "deg)";
}
#boite,
#boite * {
user-select: none;
}
<div id="boite">
<img src="https://static.vecteezy.com/system/resources/previews/009/342/282/original/cartoon-eyes-clipart-design-illustration-free-png.png" id="test" class="remove" style="position: absolute; width:150px; height:auto">
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="46" fill="currentColor" class="bi bi-plus-circle" id="rotplus" style="margin-top:120px" onclick="rot_plus()" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="46" fill="currentColor" class="bi bi-dash-circle" id="rotminus" style="margin-top:120px" onclick="rot_minus()" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
</svg>
</div>

How to add animation to the active div on window scroll?

I have multiple divs in my page. This div contains size and color. When scroll down, div visible to the screen should move up and when scroll up, it should return to its original position.
This is the code so far I have tried. With this code, when I scroll down, div is moving up but when I scroll up , div is not coming down. Can anybody please help me?
function isElementInViewport(el) {
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
(rect.top <= 0 &&
rect.bottom >= 0) ||
(rect.bottom >= (window.innerHeight || document.documentElement.clientHeight) &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight)) ||
(rect.top >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight))
);
}
window.addEventListener('scroll', function(e) {
winScrollTop = $(this).scrollTop();
var elementsToShow = document.querySelectorAll('.rectangle');
Array.prototype.forEach.call(elementsToShow, function(element) {
if (isElementInViewport(element)) {
element.classList.add('is-visible');
} else {
element.classList.remove('is-visible');
}
});
});
.rectangle {
background-color: red;
height: 444px;
width: 100px;
/* margin-top: -98px; */
z-index: -30;
transition: 0.5s;
transform: translateY(-98px);
margin-bottom: 25px;
}
.is-visible {
transform: translateY(-250px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rectangle"></div>
<div class="rectangle"></div>
<div class="rectangle"></div>
<div class="rectangle"></div>
So what i did over here is that firstly i checked the scroll event and then decided if the scroll was actually upwards or downwards. Once i identified whether i was scrolling upwards or downwards, i added the classes respectively. For the not-visible class i am setting style transform: translateY(0px) which simply returns the element to its default place.
.not-visible{
transform: translateY(0px);
}
var lastScrollTop= 0;
window.addEventListener('scroll', function(e) {
winScrollTop = $(this).scrollTop();
var st = window.pageYOffset || document.documentElement.scrollTop; // Credits:
var elementsToShow = document.querySelectorAll('.rectangle');
if (st > lastScrollTop){ // If st is greater than lastscrollTop then it is downward
console.log("down");
// then check if elemetnts are in view
Array.prototype.forEach.call(elementsToShow, function(element) {
if (isElementInViewport(element)) {
element.classList.remove('not-visible'); // remove class notvisible if any
element.classList.add('is-visible'); // Add class isvisible
}
lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
});
} else {
console.log("up");
Array.prototype.forEach.call(elementsToShow, function(element) {
if (isElementInViewport(element)) {
// Remove class isvisible and add class not visible to move the element to default place
element.classList.remove('is-visible');
element.classList.add('not-visible');
}
lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
});
}
});

Svg Draw flickering happening in Chrome browser

I need to allow user to draw a shape and I have used svg for same.
In other browser the code is working perfectly fine, but in case of chrome Version 52.0.2743.116 m it is flickering. When I created it it was working fine. But as chrome was updated the issue started happening
Issue is not replicable in chrome Version 49.0.2623.110 m
https://jsfiddle.net/2svxmgwu/1/
Try to drag and drop in yellow area from left top side to right bottom you will see barcode
Refer the attached image
The flickering does not happen if direction of creating shape is other then from top left to lower bottom.
Code
Html
<div class="thisComp">
<div class="svgElementDiv">
</div>
</div>
Js
var svgShape = $('<svg viewBox="0 0 640 480" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title> <rect stroke="#5B9BD5" id="svg_11" height="473.99998" width="635.99997" y="3" x="3" stroke-linecap="null" stroke-linejoin="null" preserveAspectRatio="none" vector-effect="non-scaling-stroke" stroke-dasharray="null" stroke-width="3" fill="#5B9BD5"/> </g></svg>');
var self = this;
//Added for chrome browser as without this flickering is very high
svgShape.find('[vector-effect="non-scaling-stroke"]').removeAttr('vector-effect');
var $ShapeWrapper = $(".svgElementDiv");
var $thisComp = $(".thisComp");
svgShape.css({
position: "absolute",
left: "0",
top: "0",
width: "100%",
height: "100%",
opacity: "0.5"
});
$ShapeWrapper.css({
position: "fixed"
});
$thisComp.mousedown(function (event) {
if ($ShapeWrapper.length > 0) {
$ShapeWrapper.html(svgShape);
$ShapeWrapper.css("left", event.clientX);
$ShapeWrapper.css("top", event.clientY);
self._selectorLeftPos = event.clientX;
self._selectorTopPos = event.clientY;
$ShapeWrapper.css({
width: "0",
height: "0"
});
self._dragged = false;
event.preventDefault();
}
});
var removeShape = function (event) {
if ($ShapeWrapper.find(svgShape).length > 0 && !(event.type=="mouseleave" && $(event.relatedTarget).closest('.guideWrapper').length>0)) {
var startX = (($ShapeWrapper.offset().left - $thisComp.offset().left) / self._transformRatio) / self._conversionFactor;
var startY = (($ShapeWrapper.offset().top - $thisComp.offset().top) / self._transformRatio) / self._conversionFactor;
var selectWidth = ($ShapeWrapper.width() / self._transformRatio) / self._conversionFactor;
var selectHeight = ($ShapeWrapper.height() / self._transformRatio) / self._conversionFactor;
self._shapeData = '{"left":"' + startX + '","top":"' + startY + '","height":"' + selectHeight + '","width":"' + selectWidth + '"}';
svgShape.remove();
}
}
$thisComp.mousemove(function (event) {
if ($ShapeWrapper.length > 0) {
var width = 0;
var height = 0;
if (event.clientX <= self._selectorLeftPos) {
width = $ShapeWrapper.offset().left - event.clientX + $ShapeWrapper.width();
$ShapeWrapper.css("left", event.clientX);
}
else {
width = event.clientX - $ShapeWrapper.offset().left;
}
if (event.clientY <= self._selectorTopPos) {
height = $ShapeWrapper.offset().top - event.clientY + $ShapeWrapper.height();
$ShapeWrapper.css("top", event.clientY);
}
else {
height = event.clientY - $ShapeWrapper.offset().top;
}
$ShapeWrapper.css("width", width);
$ShapeWrapper.css("height", height);
if (width > 3 || height > 3) {
self._dragged = true;
}
}
});
$thisComp.bind("mouseup", removeShape);
$thisComp.bind("mouseleave", removeShape);
Css
.thisComp{
height:400px;
width:400px;
background-color:yellow;
}

How to make a border?

I have element
<div id="square"></div>
He has a property to move on document
var square = document.getElementById("square");
document.body.onkeydown = function(e) {
if (e.keyCode == 37) {left()}
if (e.keyCode == 38) {up()}
if (e.keyCode == 39) {right()}
if (e.keyCode == 40) {down()}
}
How I make a function, which not allowed movement, if square element is closest to document border?
JSFiddle: https://jsfiddle.net/zutxyLsq/
You need to check if left is outside of boundaries like this:
function left() {
console.log('Left');
var left = parseInt(square.style.left || getComputedStyle(square)['left'], 10);
if (left >= 50) {
square.style.left = (left - 50) + 'px';
}
}
function right() {
console.log('Right');
var left = parseInt(square.style.left || getComputedStyle(square)['left'], 10);
if (left+50+square.offsetWidth < window.innerWidth) {
square.style.left = (left + 50) + 'px';
}
}
https://jsfiddle.net/zutxyLsq/3/
and the same for up and down.

Categories