div Resizing with inner content and maintain aspect ratio - javascript

I have made a code pen example for complete understanding please checkout this link
https://codepen.io/hasan-irshad/pen/bGpPZzB
this is the code which i am using for bottom right corner
if (currentResizer.classList.contains('bottom-right')) {
const width = original_width + (e.pageX - original_mouse_x);
const height = original_height + (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px'
element.style.height = 'max-content';
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
}
}
if you resize div from bottom right corner it works fine as I want it to work, from bottom right corner it increases/decreases width of div according to the mouse-X, and height of div according to the inner content height. This is the behavior which I want to implement on all the corners.
for example if I drag from bottom right corner so the top left corner stays at it's position
just like that if I resize it from top right corner so bottom left corner should maintain it's position.
expected behavior
1 width of outer element should depend on mouse-X
2 font size should be dependent on width of outer div
3 height of outer div should depend on inner content height
4 div element should not lose its position
below is a link of video for demonstration of end result which I want to implement.
drive.google.com/file/d/1Wgh3GhEOhv1syk_WFmcCGp0UJUyGzS5u/view
can anybody please help me complete this task?
Thanks a lot in advance!!!!!

I comment the things out you dont need, and inserted the things you should add, it was mainly that you dont need to set the realtive position and you needed to set the height to "max-content", and the only time you add a script to change your font-size was in the right-bottom corner.
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
/*Make resizable div by Hung Nguyen*/
function makeResizableDiv(div) {
const element = document.querySelector(div);
const resizers = document.querySelectorAll(div + ' .resizer')
const minimum_size = 20;
let original_width = 0;
let original_height = 0;
let original_x = 0;
let original_y = 0;
let original_mouse_x = 0;
let original_mouse_y = 0;
for (let i = 0;i < resizers.length; i++) {
const currentResizer = resizers[i];
currentResizer.addEventListener('mousedown', function(e) {
e.preventDefault()
original_width = parseFloat(getComputedStyle(element, null).getPropertyValue('width').replace('px', ''));
original_height = parseFloat(getComputedStyle(element, null).getPropertyValue('height').replace('px', ''));
original_x = element.getBoundingClientRect().left;
original_y = element.getBoundingClientRect().top;
original_mouse_x = e.pageX;
original_mouse_y = e.pageY;
window.addEventListener('mousemove', resize)
window.addEventListener('mouseup', stopResize)
})
function resize(e) {
if (currentResizer.classList.contains('bottom-right')) {
const width = original_width + (e.pageX - original_mouse_x);
const height = original_height + (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px'
element.style.height = 'max-content';
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
}
}
else if (currentResizer.classList.contains('bottom-left')) {
const height = original_height + (e.pageY - original_mouse_y)
const width = original_width - (e.pageX - original_mouse_x)
if (height > minimum_size) {
element.style.height = "max-content"
}
if (width > minimum_size) {
element.style.width = width + 'px'
element.style.left = original_x + (e.pageX - original_mouse_x) + 'px'
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
}
}
else if (currentResizer.classList.contains('top-right')) {
const width = original_width + (e.pageX - original_mouse_x)
const height = original_height - (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px'
element.style.height = "max-content"
//element.style.top = original_y + (e.pageY - original_mouse_y) + 'px'
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
}
}
else {
const width = original_width - (e.pageX - original_mouse_x)
const height = original_height - (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px'
element.style.left = original_x + (e.pageX - original_mouse_x) + 'px'
}
if (height > minimum_size) {
element.style.height = "max-content"
//element.style.top = original_y + (e.pageY - original_mouse_y) + 'px'
}
let Textdiv = document.getElementById('Text');
let relFontsizew = Textdiv.offsetWidth * 0.25;
Textdiv.style.fontSize = relFontsizew + 'px';
}
}
function stopResize() {
window.removeEventListener('mousemove', resize)
}
}
}
makeResizableDiv('.resizable')
body,
html {
background: black;
}
.resizable {
background: white;
width: 100px;
height: 100px;
position: absolute;
top: 100px;
left: 100px;
}
.resizable .resizers{
width: 100%;
height: 100%;
border: 3px solid #4286f4;
box-sizing: border-box;
}
.resizable .resizers .resizer{
width: 10px;
height: 10px;
border-radius: 50%; /*magic to turn square into circle*/
background: white;
border: 3px solid #4286f4;
position: absolute;
}
.resizable .resizers .resizer.top-left {
left: -5px;
top: -5px;
cursor: nwse-resize; /*resizer cursor*/
}
.resizable .resizers .resizer.top-right {
right: -5px;
top: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-left {
left: -5px;
bottom: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-right {
right: -5px;
bottom: -5px;
cursor: nwse-resize;
}
<div class='resizable'>
<div class='resizers'>
<div class='resizer top-left'></div>
<div class='resizer top-right'></div>
<div class='resizer bottom-left'></div>
<div class='resizer bottom-right'></div>
<article id="Text" style=" width:100%; font-size:22px; color:black">Any Text</article>
</div>
</div>

Related

How to build a resizable DIV that works with overflow: auto?

I have a resizable DIV that is resizable in the 4 sides. How ever, in some cases the content of this DIV may exceed its size. So I've added the option overflow: auto, but when I use this option, the component responsible to resize the DIV moves with the scroll.
Here's the code:
https://codesandbox.io/s/23kt1?file=/index.html
How can I fix the component always on the edges of the DIV in such a way that it's not moved when the user scroll the div?
You need an extra container for the dots to align to.
function resizeable() {
var resizers = document.querySelectorAll('.n, .s, .w, .e, .nw, .ne, .se, .sw');
const min = 40;
for (let i = 0; i < resizers.length; i++) {
const currentResizer = resizers[i];
const element = currentResizer.parentElement;
const parent = currentResizer.parentElement.parentElement;
let p;
let c;
let original_w = 0;
let original_h = 0;
let parent_x = 0;
let parent_y = 0;
let parent_sx = 0;
let parent_sy = 0;
let child_x = 0;
let child_y = 0;
let mouse_x = 0;
let mouse_y = 0;
let scale_x = 0;
let scale_y = 0;
let scroll_x = 0;
let scroll_y = 0;
// Mouse events
currentResizer.addEventListener('mousedown', function(e) {
first(e);
document.addEventListener('mousemove', resize);
document.addEventListener('mouseup', stopResize);
e.preventDefault();
});
// First location & width
function first(e) {
c = element.getBoundingClientRect();
child_y = c.top;
child_x = c.left;
p = parent.getBoundingClientRect();
parent_y = p.top;
parent_x = p.left;
parent_sy = parent.scrollTop;
parent_sx = parent.scrollLeft;
scroll_y = window.scrollY;
scroll_x = window.scrollX;
original_w = parseFloat(c.width).toFixed(2);
original_h = parseFloat(c.height).toFixed(2);
scale_y = parseFloat(c.height / element.offsetHeight).toFixed(2);
scale_x = parseFloat(c.width / element.offsetWidth).toFixed(2);
mouse_y = e.pageY - scroll_y;
mouse_x = e.pageX - scroll_x;
}
// Resize process
function resize(e) {
element.style.position = "absolute";
if (currentResizer.classList.contains('se')) {
const width = e.pageX - scroll_x - child_x;
const height = e.pageY - scroll_y - child_y;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
if (parent.scrollTop < parent.scrollHeight) {
parent.scrollTop = parent.scrollHeight;
}
if (parent.scrollLeft < parent.scrollWidth) {
parent.scrollLeft = parent.scrollWidth;
}
} else if (currentResizer.classList.contains('sw')) {
const width = original_w - (e.pageX - scroll_x - child_x);
const height = e.pageY - scroll_y - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
if (width > min) {
element.style.left = e.pageX - scroll_x - parent_x + parent_sx + 'px';
element.style.width = (width / scale_x) + 'px';
}
if (parent.scrollTop < parent.scrollHeight) {
parent.scrollTop = parent.scrollHeight;
}
} else if (currentResizer.classList.contains('ne')) {
const width = e.pageX - child_x - scroll_x;
const height = original_h - (e.pageY - mouse_y - scroll_y);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y - scroll_y + parent_sy + 'px';
}
if (parent.scrollLeft < parent.scrollWidth) {
parent.scrollLeft = parent.scrollWidth;
}
} else if (currentResizer.classList.contains('nw')) {
const width = original_w - (e.pageX - scroll_x - child_x);
const height = original_h - (e.pageY - scroll_y - mouse_y);
if (width > min) {
element.style.left = e.pageX - parent_x - scroll_x + parent_sx + 'px';
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y - scroll_y + parent_sy + 'px';
}
} else if (currentResizer.classList.contains('e')) {
const width = e.pageX - scroll_x - child_x;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (parent.scrollLeft < parent.scrollWidth) {
parent.scrollLeft = parent.scrollWidth;
}
} else if (currentResizer.classList.contains('s')) {
const height = e.pageY - scroll_y - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
if (parent.scrollTop < parent.scrollHeight) {
parent.scrollTop = parent.scrollHeight;
}
} else if (currentResizer.classList.contains('w')) {
const width = original_w - (e.pageX - scroll_x - child_x);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
element.style.left = (e.pageX - scroll_x - parent_x + parent_sx) + 'px';
}
} else if (currentResizer.classList.contains('n')) {
const height = original_h - (e.pageY - scroll_y - mouse_y);
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y - scroll_y + parent_sy + 'px';
}
}
}
// When mouse released stop
function stopResize(e) {
first(e);
document.removeEventListener('mousemove', resize);
}
}
}
resizeable();
body {
width: 1200px;
}
div {
position: absolute;
background-color: grey;
}
.regular {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: red;
overflow: auto;
position: absolute;
}
.n,
.s,
.w,
.e,
.nw,
.ne,
.se,
.sw {
position: absolute;
width: 18px;
height: 18px;
border: 1px solid grey;
border-radius: 20px;
background-color: #fff;
z-index: 1;
}
.n:hover,
.s:hover,
.w:hover,
.e:hover,
.nw:hover,
.ne:hover,
.se:hover,
.sw:hover {
background-color: red;
}
.nw {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.ne {
top: -10px;
left: calc(100% - 10px);
cursor: ne-resize;
}
.sw {
top: calc(100% - 10px);
left: -10px;
cursor: sw-resize;
}
.se {
top: calc(100% - 10px);
left: calc(100% - 10px);
cursor: se-resize;
}
.n {
top: -10px;
left: calc(50% - 10px);
cursor: n-resize;
}
.w {
top: calc(50% - 10px);
left: -10px;
cursor: w-resize;
}
.e {
top: calc(50% - 10px);
left: calc(100% - 10px);
cursor: e-resize;
}
.s {
top: calc(100% - 10px);
left: calc(50% - 10px);
cursor: s-resize;
}
.container {
position: relative;
width: 300px;
height: 300px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<div class="container">
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
<div class="regular">
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
<p>SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS</p>
</div>
</div>
<script src="/src/index.js"></script>
</body>
</html>

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>

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>
```

Not being able to draw over canvas html5

I am trying to draw a rectangle on a canvas in HTML5. If I use a canvas (with fileList as id) it is not getting displayed on the screen but if I used a div it is getting displayed. I want to display a rectangle over an image for annotation.
function initDraw(canvas) {
function setMousePosition(e) {
var ev = e || window.event;
if (ev.pageX) {
mouse.x = ev.pageX + window.pageXOffset;
mouse.y = ev.pageY + window.pageYOffset;
} else if (ev.clientX) {
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 = "crosshair";
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";
}
}
}
initDraw(document.getElementById('fileList'));
.rectangle {
border: 10px solid black;
position: absolute;
background-color: black;
}
<canvas id="fileList" height="680px" width="800px"></canvas>
Summary
You seem to be asking how to overlap a DIV on a canvas.
Answer
Using your CSS, use the Z-Index to control how the layers overlap
You will need to set one as Z-Index:0 and the DIV with Z-Index: of 1 or above;
Don't forget: that DIV elements without a height or width will not show show in Internet Explorer or Safari, so ensure your CSS includes a height and width
function funStart(){
if (typeof(document.getElementById("fileList").getContext("2d")) == undefined){
console.log ("No HTML5 Canvas support");
return;
}else{
var ctx = document.getElementById("fileList").getContext("2d");
}
ctx.canvas.height = 500;
ctx.canvas.width = 500;
ctx.fillStyle = "#F00";
ctx.fillRect (0,0, ctx.canvas.width, ctx.canvas.height);
ctx.fill();
}
document.addEventListener("DOMContentLoaded", funStart(), false);
.rectangle {
border: 10px solid silver;
color: white;
height: 300px;
width: 200px;
position: absolute;
top: 10;
left: 10;
background-color: black;
z-index: 23;
}
canvas{
position: absolute;
z-index: 0;
}
<canvas id="fileList" height="680px" width="800px"></canvas>
<div id="messageBoard" class="rectangle">My DIV Message goes here</div>
You're putting the .rectangle <div> inside the <canvas>, but the children of <canvas> are used as fallback content. They'll only be displayed if the browser doesn't support <canvas>.
Instead, wrap the <canvas> in a positioned element to create a manageable containing block, and add the .rectangles to that element:
function initDraw(canvas) {
function setMousePosition(e) {
var ev = e || window.event;
mouse.x = ev.offsetX;
mouse.y = ev.offsetY;
};
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 = "crosshair";
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.closest('.canvaswrap').appendChild(element);
canvas.style.cursor = "crosshair";
}
}
}
initDraw(document.getElementById('fileList'));
.rectangle {
border: 10px solid black;
position: absolute;
background-color: black;
box-sizing: border-box;
pointer-events: none;
}
.canvaswrap {
position: relative;
padding: 0;
}
<div class="canvaswrap">
<canvas id="fileList" height="680" width="800"></canvas>
</div>
(Since we're now positioning relative to an element instead of the entire page, I changed your setMousePosition logic as well. I also added box-sizing: border-box; to the .rectangles' styling so that they're not off the clicked coordinates by 10px, and pointer-events: none; so mouse events get sent to the <canvas> instead of being caught by overlaid .rectangles. And <canvas>'s height and width attributes are defined to be in pixels; you don't need to put the "px" in them.)

ContentEditable image resize in chrome, what is the best solution?

I'm trying to integrate image resizing using contentEditable on Chrome. I know there are problems with webkit about the normal operation of this feature, so I was wondering what is the best alternative method for the integration of image resizing in case a user uses Google Chrome (jQuery plugins? Javascript methods?).
<div contenteditable>
<img src="http://www.thebrandbite.com/wp-content/media/2015/07/apple-7.jpg" width=200 />
</div>
Here is how it works out-of-the-box with Firefox:
Your options are:
Use a library. They definitely exist: YUI has an image resize module, for example. I've never used it but the demo works in all the desktop browsers I tried.
Write your own: add some draggable positioned elements for the resize handles. I've done this before and it's not too hard if you know what you're doing.
#Tim-Down Answer is probably the better solution.
But I want to throw out there, that you can resize images with just CSS, if you don't want to do anything further with it:
http://codepen.io/anon/pen/JEEKqO
resize: both;
background-size: contain;
background-repeat: no-repeat;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/photoshop-face-after.jpg);
body {
background-color: #1D1F1F;
}
section {
display: table;
margin: 0 auto;
}
div {
resize: both;
background-color: white;
overflow: scroll;
background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/photoshop-face-after.jpg');
background-size: cover;
background-repeat: no-repeat;
}
<section>
<button>both</button>
<button>horizontal</button>
<button>vertical</button>
<button>none</button>
<div class="resize"></div>
</section>
Try this one (source):
function enableImageResizeInDiv(id) {
if (!(/chrome/i.test(navigator.userAgent) && /google/i.test(window.navigator.vendor))) {
return;
}
var editor = document.getElementById(id);
var resizing = false;
var currentImage;
var createDOM = function (elementType, className, styles) {
let ele = document.createElement(elementType);
ele.className = className;
setStyle(ele, styles);
return ele;
};
var setStyle = function (ele, styles) {
for (key in styles) {
ele.style[key] = styles[key];
}
return ele;
};
var removeResizeFrame = function () {
document.querySelectorAll(".resize-frame,.resizer").forEach((item) => item.parentNode.removeChild(item));
};
var offset = function offset(el) {
const rect = el.getBoundingClientRect(),
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
};
var clickImage = function (img) {
removeResizeFrame();
currentImage = img;
const imgHeight = img.offsetHeight;
const imgWidth = img.offsetWidth;
const imgPosition = { top: img.offsetTop, left: img.offsetLeft };
const editorScrollTop = editor.scrollTop;
const editorScrollLeft = editor.scrollLeft;
const top = imgPosition.top - editorScrollTop - 1;
const left = imgPosition.left - editorScrollLeft - 1;
editor.append(createDOM('span', 'resize-frame', {
margin: '10px',
position: 'absolute',
top: (top + imgHeight - 10) + 'px',
left: (left + imgWidth - 10) + 'px',
border: 'solid 3px blue',
width: '6px',
height: '6px',
cursor: 'se-resize',
zIndex: 1
}));
editor.append(createDOM('span', 'resizer top-border', {
position: 'absolute',
top: (top) + 'px',
left: (left) + 'px',
border: 'dashed 1px grey',
width: imgWidth + 'px',
height: '0px'
}));
editor.append(createDOM('span', 'resizer left-border', {
position: 'absolute',
top: (top) + 'px',
left: (left) + 'px',
border: 'dashed 1px grey',
width: '0px',
height: imgHeight + 'px'
}));
editor.append(createDOM('span', 'resizer right-border', {
position: 'absolute',
top: (top) + 'px',
left: (left + imgWidth) + 'px',
border: 'dashed 1px grey',
width: '0px',
height: imgHeight + 'px'
}));
editor.append(createDOM('span', 'resizer bottom-border', {
position: 'absolute',
top: (top + imgHeight) + 'px',
left: (left) + 'px',
border: 'dashed 1px grey',
width: imgWidth + 'px',
height: '0px'
}));
document.querySelector('.resize-frame').onmousedown = () => {
resizing = true;
return false;
};
editor.onmouseup = () => {
if (resizing) {
currentImage.style.width = document.querySelector('.top-border').offsetWidth + 'px';
currentImage.style.height = document.querySelector('.left-border').offsetHeight + 'px';
refresh();
currentImage.click();
resizing = false;
}
};
editor.onmousemove = (e) => {
if (currentImage && resizing) {
let height = e.pageY - offset(currentImage).top;
let width = e.pageX - offset(currentImage).left;
height = height < 1 ? 1 : height;
width = width < 1 ? 1 : width;
const top = imgPosition.top - editorScrollTop - 1;
const left = imgPosition.left - editorScrollLeft - 1;
setStyle(document.querySelector('.resize-frame'), {
top: (top + height - 10) + 'px',
left: (left + width - 10) + "px"
});
setStyle(document.querySelector('.top-border'), { width: width + "px" });
setStyle(document.querySelector('.left-border'), { height: height + "px" });
setStyle(document.querySelector('.right-border'), {
left: (left + width) + 'px',
height: height + "px"
});
setStyle(document.querySelector('.bottom-border'), {
top: (top + height) + 'px',
width: width + "px"
});
}
return false;
};
};
var bindClickListener = function () {
editor.querySelectorAll('img').forEach((img, i) => {
img.onclick = (e) => {
if (e.target === img) {
clickImage(img);
}
};
});
};
var refresh = function () {
bindClickListener();
removeResizeFrame();
if (!currentImage) {
return;
}
var img = currentImage;
var imgHeight = img.offsetHeight;
var imgWidth = img.offsetWidth;
var imgPosition = { top: img.offsetTop, left: img.offsetLeft };
var editorScrollTop = editor.scrollTop;
var editorScrollLeft = editor.scrollLeft;
const top = imgPosition.top - editorScrollTop - 1;
const left = imgPosition.left - editorScrollLeft - 1;
editor.append(createDOM('span', 'resize-frame', {
position: 'absolute',
top: (top + imgHeight) + 'px',
left: (left + imgWidth) + 'px',
border: 'solid 2px red',
width: '6px',
height: '6px',
cursor: 'se-resize',
zIndex: 1
}));
editor.append(createDOM('span', 'resizer', {
position: 'absolute',
top: (top) + 'px',
left: (left) + 'px',
border: 'dashed 1px grey',
width: imgWidth + 'px',
height: '0px'
}));
editor.append(createDOM('span', 'resizer', {
position: 'absolute',
top: (top) + 'px',
left: (left + imgWidth) + 'px',
border: 'dashed 1px grey',
width: '0px',
height: imgHeight + 'px'
}));
editor.append(createDOM('span', 'resizer', {
position: 'absolute',
top: (top + imgHeight) + 'px',
left: (left) + 'px',
border: 'dashed 1px grey',
width: imgWidth + 'px',
height: '0px'
}));
};
var reset = function () {
if (currentImage != null) {
currentImage = null;
resizing = false;
removeResizeFrame();
}
bindClickListener();
};
editor.addEventListener('scroll', function () {
reset();
}, false);
editor.addEventListener('mouseup', function (e) {
if (!resizing) {
const x = (e.x) ? e.x : e.clientX;
const y = (e.y) ? e.y : e.clientY;
let mouseUpElement = document.elementFromPoint(x, y);
if (mouseUpElement) {
let matchingElement = null;
if (mouseUpElement.tagName === 'IMG') {
matchingElement = mouseUpElement;
}
if (!matchingElement) {
reset();
} else {
clickImage(matchingElement);
}
}
}
});
}
enableImageResizeInDiv('edt');
#edt {
padding: 2px;
width: 100%;
height: 500px;
border: 1px solid black;
overflow: scroll;
}
<!doctype html>
<html>
<body>
How to enable image resizing inside contenteditable DIV (aka WYSIWYG editor) in Chrome?<br><hr>
<div id="edt" contenteditable="true">
<p><b>Green</b><img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAABeCAYAAADi4bzuAAABh0lEQVR4Ae3SMRXAIBAFQYKV6InYKISGgvUwV91v983z/t8aToFTYCqhwF0AiLuGfwABQQoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykABDJYQDBQAoAkRwGEAykwAbutgLcDSwO9gAAAABJRU5ErkJggg==">Red
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAABeCAYAAADi4bzuAAAEQElEQVR4Ae2cPXLcMAyFn0TJXk8mXVKlzY1S5ghpcy3fKCdIxl1+7JVIZsAV1oJ3xg3cEPuYWfNHQsZ47xNIbeHh4dPnCjYqsCkwUgkqsFeAQOzV4BgEghAYBQiEkYMTAkEGjAIEwsjBCYEgA0YBAmHk4IRAkAGjAIEwcnBCIMiAUYBAGDk4IRBkwChAIIwcnBAIMmAUIBBGDk4IBBkwChAIIwcnBIIMGAUIhJGDEwJBBowCBMLIwQmBIANGAQJh5OCEQJABowCBMHJwQiDIgFGAQBg5OCEQZMAoQCCMHJyEB6IMgHy07Ya6xH6nwLQbdzncmz2++EsXcq0qARWQodwj63lbfxnTpQhv+Et3XSHUcDFdjBWP1X+99oZaXcV/1X2FEJeGCiQBop4qgjz9AkkDpTzDIveyMrzOddcVQmFo1UErxNbrtdZvW4VWEVmTCiIfNqtA1xVC93/dKnSOAshxQg3Xo4VUEHkC9ttJ2WCxslzvrGsg1DY1X4zWbUMgEUBkra3LXAO2beZ84NytX/uwayDEaGllBJ62sZ4nkjz6WxPj1w0WOWtIk75q6djuY2cfmi71ELPVewFE5m1tA0SSEki07YbnNxK9xr5zINohsY44jDdIjwW3T8D78YC6nGwfptS2DakGUjF0C9E3DQJwqUDXW0ZLJxfUsuLdfIthGPD49x8O84xjXZBzRtpy3hWMtrKvFJeyXO9K90BM04S8rMgVrU9TAkrBKP+GERXZbA1aJa7X8tcz7x6IY14x3844lgJMM9ZaMaWEYc3nzLUayBlDgJCPNKkaeu1885UP9m9i3UnRXidvZ/xGwUNa8OH7N3z8+gV/UsFSC+r2GpFH4JiAJQEyljaV07ni5VbSnQhv/At3DYRosSwZa8443N0Bv37ix/096jBgupnPQMh98uax72VMGE6a7H8OPf81fKkQaTpgQcG6HjHK+UFaqcCSkcYRadsU9JVULut3FXqe4LZxkk1+dn2GEEPX5elkfBmQ8tDeLOoopKT21oFyOlS2c8P2zaUkLhA0SJ614Kh3IMTBVgFKbvW/lBVD+0Zye+Zt1wzXA6VMWBkun4HuzxCXKXHFowCB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVkxKB8KgXMJZABDTVk9J/bM/jwqGSC8IAAAAASUVORK5CYII=">
</p>
</div>
</body>
</html>

Categories

Resources