Only the first window is draggable - javascript

I created a code, where a window pops up. This window is draggable and resizable. I added a function in JavaScript, which adds two new windows when the first one is closed and adds more when the others are closed, but I also want them to be draggable as well.
I tried almost everything I know, but I don't seem to understand the issue.
const windowElement = document.querySelector("#window");
const header = document.querySelector("#header2");
const resizeContainer = document.querySelector("#resize-container");
let isDragging = false;
let currentX;
let currentY;
let xOffset = 0;
let yOffset = 0;
let isResizing = false;
let initialX;
let initialY;
let initialWidth;
let initialHeight;
let currentWidth;
let currentHeight;
const minimumWidth = 150;
const minimumHeight = 150;
header.addEventListener("mousedown", dragStart);
header.addEventListener("mouseup", dragEnd);
header.addEventListener("mousemove", drag);
resizeContainer.addEventListener("mousedown", resizeStart);
resizeContainer.addEventListener("mouseup", resizeEnd);
resizeContainer.addEventListener("mousemove", resize);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
isDragging = true;
}
function dragEnd(e) {
isDragging = false;
}
function drag(e) {
e.preventDefault();
if (isDragging) {
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, windowElement);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
function resizeStart(e) {
initialX = e.clientX;
initialY = e.clientY;
initialWidth = windowElement.offsetWidth;
initialHeight = windowElement.offsetHeight;
isResizing = true;
}
function resizeEnd(e) {
isResizing = false;
}
function resize(e) {
if (isResizing) {
currentWidth = initialWidth + (e.clientX - initialX);
currentHeight = initialHeight + (e.clientY - initialY);
if (currentWidth >= minimumWidth) {
windowElement.style.width = currentWidth + "px";
}
if (currentHeight >= minimumHeight) {
windowElement.style.height = currentHeight + "px";
}
}
}
function closeWindow() {
const parentElement = document.querySelector("#parent");
const windowElement = document.querySelector("#window");
windowElement.style.display = "none";
setTimeout(() => {
const newWindow1 = windowElement.cloneNode(true);
const newWindow2 = windowElement.cloneNode(true);
const xPos1 = Math.floor(Math.random() * (parentElement.offsetWidth - newWindow1.offsetWidth));
const yPos1 = Math.floor(Math.random() * (parentElement.offsetHeight - newWindow1.offsetHeight));
const xPos2 = Math.floor(Math.random() * (parentElement.offsetWidth - newWindow2.offsetWidth));
const yPos2 = Math.floor(Math.random() * (parentElement.offsetHeight - newWindow2.offsetHeight));
newWindow1.style.display = "";
newWindow2.style.display = "";
setTranslate(xPos1, yPos1, newWindow1);
setTranslate(xPos2, yPos2, newWindow2);
parentElement.appendChild(newWindow1);
parentElement.appendChild(newWindow2);
}, 500);
}
function createWindow() {
const parentElement = document.querySelector("#parent");
const windowElement = document.createElement("div");
let isDragging = false;
let currentX;
let currentY;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
isDragging = true;
}
function dragEnd(e) {
isDragging = false;
}
function drag(e) {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, this.parentNode);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
windowElement.classList.add("old-computer-window");
windowElement.style.left = Math.floor(Math.random() * (parentElement.offsetWidth - 300)) + "px";
windowElement.style.top = Math.floor(Math.random() * (parentElement.offsetHeight - 300)) + "px";
windowElement.setAttribute("data-aos", "zoom-in");
windowElement.setAttribute("data-aos-delay", "300");
const header = document.createElement("div");
header.classList.add("header2");
header.innerHTML = '<p>DANIEL.JPG</p><div class="close" onclick="closeWindow(this)">✕</div>';
const imageContainer = document.createElement("div");
imageContainer.classList.add("image-container");
const resizeContainer = document.createElement("div");
resizeContainer.classList.add("resize-container");
windowElement.appendChild(header);
windowElement.appendChild(imageContainer);
windowElement.appendChild(resizeContainer);
parentElement.appendChild(windowElement);
header.addEventListener("mousedown", dragStart);
header.addEventListener("mouseup", dragEnd);
header.addEventListener("mousemove", drag);
resizeContainer.addEventListener("mousedown", resizeStart);
resizeContainer.addEventListener("mouseup", resizeEnd);
resizeContainer.addEventListener("mousemove", resize);
}
#computer-window {
width: 100%;
height: 300px;
background-color: #ddd;
border-style: solid;
border-width: 2px;
border-left-color: white;
border-top-color: white;
border-bottom-color: darkred;
border-right-color: darkred;
}
#header2 {
background-color: black;
color: #fff;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
#title {
font-size: 20px;
font-weight: bold;
}
#close-btn {
border-style: solid;
border-width: 2px;
border-left-color: white;
border-top-color: white;
border-bottom-color: darkred;
border-right-color: darkred;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
#parent {
position: relative;
width: 800px;
height: 600px;
border: orange;
}
#window {
position: absolute;
width: 100%;
max-height: 1080px;
background-color: white;
border-style: solid;
border-width: 2px;
border-left-color: #191919;
border-top-color: #191919;
border-bottom-color: darkred;
border-right-color: darkred;
user-select: none;
overflow: hidden;
<div data-aos="zoom-in" data-aos-delay="300" id="parent">
<div class="old-computer-window" id="window">
<div class="header2" id="header2">
<p>DANIEL.JPG</p>
<div class="close" id="close" onclick="closeWindow()">✕</div>
</div>
<div class="image-container"></div>
<div class="resize-container" id="resize-container"></div>
</div>
</div>

Related

Custom cursor doesn't move

I'm trying to create a custom cursor for my website but it does not work well and I don't know what the problem is.
Here is the link to the code on Codepen
https://codepen.io/mahmoudkattan/pen/OJZXQow
const cursorTag = document.querySelector("div.cursor");
const cursor = cursorTag.querySelector("div");
let currentX = 0;
let currentY = 0;
let aimX = 0;
let aimY = 0;
let speed = 0.3;
const animate = function () {
currentX += (aimX - currentX) * speed;
currentY += (aimY - currentY) * speed;
cursor.style.left = currentX + "px";
cursor.style.top = currentY + "px";
requestAnimationFrame(animate);
};
animate();
document.addEventListener("mouseover", function (event) {
aimX = event.pageX;
aimY = event.pageY;
});
console.log(aimX);
div.cursor div {
z-index: 9999999;
position: fixed;
top: 300px;
left: 300px;
width: 45px;
height: 45px;
border: 1px solid var(--white);
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
}
<div class="cursor">
<div></div>
</div>
who can help with that?
Thanks
You want mousemove not mouseover
just change mouseover to mousemove
document.addEventListener("mousemove", function (event) {
aimX = event.pageX;
aimY = event.pageY;
});

Mapping image onto JS cloth and creating a slider

Here is all the code for the website, it has many bugs, like the footer which is stuck in the middle. So the idea is to create 11 different tissues in the format of this image mapped to the JS I have, bit i dont know how to do that.[![sample tissue][1]][1]
I would like to create a slider that functions when you click on the collection number it switchees to the next collection.
Also all the links only take the size and not the column width when hovered.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$</title>
<link rel="stylesheet" href="normalize.css">
<style type="text/css">
* {
margin: 0;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
font-family: sans-serif;
}
body {
}
#c {
display: block;
margin: 20px auto 0;
}
#info {
position: absolute;
left: -1px;
top: -1px;
width: auto;
max-width: 420px;
height: auto;
background: #f8f8f8;
border-bottom-right-radius: 10px;
border:1px solid #ccc;
}
#top {
background: #fff;
width: 100%;
height: auto;
position: relative;
border-bottom: 1px solid #eee;
}
p {
font-family: Arial, sans-serif;
color: #666;
text-align: justify;
font-size: 16px;
margin: 0px 16px;
}
#github, #twitter {
color:#3377ee;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
margin: 0 auto;
text-align: center;
text-decoration:none;
}
.center {
text-align: center;
}
#net {
text-align:center;
white-space:nowrap;
font-size:19px;
background:rgba(0,0,0,0.1);
padding:8px 12px;
border-radius:8px;
display:block;
color:#888;
}
#net > span {
color:#3377ee;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
display: block;
margin: 0 auto;
text-align: center;
text-decoration:none;
}
.bull {
opacity: 0.3;
margin: 0 6px;
font-size: 14px;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
border-bottom: 1px solid black;
}
.column {
flex-basis: 100%;
border-right: 1px solid black;
}
#media screen and (min-width: 800px) {
.column {
flex: 1;
}
}
#media screen and (min-width: 800px) {
._25 {
flex: 2.5;
}
._55 {
flex: 5.5;
}
._20 {
flex: 2;
}
}
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
color: black;
}
a:hover {
text-decoration: none;
color: white;
background: black;}
a:active {
text-decoration: none;
color: white;
background: black;
}
</style>
</head>
<body>
<div class="row">
<div class="column">
Rakṣas Sari collection
</div>
<div class="column">
Concept
</div>
<div class="column">
Process
</div>
</div>
<div class="row">
<div class="column">
Red Collection N°1
</div>
<div class="column">
Collection N°2
</div>
<div class="column">
Collection N°3
</div>
<div class="column">
Collection N°4
</div>
<div class="column">
Collection N°5
</div>
<div class="column">
Collection N°6
</div>
<div class="column">
Collection N°7
</div>
<div class="column">
Collection N°8
</div>
<div class="column">
Collection N°9
</div>
<div class="column">
Collection N°10
</div>
<div class="column">
Collection N°11
</div>
</div>
<div class="row">
<div class="column _25">
Project photoshoot
</div>
<div class="column _55">
<canvas id="c"></canvas>
<div id="top">
<a id="close" href="">Reset tissue</a>
</div>
</div>
<div class="column _20">
Red is a celebratory color. It commemorates a couple’s union. It symbolizes love, sensuality, and passion. That’s why it features prominently in auspicious occasions, such as weddings, festivals, and births. As red also signifies chastity, it is the color of choice for brides.
</div>
</div>
<footer>
<div class="row">
<div class="column">
©Copyright Angelo Barbattini
</div>
<div class="column">
ECAL 2022
</div>
</div>
</footer style="position: fixed;bottom: 0;">
<!--div id="new">
Wobble some <a target="_blank" href="https://codepen.io/dissimulate/details/dJgMaO">jelly</a> <span class="bull">•</span>
Check out my <a target="_blank" href="https://www.instagram.com/abro_oks/">instagram!</a>
</div-->
<script type="text/javascript">
document.getElementById("close").onmousedown = function (e) {
e.preventDefault();
document.getElementById("info").style.display = "none";
return false;
};
// settings
var physics_accuracy = 3,
mouse_influence = 20,
mouse_cut = 5,
gravity = 1200,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
var Point = function (x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};
Point.prototype.update = function (delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + (this.x - this.px) * 0.99 + (this.vx / 2) * delta;
ny = this.y + (this.y - this.py) * 0.99 + (this.vy / 2) * delta;
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0;
};
Point.prototype.draw = function () {
if (!this.constraints.length) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function () {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx
? (this.x = 2 * boundsx - this.x)
: 1 > this.x && (this.x = 2 - this.x);
this.y < 1
? (this.y = 2 - this.y)
: this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function (point) {
this.constraints.push(new Constraint(this, point));
};
Point.prototype.remove_constraint = function (constraint) {
this.constraints.splice(this.constraints.indexOf(constraint), 1);
};
Point.prototype.add_force = function (x, y) {
this.vx += x;
this.vy += y;
var round = 400;
this.vx = ~~(this.vx * round) / round;
this.vy = ~~(this.vy * round) / round;
};
Point.prototype.pin = function (pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function (p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function () {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
Constraint.prototype.draw = function () {
ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};
var Cloth = function () {
this.points = [];
var start_x = canvas.width / 2 - (cloth_width * spacing) / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)]);
this.points.push(p);
}
}
};
Cloth.prototype.update = function () {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(0.016);
};
Cloth.prototype.draw = function () {
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
function start() {
canvas.onmousedown = function (e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
(mouse.x = e.clientX - rect.left),
(mouse.y = e.clientY - rect.top),
(mouse.down = true);
e.preventDefault();
};
canvas.onmouseup = function (e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function (e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
(mouse.x = e.clientX - rect.left),
(mouse.y = e.clientY - rect.top),
e.preventDefault();
};
canvas.oncontextmenu = function (e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = "#888";
cloth = new Cloth();
update();
}
window.onload = function () {
canvas = document.getElementById("c");
ctx = canvas.getContext("2d");
canvas.width = 560;
canvas.height = 350;
start();
};
</script>
</body>
</html>```
[1]: https://i.stack.imgur.com/Celmj.jpg
The questioner is focusing on the problem of getting an actual image to look like material being moved with the wind.
The code presented to do this divides a canvas into small rectangular elements and moves each of those as required by the 'physics' given (value of gravity/wind for example).
The original just draws grid lines for each of these areas. What we need is for the equivalent rectangle in the original image to be copied to that point.
This snippet achieves this by adding a origx/y to the info kept about each point so that we know where to find the original rectangle.
It brings the image into an img element (it is important to wait until this is loaded before doing more with it) then copies it to an off-screen canvas that has the same dimensions as the one which will hold the material. This canvas is inspected when we need the 'mini image' to put at a given point.
WARNING: this code (even without the introduction of an image) is pretty processor intensive. On a farily powerful laptop with good GPU it was taking around 19% of CPU and not much less of GPU and the fan was whirring. This is even when there is no movement of the mouse. The code could do with a thorough look through, for example to stop the timer when user activity is completed, and perhaps putting the frame rate down (it's 60fps in the given code). I would not recommend it be put in a webpage and left there running - it will be a battery drainer.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
-->
<script type="text/javascript" src=""></script>
<link rel="stylesheet" type="text/css" href="">
<style type="text/css">
body {}
.wrapper {}
* {
margin: 0;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
body {
background: #333;
}
canvas {
background: #333;
width: 100%;
height: 376px;
margin: 0 auto;
display: block;
border: solid red 2px;
}
#info {
position: absolute;
left: -1px;
top: -1px;
width: auto;
max-width: 380px;
height: auto;
background: #f2f2f2;
border-bottom-right-radius: 10px;
}
#top {
background: #fff;
width: 100%;
height: auto;
position: relative;
border-bottom: 1px solid #eee;
}
p {
font-family: Arial, sans-serif;
color: #666;
text-align: justify;
font-size: 16px;
margin: 10px;
}
a {
font-family: sans-serif;
color: #444;
text-decoration: none;
font-size: 20px;
}
#site {
float: left;
margin: 10px;
color: #38a;
border-bottom: 1px dashed #888;
}
#site:hover {
color: #7af;
}
#close {
float: right;
margin: 10px;
}
#p {
font-family: Verdana, sans-serif;
position: absolute;
right: 10px;
bottom: 10px;
color: #adf;
border: 1px dashed #555;
padding: 4px 8px;
}
</style>
<img src="https://i.stack.imgur.com/Celmj.jpg" style="margin-top: -2000px; position: absolute;">
<canvas width="1360" height="376" style="margin-top: -2000px; position: absolute;"></canvas>
<script type="text/javascript">
/*
Copyright (c) 2013 lonely-pixel.com, Stuffit at codepen.io (http://codepen.io/stuffit)
View this and others at http://lonely-pixel.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
const mycanvas = document.querySelector('canvas');
const mycontext = mycanvas.getContext('2d');
// settings
var physics_accuracy = 5,
mouse_influence = 20,
mouse_cut = 6,
gravity = 900,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
window.onload = function() {
// ADDED TO BRING IN THE IMAGE
mycontext.clearRect(0, 0, mycanvas.width, mycanvas.height);
mycontext.drawImage(document.querySelector('img'), 0, 0, 1180, 376);
canvas = document.getElementById('c');
ctx = canvas.getContext('2d');
canvas.width = canvas.clientWidth;
canvas.height = 376;
canvas.onmousedown = function(e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};
canvas.onmouseup = function(e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function(e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};
canvas.oncontextmenu = function(e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = 'rgba(222,222,222,0.6)';
ctx.strokeStyle = 'magenta';
cloth = new Cloth();
update();
};
var Point = function(x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
//added - remember where this point was originally so we can get the right bit of the img
this.origx = x;
this.origy = y;
};
Point.prototype.update = function(delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0
};
Point.prototype.draw = function() {
if (this.constraints.length <= 0) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function() {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function(point) {
this.constraints.push(
new Constraint(this, point)
);
};
Point.prototype.remove_constraint = function(lnk) {
var i = this.constraints.length;
while (i--)
if (this.constraints[i] == lnk) this.constraints.splice(i, 1);
};
Point.prototype.add_force = function(x, y) {
this.vx += x;
this.vy += y;
};
Point.prototype.pin = function(pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function(p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function() {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
let num = 0;
Constraint.prototype.draw = function() {
ctx.drawImage(mycanvas, this.p1.origx, this.p1.origy, spacing, spacing, this.p1.x, this.p1.y, spacing + 1, spacing + 1);
};
var Cloth = function() {
this.points = [];
var start_x = canvas.width / 2 - cloth_width * spacing / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
this.points.push(p);
}
}
};
Cloth.prototype.update = function() {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(.016);
};
Cloth.prototype.draw = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
</script>
</head>
<body>
<canvas id="c" width="800" height="376"> </canvas>
</body>
</html>
Note: it is possible to 'tear' the material with a right click and this facility probably needs removing - unless you want users to ruin the look of the cloth :)

How to Draw on rotated canvas using mouse?

I want to draw on img its work fine but when i rotate the image its drawing axis is total change and it not draw on the right area
https://codepen.io/ali-shahzil/project/editor/AddPLW
var canvas;
var ctx;
var SCALE_MIN = 1,
SCALE_MAX = 25;
var currScale = 0; // def pic width=600px, 100px=1scale unit
var xscale = 1.0;
var scaleFactor = 1.00;
var painting = false,
mark = true,
lastX = 0,
lastY = 0,
lineThickness = 0.3,
width = 600,
height = 600;
var img = new Image();
img.src = 'img.JPG';
img.onload = function() {
canvas = document.getElementById("canvas1"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = document.getElementById("canvas2"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = ctx = ''; //reset
}
function doMarking() {
var checkBox = document.getElementById("mark");
if (checkBox.checked == true) {
mark = true;
if (canvas != null)
canvas.style.cursor = "pointer";
//currImgId = '';
} else {
mark = false;
if (canvas != null);
canvas.style.cursor = "";
}
lastX = 0,
lastY = 0,
painting = false;
}
function mouseDown(e) {
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - (e.target).offsetLeft;
lastY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
lastX = lastX * scaleX;
lastY = lastY * scaleY;
//console.log('Before lasX=' + lastX + ' lastY=' + lastY+',currScale='+currScale);
//lastX=transformSimple(lastX);
// lastY=transformSimple(lastY);
//console.log('After lasX=' + lastX + ' lastY=' + lastY+', currScale='+currScale);
//console.log('offleft=' + (e.target).offsetLeft + ', offsetTop=' + (e.target).offsetTop);
// console.log('e=' + e);
}
/*
canvas1.onmousedown=function (e) {
console.log('mousedown2 id=' + e);
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
console.log('lasX=' + lastX + ' lastY=' + lastY);
}
*/
function mouseUp(e) {
if (!mark)
return;
painting = false;
}
function mouseMove(e) {
if (!mark)
return;
if (painting) {
mouseX = e.pageX - (e.target).offsetLeft;
mouseY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
mouseX = mouseX * scaleX;
mouseY = mouseY * scaleY;
// mouseX=transformSimple(mouseX);
// mouseY=transformSimple(mouseY);
//console.log('mx=' + mouseX + ', my=' + mouseY);
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep) {
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 10;
if (lineThickness < 1) {
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
// translate(y,x);
ctx.fillRect(y, x, lineThickness, lineThickness);
//ctx.fillRect(transformSimple(y), transformSimple(x), lineThickness, lineThickness);
} else {
ctx.fillRect(x, y, lineThickness, lineThickness);
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
// console.log('x=' + x + ', y=' + y );
}
lastX = mouseX;
lastY = mouseY;
}
}
/*
canvas.addEventListener('click', function (event) {
if (mark)
return;
//get the img of convas
});*/
//-------------- img zooms
function zoomin_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
//console.log('zoomin currWidth='+currWidth);
if (currWidth >= 1500) return false;
else {
canvas.style.width = (currWidth + 100) + "px";
//if (currScale < SCALE_MAX)
// currScale++;
//console.log('scale=' + currScale);
}
}
}
function zoomout_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
if (currWidth <= 100) return false;
else {
canvas.style.width = (currWidth - 100) + "px";
//if (currScale > SCALE_MIN)
// currScale--;
//console.log('scale=' + currScale);
}
}
}
var currImgId = null;
function selectImg(e) {
if (currImgId != null) {
document.getElementById(currImgId).style.border = "none";
}
e.target.style.border = "2px solid orange";
currImgId = (e.target).getAttribute('id');
if (typeof canvas !== 'undefined') {
// the variable is defined
canvas = e.target;
ctx = canvas.getContext("2d");
}
//ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
}
function rotate() {
if (currImgId != null) {
document.getElementById(currImgId).setAttribute("class", "rotated-image");
}
}
var degrees = 0;
function rotateRight() {
console.log('currimgid=' + currImgId);
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees + 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function rotateLeft() {
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees - 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function translate(X, Y) {
console.log('untransformed x=' + X + ', y=' + Y);
// const point = {x: 0, y: 0};
const matrix = ctx.getTransform();
const transformedPoint = {
x: matrix.a * X + matrix.c * Y + matrix.e,
y: matrix.b * X + matrix.d * Y + matrix.f,
};
console.log('transformed x=' + transformedPoint.x + ', y=' + transformedPoint.y);
}
function translateSimple(X, Y) {
//console.log('scalefactor='+scaleFactor);
console.log('untransformed x=' + X + ', y=' + Y);
if (scaleFactor >= 1.0)
console.log('transformed x=' + X / scaleFactor + ', y=' + Y / scaleFactor);
else
console.log('transformed x=' + X * scaleFactor + ', y=' + Y * scaleFactor);
}
function transformSimple(a) {
//return (parseInt(a/(scaleFactor*scaleFactor)));
if (currScale == 0)
return (a);
else
return (a - 16 * (currScale));
}
function draw() {
for (var x = 100; x < 102; x++)
ctx.fillRect(100, x, 4.9, 4.9);
}
.main_bottom {
background-color: #e8e9eb;
display: flex;
align-items: center;
justify-content: space-around;
border: 10px solid #e8e9eb;
border-top: 30px solid #e8e9eb;
height: 90vh;
}
form {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
margin-bottom: 5px;
}
.scrollit {
/*overflow-y: auto;*/
/* overflow-y: scroll;*/
height: 300px;
overflow-x: hidden;
overflow-y: auto;
}
.first {
display: flex;
flex-direction: row;
visibility: hidden;
}
.submit {
display: flex;
flex-direction: row;
}
img {
width: 100%;
max-width: 800px;
height: auto;
display: block;
margin-left: auto;
margin-right: auto;
}
.fix {
height: 300px;
margin-top: 200px;
}
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
}
#left_panel {
display: flex;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 700px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#right_panel {
display: flex;
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 700px;
margin-right: 15px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#drag {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 8px;
cursor: w-resize;
}
/*img zooms*/
#navbar {
overflow: hidden;
background-color: #099;
position: fixed;
top: 0;
width: 100%;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 20px;
}
#navbar a {
float: left;
display: block;
color: #666;
text-align: center;
padding-right: 20px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
#navbar a.active {
background-color: #4caf50;
color: white;
}
.main {
padding: 16px;
margin-top: 30px;
width: 100%;
height: 100vh;
overflow: auto;
cursor: grab;
cursor: -o-grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
.main img {
height: auto;
width: auto;
}
.button {
width: 300px;
height: 60px;
}
/*---- toggle switch*/
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked+.slider {
background-color: #2196f3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
.both {
margin-top: 50px;
display: flex;
justify-content: center;
}
<!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">
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<title>Order by Picture</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div id="navbar">
<button type="button" onclick="zoomin_canvas()">+</button>
<button type="button" onclick="zoomout_canvas()">-</button>
<button id="rotateRight" onclick="rotateRight()">Right</button>
<button id="rotateLeft" onclick="rotateLeft()">Left</button>
<button id="Button1" onclick="draw()">draw</button
<label> Marking</label>
<label class="switch">
<input type="checkbox" checked onclick="doMarking()" id="mark">
<span class="slider round"></span>
</label>
</div>
<div class="both">
<div class="canvas1">
<canvas id="canvas1" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<div class="canvas2">
<canvas id="canvas2" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
</div>
</body>
</html>
Don't rotate the canvas
Draw the rotated image on the canvas, rather than rotate the canvas.
When you draw image on the canvas, rotate it, then you can draw over it using the normal mouse coords.
Rotating image on canvas
The code below will draw an image rotated by any amount. The image will be scaled down if needed to ensure it fits the canvas. The function will rotate the image any angle you want.
// ctx is canvas 2D context
// deg in degrees rotated CW from 3 O-clock
// img to render. NOTE image must be loaded first
function drawRotatedImage(ctx, deg, img) {
const w = img.naturalWidth;
const h = img.naturalHeight;
const cw = ctx.canvas.width;
const ch = ctx.canvas.height;
// convert deg to radians
const rad = deg * Math.PI / 180;
// Get vector for rotated xAxis ax, ay. With aax, aay in first quadrant
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
// get the rotated width and height of image
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
// get scale so that image fits the canvas. Dont enlarge only reduce if to big
const scale = Math.min(1, cw / tw, ch / th);
// set canvas transform to center of canvas, rotated and scaled to fit
ctx.setTransform(ax * scale, ay * scale, -ay * scale, ax * scale, cw / 2, ch / 2);
// draw image on canvas offset by half its width and height
ctx.drawImage(img, -w / 2, -h / 2);
// restore canvas transform to default
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
Example
Example using the above function to render image to canvas and then use mouse to draw over the image. Click rotate to rotate the image.
const ctx = canvas.getContext("2d");
const mouse = {x: 0, y: 0, b: false, ox: 0, oy: 0};
var rot = 90;
const img = new Image;
img.src = "https://i.stack.imgur.com/C7qq2.png?s=420&g=1";
img.onload = () => rotImage(ctx, rot, img);
resize();
addEventListener("resize", resize);
rotBtn.addEventListener("click", () => img.complete && rotImage(ctx, rot += 90, img));
addEventListener("mousemove", mouseEvent);
addEventListener("mousedown", mouseEvent);
addEventListener("mouseup", mouseEvent);
addEventListener("mouseout", mouseEvent);
function resize() {
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.strokeStyle = "#00F";
img.complete && rotImage(ctx, rot, img);
}
function mouseEvent(e) {
mouse.ox = mouse.x;
mouse.oy = mouse.y;
mouse.x = e.pageX;
mouse.y = e.pageY;
if (e.type === "mousedown") { mouse.b = true }
else if (e.type === "mouseup" || e.type === "mouseout") { mouse.b = false }
mouse.b && drawWithMouse(ctx, mouse);
}
function drawWithMouse(ctx, mouse) {
ctx.beginPath();
ctx.lineTo(mouse.ox, mouse.oy);
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
}
function rotImage(ctx, deg, img) {
const cw = ctx.canvas.width, ch = ctx.canvas.height;
const w = img.naturalWidth, h = img.naturalHeight;
const rad = deg * Math.PI / 180;
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
const sc = Math.min(1, cw / tw, ch / th);
ctx.clearRect(0, 0, cw, ch);
ctx.setTransform(ax * sc, ay * sc, -ay * sc, ax * sc, cw / 2, ch / 2);
ctx.drawImage(img, -w / 2, -h / 2);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
* {font-family: arial;}
button { position: absolute; top: 10px; left: 10px }
canvas { position: absolute; top: 0px; left: 0px }
<canvas id="canvas"></canvas>
<button id="rotBtn">Rotate</button>

how to resize div after rotating it (is it possible to modify the mouse event coordinates based on the rotation?)

there are 8 nodes around a div which can resize the div in 8 directions, when the div is not rotated, they can resize properly. However, when the div is rotated, for example, 90 degrees clockwise, then the behavior is weird, since the mouse event is different with the rotated div.
i've checked these but didn't help:
Logic to set fixed corner while resize after rotate?
How to resize with fixed corner after rotate?
i made a demo here: https://output.jsbin.com/nobasavaza
any ideas?
```
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
#cut {
opacity: 0.6;
height: 150px;
width: 150px;
position: absolute;
top: 150px;
left: 150px;
cursor: pointer;
border: 1px dotted red;
}
.box-resize {
border: 1px solid black;
width: 4px;
height: 4px;
position: absolute;
}
.box-top-left {
top: -3px;
left: -3px;
cursor: nw-resize;
}
.box-top-right {
top: -3px;
right: -3px;
cursor: ne-resize;
}
.box-left-center {
top: 50%;
left: -3px;
cursor: w-resize;
}
.box-right-center {
top: 50%;
right: -3px;
cursor: e-resize;
}
.box-bottom-left {
left: -3px;
bottom: -3px;
cursor: sw-resize;
}
.box-bottom-right {
right: -3px;
bottom: -3px;
cursor: se-resize;
}
.box-top-center {
left: 50%;
top: -3px;
cursor: n-resize;
}
.box-bottom-center {
left: 50%;
bottom: -3px;
cursor: s-resize;
}
</style>
</head>
<body>
<input type="text" id="rotate_degree" placeholder="degree in closewise">
<button id="rotate_submit">rorate</button>
<div id="cut">
hello
<div class="box-resize box-top-left"></div>
<div class="box-resize box-top-right"></div>
<div class="box-resize box-left-center"></div>
<div class="box-resize box-right-center"></div>
<div class="box-resize box-bottom-left"></div>
<div class="box-resize box-bottom-right"></div>
<div class="box-resize box-top-center"></div>
<div class="box-resize box-bottom-center"></div>
</div>
<script>
window.onload = function () {
var resize = document.getElementsByClassName("box-resize");
var cut = document.getElementById("cut");
var cutWidth = 0;
var cutHeight = 0;
var startX = 0;
var startY = 0;
var top = 0;
var left = 0;
var dir = "";
for (var i = 0; i < resize.length; i++) {
resize[i].onmousedown = function (e) {
startX = e.clientX;
startY = e.clientY;
cutWidth = cut.offsetWidth;
cutHeight = cut.offsetHeight;
top = cut.offsetTop;
left = cut.offsetLeft;
var className = this.className;
if (className.indexOf("box-right-center") > -1) {
dir = "E";
}
else if (className.indexOf("box-top-left") > -1) {
dir = "NW";
}
else if (className.indexOf("box-top-right") > -1) {
dir = "NE";
}
else if (className.indexOf("box-left-center") > -1) {
dir = "W";
}
else if (className.indexOf("box-bottom-left") > -1) {
dir = "SW";
}
else if (className.indexOf("box-bottom-right") > -1) {
dir = "SE";
}
else if (className.indexOf("box-bottom-center") > -1) {
dir = "S";
}
else if (className.indexOf("box-top-center") > -1) {
dir = "N";
}
document.addEventListener('mousemove', test);
e.preventDefault();
}
}
document.onmouseup = function (e) {
dir = "";
document.removeEventListener('mousemove', test);
e.preventDefault();
}
function test(e) {
var width = e.clientX - startX;
var height = e.clientY - startY;
if (dir == "E") {
cut.style.width = cutWidth + width + "px";
}
else if (dir == "S") {
cut.style.height = cutHeight + height + "px";
}
else if (dir == "N") {
if (height < cutHeight) {
cut.style.height = cutHeight - height + "px";
cut.style.top = top + height + "px";
}
}
else if (dir == "W") {
if (width < cutWidth) {
cut.style.width = cutWidth - width + "px";
cut.style.left = left + width + "px";
}
}
else if (dir == "NW") {
if (width < cutWidth && height < cutHeight) {
cut.style.width = cutWidth - width + "px";
cut.style.height = cutHeight - height + "px";
cut.style.top = top + height + "px";
cut.style.left = left + width + "px";
}
}
else if (dir == "NE") {
if (height < cutHeight) {
cut.style.width = cutWidth + width + "px";
cut.style.height = cutHeight - height + "px";
cut.style.top = top + height + "px";
}
}
else if (dir == "SW") {
if (width < cutWidth) {
cut.style.width = cutWidth - width + "px";
cut.style.height = cutHeight + height + "px";
cut.style.left = left + width + "px";
}
}
else if (dir == "SE") {
if (width < cutWidth) {
cut.style.width = cutWidth + width + "px";
cut.style.height = cutHeight + height + "px";
}
}
}
}
document.getElementById('rotate_submit').addEventListener('click', function () {
const degree = document.getElementById('rotate_degree');
document.getElementById("cut").style.transform = 'rotate(' + degree.value + 'deg)';
})
</script>
</body>
</html>
```

Drag an HTML box and make another box follow it with JavaScript

I am trying to create something like drag a box (Hello World) to any location, and the second box (Follow World) will follow slowly.
In the code below, the drag box is fine, but the follow box will not follow properly. Also, the drag box cannot drop.
function startDrag(e) {
// determine event object
if (!e) {
var e = window.event;
}
// IE uses srcElement, others use target
var targ = e.target ? e.target : e.srcElement;
if (targ.className != 'dragme') {
return
};
// calculate event X, Y coordinates
offsetX = e.clientX;
offsetY = e.clientY;
// assign default values for top and left properties
if (!targ.style.left) {
targ.style.left = '0px'
};
if (!targ.style.top) {
targ.style.top = '0px'
};
// calculate integer values for top and left
// properties
coordX = parseInt(targ.style.left);
coordY = parseInt(targ.style.top);
drag = true;
// move div element
document.onmousemove = dragDiv;
return false;
}
function dragDiv(e) {
if (!drag) {
return
};
if (!e) {
var e = window.event
};
var targ = e.target ? e.target : e.srcElement;
// move div element
targ.style.left = coordX + e.clientX - offsetX + 'px';
targ.style.top = coordY + e.clientY - offsetY + 'px';
return false;
}
function stopDrag() {
timer();
drag = false;
}
window.onload = function() {
document.onmousedown = startDrag;
document.onmouseup = stopDrag;
}
function disp() {
var step = 1;
var y = document.getElementById('followme').offsetTop;
var x = document.getElementById('followme').offsetLeft;
var ty = document.getElementById('draggable').offsetTop;
var ty = document.getElementById('draggable').offsetLeft;
if (y < ty) {
y = y + step;
document.getElementById('followme').style.top = y + "px"; // vertical movment
} else {
if (x < tx) {
x = x + step;
document.getElementById('followme').style.left = x + "px"; // horizontal movment
}
}
}
function timer() {
disp();
var y = document.getElementById('followme').offsetTop;
var x = document.getElementById('followme').offsetLeft;
document.getElementById("msg").innerHTML = "X: " + tx + " Y : " + ty
my_time = setTimeout('timer()', 10);
}
.dragme {
position: relative;
width: 60px;
height: 80px;
cursor: move;
}
.followme {
position: relative;
width: 60px;
height: 80px;
}
#draggable {
background-color: #ccc;
border: 1px solid #000;
}
#followme {
background-color: #ccc;
border: 1px solid #000;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Drag and drop</title>
</head>
<body>
<div id='msg'></div>
<div id="draggable" class="dragme">"Hello World!"</div>
<div id="followme" class="followme">"Follow World!"</div>
Fix yours disp and timer functions to this:
function disp()
{
var step = 1;
// in dragDiv() you modifying style.left/style.top properties, not offsetTop/offsetLeft
var x = parseInt(document.getElementById('followme').style.left) || 0;
var y = parseInt(document.getElementById('followme').style.top) || 0;
var tx = parseInt(document.getElementById('draggable').style.left) || 0;
var ty = parseInt(document.getElementById('draggable').style.top) || 0;
// properly calculate offset
var dx = ((dx = tx - x) == 0) ? 0 : Math.abs(dx) / dx;
var dy = ((dy = ty - y) == 0) ? 0 : Math.abs(dy) / dy;
document.getElementById('followme').style.left = (x + dx * step) + "px"; // horisontal movment
document.getElementById('followme').style.top = (y + dy * step) + "px"; // vertical movment
}
function timer()
{
disp();
var y=document.getElementById('followme').offsetTop;
var x=document.getElementById('followme').offsetLeft;
document.getElementById("msg").innerHTML="X: " + x + " Y : " + y; // typo was here
my_time = setTimeout(function () {
clearTimeout(my_time); // need to clear timeout or it'll be adding each time 'Hello world' clicked
timer();
},10);
}
In the following snippet, the pink box is draggable and the blue box follows it around. You can change pixelsPerSecond to adjust the speed of movement.
function message(s) {
document.getElementById('messageContainer').innerHTML = s;
}
window.onload = function () {
var pixelsPerSecond = 80,
drag = document.getElementById('drag'),
follow = document.getElementById('follow'),
wrapper = document.getElementById('wrapper'),
messageContainer = document.getElementById('messageContainer'),
leftMax,
topMax;
function setBoundaries() {
leftMax = wrapper.offsetWidth - drag.offsetWidth;
topMax = wrapper.offsetHeight - drag.offsetHeight;
drag.style.left = Math.min(drag.offsetLeft, leftMax) + 'px';
drag.style.top = Math.min(drag.offsetTop, topMax) + 'px';
}
setBoundaries();
window.onresize = setBoundaries;
[drag, follow, messageContainer].forEach(function (element) {
element.className += ' unselectable';
element.ondragstart = element.onselectstart = function (event) {
event.preventDefault();
};
});
var start = Date.now();
drag.onmousedown = function (event) {
event = event || window.event;
var x0 = event.pageX || event.clientX,
y0 = event.pageY || event.clientY,
left0 = drag.offsetLeft,
top0 = drag.offsetTop;
window.onmousemove = function (event) {
var x = event.pageX || event.clientX,
y = event.pageY || event.clientY;
drag.style.left = Math.max(0, Math.min(left0 + x - x0, leftMax)) + 'px';
drag.style.top = Math.max(0, Math.min(top0 + y - y0, topMax)) + 'px';
};
window.onmouseup = function () {
window.onmousemove = window.onmouseup = undefined;
};
};
follow.x = follow.offsetLeft;
follow.y = follow.offsetTop;
function update() {
var elapsed = Date.now() - start;
if (elapsed === 0) {
window.requestAnimationFrame(update);
return;
}
var x1 = drag.offsetLeft,
y1 = drag.offsetTop + (drag.offsetTop + drag.offsetHeight <= topMax ?
drag.offsetHeight : -drag.offsetHeight),
x0 = follow.x,
y0 = follow.y,
dx = x1 - x0,
dy = y1 - y0,
distance = Math.sqrt(dx*dx + dy*dy),
angle = Math.atan2(dy, dx),
dd = Math.min(distance, pixelsPerSecond * elapsed / 1000);
message('x: ' + x1 + ', y: ' + y1);
follow.x += Math.cos(angle) * dd;
follow.style.left = follow.x + 'px';
follow.y += Math.sin(angle) * dd;
follow.style.top = follow.y + 'px';
start = Date.now();
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
};
#wrapper {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #eee;
font-family: sans-serif;
text-align: center;
}
.unselectable {
-webkit-user-select: none;
-khtml-user-drag: none;
-khtml-user-select: none;
-moz-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
#messageContainer {
position: absolute;
left: 80px;
top: 50px;
font-size: 36px;
color: #aaa;
cursor: default;
}
.box {
position: absolute;
width: 60px;
height: 80px;
}
.label {
margin: 30px auto;
font-size: 14px;
}
#drag {
left: 100px;
top: 120px;
background: #f0dddb;
border: 2px solid #deb7bb;
cursor: move;
}
#follow {
left: 0;
top: 0;
background-color: #ddebf3;
border: 2px solid #bfd5e1;
cursor: default;
}
<div id="wrapper">
<div id="messageContainer"></div>
<div class="box" id="follow"> <div class="label">it follows</div> </div>
<div class="box" id="drag"> <div class="label">drag me</div> </div>

Categories

Resources