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

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>

Related

How to fix aspect ratio of resizable-draggable element?

I have found a nice solution for Creating a DRR element in javascript here
Currently, I would like to have this feature support to maintaining the aspect ratio.
Here is snippet:
var box = document.getElementById("box");
var boxWrapper = document.getElementById("box-wrapper");
const minWidth = 40;
const minHeight = 40;
var initX, initY, mousePressX, mousePressY, initW, initH, initRotate;
function repositionElement(x, y) {
boxWrapper.style.left = x + 'px';
boxWrapper.style.top = y + 'px';
}
function resize(w, h) {
box.style.width = w + 'px';
box.style.height = h + 'px';
}
function getCurrentRotation(el) {
var st = window.getComputedStyle(el, null);
var tm = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform")
"none";
if (tm != "none") {
var values = tm.split('(')[1].split(')')[0].split(',');
var angle = Math.round(Math.atan2(values[1], values[0]) * (180 / Math.PI));
return (angle < 0 ? angle + 360 : angle);
}
return 0;
}
function rotateBox(deg) {
boxWrapper.style.transform = `rotate(${deg}deg)`;
}
// drag support
boxWrapper.addEventListener('mousedown', function (event) {
if (event.target.className.indexOf("dot") > -1) {
return;
}
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
function eventMoveHandler(event) {
repositionElement(initX + (event.clientX - mousePressX),
initY + (event.clientY - mousePressY));
}
boxWrapper.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
boxWrapper.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
// done drag support
// handle resize
var rightMid = document.getElementById("right-mid");
var leftMid = document.getElementById("left-mid");
var topMid = document.getElementById("top-mid");
var bottomMid = document.getElementById("bottom-mid");
var leftTop = document.getElementById("left-top");
var rightTop = document.getElementById("right-top");
var rightBottom = document.getElementById("right-bottom");
var leftBottom = document.getElementById("left-bottom");
function resizeHandler(event, left = false, top = false, xResize = false, yResize = false) {
initX = boxWrapper.offsetLeft;
initY = boxWrapper.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
initW = box.offsetWidth;
initH = box.offsetHeight;
initRotate = getCurrentRotation(boxWrapper);
var initRadians = initRotate * Math.PI / 180;
var cosFraction = Math.cos(initRadians);
var sinFraction = Math.sin(initRadians);
function eventMoveHandler(event) {
var wDiff = (event.clientX - mousePressX);
var hDiff = (event.clientY - mousePressY);
var rotatedWDiff = cosFraction * wDiff + sinFraction * hDiff;
var rotatedHDiff = cosFraction * hDiff - sinFraction * wDiff;
var newW = initW, newH = initH, newX = initX, newY = initY;
if (xResize) {
if (left) {
newW = initW - rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = initW - minWidth;
}
} else {
newW = initW + rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = minWidth - initW;
}
}
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
}
if (yResize) {
if (top) {
newH = initH - rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = initH - minHeight;
}
} else {
newH = initH + rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = minHeight - initH;
}
}
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
}
resize(newW, newH);
repositionElement(newX, newY);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}
rightMid.addEventListener('mousedown', e => resizeHandler(e, false, false, true, false));
leftMid.addEventListener('mousedown', e => resizeHandler(e, true, false, true, false));
topMid.addEventListener('mousedown', e => resizeHandler(e, false, true, false, true));
bottomMid.addEventListener('mousedown', e => resizeHandler(e, false, false, false, true));
leftTop.addEventListener('mousedown', e => resizeHandler(e, true, true, true, true));
rightTop.addEventListener('mousedown', e => resizeHandler(e, false, true, true, true));
rightBottom.addEventListener('mousedown', e => resizeHandler(e, false, false, true, true));
leftBottom.addEventListener('mousedown', e => resizeHandler(e, true, false, true, true));
// handle rotation
var rotate = document.getElementById("rotate");
rotate.addEventListener('mousedown', function (event) {
// if (event.target.className.indexOf("dot") > -1) {
// return;
// }
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
var arrow = document.querySelector("#box");
var arrowRects = arrow.getBoundingClientRect();
var arrowX = arrowRects.left + arrowRects.width / 2;
var arrowY = arrowRects.top + arrowRects.height / 2;
function eventMoveHandler(event) {
var angle = Math.atan2(event.clientY - arrowY, event.clientX - arrowX) + Math.PI / 2;
rotateBox(angle * 180 / Math.PI);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
resize(200, 200);
repositionElement(200, 200);
.box {
background-color: #00BCD4;
position: relative;
user-select: none;
transform: translate(-50%, -50%);
}
.box-wrapper {
position: absolute;
transform-origin: top left;
user-select: none;
}
.dot {
height: 10px;
width: 10px;
background-color: #1E88E5;
position: absolute;
border-radius: 100px;
border: 1px solid white;
user-select: none;
}
.dot:hover {
background-color: #0D47A1;
}
.dot.left-top {
top: -5px;
left: -5px;
/* cursor: nw-resize; */
}
.dot.left-bottom {
bottom: -5px;
left: -5px;
/* cursor: sw-resize; */
}
.dot.right-top {
top: -5px;
right: -5px;
/* cursor: ne-resize; */
}
.dot.right-bottom {
bottom: -5px;
right: -5px;
/* cursor: se-resize; */
}
.dot.top-mid {
top: -5px;
left: calc(50% - 5px);
/* cursor: n-resize; */
}
.dot.left-mid {
left: -5px;
top: calc(50% - 5px);
/* cursor: w-resize; */
}
.dot.right-mid {
right: -5px;
top: calc(50% - 5px);
/* cursor: e-resize; */
}
.dot.bottom-mid {
bottom: -5px;
left: calc(50% - 5px);
/* cursor: s-resize; */
}
.dot.rotate {
top: -30px;
left: calc(50% - 5px);
cursor: url('https://findicons.com/files/icons/1620/crystal_project/16/rotate_ccw.png'), auto;
}
.rotate-link {
position: absolute;
width: 1px;
height: 15px;
background-color: #1E88E5;
top: -20px;
left: calc(50% + 0.5px);
z-index: -1;
}
<div class="box-wrapper" id="box-wrapper">
<div class="box" id="box">
<div class="dot rotate" id="rotate"></div>
<div class="dot left-top" id="left-top"></div>
<div class="dot left-bottom" id="left-bottom"></div>
<div class="dot top-mid" id="top-mid"></div>
<div class="dot bottom-mid" id="bottom-mid"></div>
<div class="dot left-mid" id="left-mid"></div>
<div class="dot right-mid" id="right-mid"></div>
<div class="dot right-bottom" id="right-bottom"></div>
<div class="dot right-top" id="right-top"></div>
<div class="rotate-link"></div>
</div>
</div>
I am fine if answers are related to maintaining square aspect-ratio only.
Tried solution:
In resize function, set height and width equally.
Reposition element once resize is done and according to position of resized element.
But, repositioning behaviour seems glitchy with above solution (missing something / not doing it right).
Goal:
Fix aspect ratio
Keep repositioning behaviour as it is.
Note:
Rotating feature can be ignored, I am looking for a repositioning element accurately.
Thanks! for your appreciable answers.
There are two challenges to this question: maintaining an aspect ratio (which is pretty straightforward) and also calculating position based off of anchor points (which can be tricky from the example).
In the original example, the position and magnitude of each dimension is calculated separately (width and x position calculated in the same code block, then height and y position):
if (xResize) {
// recalculate width
if (left) {
newW = initW - rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = initW - minWidth;
}
} else {
newW = initW + rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = minWidth - initW;
}
}
// recalculate position
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
}
if (yResize) {
// recalculate height
if (top) {
newH = initH - rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = initH - minHeight;
}
} else {
newH = initH + rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = minHeight - initH;
}
}
// recalculate position
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
}
To maintain the aspect ratio, you'd need to constrain the width and height in relation to each other, then reposition based off of those values. Since repositioning based off of height and width are now dependent on each other, this makes the code a little more clunky:
// calculate new width and height
if (xResize) {
if (left) {
newW = initW - rotatedWDiff;
} else {
newW = initW + rotatedWDiff;
}
if (newW < minWidth) {
newW = minWidth;
}
}
if (yResize) {
if (top) {
newH = initH - rotatedHDiff;
} else {
newH = initH + rotatedHDiff;
}
if (newH < minHeight) {
newH = minHeight;
}
}
// constrain aspect ratio, if a corner is being dragged
var scale;
if (xResize && yResize) {
scale = Math.max(newW / initW, newH / initH);
newW = scale * initW;
newH = scale * initH;
}
// recalculate position
if (xResize) {
if (left) {
rotatedWDiff = initW - newW;
} else {
rotatedWDiff = newW - initW;
}
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
}
if (yResize) {
if (top) {
rotatedHDiff = initH - newH;
} else {
rotatedHDiff = newH - initH;
}
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
}
Altogether it looks like this:
var box = document.getElementById("box");
var boxWrapper = document.getElementById("box-wrapper");
const minWidth = 40;
const minHeight = 40;
var initX, initY, mousePressX, mousePressY, initW, initH, initRotate;
function repositionElement(x, y) {
boxWrapper.style.left = x + 'px';
boxWrapper.style.top = y + 'px';
}
function resize(w, h) {
box.style.width = w + 'px';
box.style.height = h + 'px';
}
function getCurrentRotation(el) {
var st = window.getComputedStyle(el, null);
var tm = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform")
"none";
if (tm != "none") {
var values = tm.split('(')[1].split(')')[0].split(',');
var angle = Math.round(Math.atan2(values[1], values[0]) * (180 / Math.PI));
return (angle < 0 ? angle + 360 : angle);
}
return 0;
}
function rotateBox(deg) {
boxWrapper.style.transform = `rotate(${deg}deg)`;
}
// drag support
boxWrapper.addEventListener('mousedown', function (event) {
if (event.target.className.indexOf("dot") > -1) {
return;
}
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
function eventMoveHandler(event) {
repositionElement(initX + (event.clientX - mousePressX),
initY + (event.clientY - mousePressY));
}
boxWrapper.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
boxWrapper.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
// done drag support
// handle resize
var rightMid = document.getElementById("right-mid");
var leftMid = document.getElementById("left-mid");
var topMid = document.getElementById("top-mid");
var bottomMid = document.getElementById("bottom-mid");
var leftTop = document.getElementById("left-top");
var rightTop = document.getElementById("right-top");
var rightBottom = document.getElementById("right-bottom");
var leftBottom = document.getElementById("left-bottom");
function resizeHandler(event, left = false, top = false, xResize = false, yResize = false) {
initX = boxWrapper.offsetLeft;
initY = boxWrapper.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
initW = box.offsetWidth;
initH = box.offsetHeight;
initRotate = getCurrentRotation(boxWrapper);
var initRadians = initRotate * Math.PI / 180;
var cosFraction = Math.cos(initRadians);
var sinFraction = Math.sin(initRadians);
function eventMoveHandler(event) {
var wDiff = (event.clientX - mousePressX);
var hDiff = (event.clientY - mousePressY);
var rotatedWDiff = cosFraction * wDiff + sinFraction * hDiff;
var rotatedHDiff = cosFraction * hDiff - sinFraction * wDiff;
var newW = initW, newH = initH, newX = initX, newY = initY;
// calculate new width and height
if (xResize) {
if (left) {
newW = initW - rotatedWDiff;
} else {
newW = initW + rotatedWDiff;
}
if (newW < minWidth) {
newW = minWidth;
}
}
if (yResize) {
if (top) {
newH = initH - rotatedHDiff;
} else {
newH = initH + rotatedHDiff;
}
if (newH < minHeight) {
newH = minHeight;
}
}
var scale;
// constrain aspect ratio, if a corner is being dragged
// can remove the conditional if aspect ratio should always be preserved
if (xResize && yResize) {
scale = Math.max(newW / initW, newH / initH);
newW = scale * initW;
newH = scale * initH;
}
// recalculate position
if (xResize) {
if (left) {
rotatedWDiff = initW - newW;
} else {
rotatedWDiff = newW - initW;
}
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
}
if (yResize) {
if (top) {
rotatedHDiff = initH - newH;
} else {
rotatedHDiff = newH - initH;
}
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
}
resize(newW, newH);
repositionElement(newX, newY);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}
rightMid.addEventListener('mousedown', e => resizeHandler(e, false, false, true, false));
leftMid.addEventListener('mousedown', e => resizeHandler(e, true, false, true, false));
topMid.addEventListener('mousedown', e => resizeHandler(e, false, true, false, true));
bottomMid.addEventListener('mousedown', e => resizeHandler(e, false, false, false, true));
leftTop.addEventListener('mousedown', e => resizeHandler(e, true, true, true, true));
rightTop.addEventListener('mousedown', e => resizeHandler(e, false, true, true, true));
rightBottom.addEventListener('mousedown', e => resizeHandler(e, false, false, true, true));
leftBottom.addEventListener('mousedown', e => resizeHandler(e, true, false, true, true));
// handle rotation
var rotate = document.getElementById("rotate");
rotate.addEventListener('mousedown', function (event) {
// if (event.target.className.indexOf("dot") > -1) {
// return;
// }
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
var arrow = document.querySelector("#box");
var arrowRects = arrow.getBoundingClientRect();
var arrowX = arrowRects.left + arrowRects.width / 2;
var arrowY = arrowRects.top + arrowRects.height / 2;
function eventMoveHandler(event) {
var angle = Math.atan2(event.clientY - arrowY, event.clientX - arrowX) + Math.PI / 2;
rotateBox(angle * 180 / Math.PI);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
resize(300, 200);
repositionElement(200, 200);
.box {
background-color: #00BCD4;
position: relative;
user-select: none;
transform: translate(-50%, -50%);
}
.box-wrapper {
position: absolute;
transform-origin: top left;
user-select: none;
}
.dot {
height: 10px;
width: 10px;
background-color: #1E88E5;
position: absolute;
border-radius: 100px;
border: 1px solid white;
user-select: none;
}
.dot:hover {
background-color: #0D47A1;
}
.dot.left-top {
top: -5px;
left: -5px;
/* cursor: nw-resize; */
}
.dot.left-bottom {
bottom: -5px;
left: -5px;
/* cursor: sw-resize; */
}
.dot.right-top {
top: -5px;
right: -5px;
/* cursor: ne-resize; */
}
.dot.right-bottom {
bottom: -5px;
right: -5px;
/* cursor: se-resize; */
}
.dot.top-mid {
top: -5px;
left: calc(50% - 5px);
/* cursor: n-resize; */
}
.dot.left-mid {
left: -5px;
top: calc(50% - 5px);
/* cursor: w-resize; */
}
.dot.right-mid {
right: -5px;
top: calc(50% - 5px);
/* cursor: e-resize; */
}
.dot.bottom-mid {
bottom: -5px;
left: calc(50% - 5px);
/* cursor: s-resize; */
}
.dot.rotate {
top: -30px;
left: calc(50% - 5px);
cursor: url('https://findicons.com/files/icons/1620/crystal_project/16/rotate_ccw.png'), auto;
}
.rotate-link {
position: absolute;
width: 1px;
height: 15px;
background-color: #1E88E5;
top: -20px;
left: calc(50% + 0.5px);
z-index: -1;
}
<div class="box-wrapper" id="box-wrapper">
<div class="box" id="box">
<div class="dot rotate" id="rotate"></div>
<div class="dot left-top" id="left-top"></div>
<div class="dot left-bottom" id="left-bottom"></div>
<div class="dot top-mid" id="top-mid"></div>
<div class="dot bottom-mid" id="bottom-mid"></div>
<div class="dot left-mid" id="left-mid"></div>
<div class="dot right-mid" id="right-mid"></div>
<div class="dot right-bottom" id="right-bottom"></div>
<div class="dot right-top" id="right-top"></div>
<div class="rotate-link"></div>
</div>
</div>
You could also relay on CSS rule aspect-ratio :
If you use minWidth and minHeight instead to resize the element it might help to reset and keep ratio.
example below , with a a few reset on resize(X,X) function to test behavior :)
const box = document.getElementById("box");
var boxWrapper = document.getElementById("box-wrapper");
const minWidth = 40;
const minHeight = 40;
function resetSize() {// shrinks it to the min size set (unless content inside takes bigger room
box.style.width = '0';
box.style.height = '0';
}
function setCssRatio() {// get ratio from its size
let bH = box.offsetHeight;
let bW = box.offsetWidth;
let dif = bH / bW;
document.documentElement.style.setProperty("--ratio", "1/" + dif);
document.querySelector('#box p').innerHTML = "calculated ratio: <br> 1 / " + dif.toFixed(1);
box.style.width = 'auto';
box.style.height = 'auto';
}
var initX, initY, mousePressX, mousePressY, initW, initH, initRotate;
function repositionElement(x, y) {
boxWrapper.style.left = x + 'px';
boxWrapper.style.top = y + 'px';
}
function resize(w, h) {
box.style.minWidth = w + 'px';
box.style.minHeight = h + 'px';
setCssRatio();
}
function getCurrentRotation(el) {
var st = window.getComputedStyle(el, null);
var tm = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform")
"none";
if (tm != "none") {
var values = tm.split('(')[1].split(')')[0].split(',');
var angle = Math.round(Math.atan2(values[1], values[0]) * (180 / Math.PI));
return (angle < 0 ? angle + 360 : angle);
}
return 0;
}
function rotateBox(deg) {
boxWrapper.style.transform = `rotate(${deg}deg)`;
}
// drag support
boxWrapper.addEventListener('mousedown', function(event) {
if (event.target.className.indexOf("dot") > -1) {
return;
}
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
function eventMoveHandler(event) {
repositionElement(initX + (event.clientX - mousePressX),
initY + (event.clientY - mousePressY));
}
boxWrapper.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
boxWrapper.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
// done drag support
// handle resize
var rightMid = document.getElementById("right-mid");
var leftMid = document.getElementById("left-mid");
var topMid = document.getElementById("top-mid");
var bottomMid = document.getElementById("bottom-mid");
var leftTop = document.getElementById("left-top");
var rightTop = document.getElementById("right-top");
var rightBottom = document.getElementById("right-bottom");
var leftBottom = document.getElementById("left-bottom");
function resizeHandler(event, left = false, top = false, xResize = false, yResize = false) {
initX = boxWrapper.offsetLeft;
initY = boxWrapper.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
initW = box.offsetWidth;
initH = box.offsetHeight;
initRotate = getCurrentRotation(boxWrapper);
var initRadians = initRotate * Math.PI / 180;
var cosFraction = Math.cos(initRadians);
var sinFraction = Math.sin(initRadians);
function eventMoveHandler(event) {
var wDiff = (event.clientX - mousePressX);
var hDiff = (event.clientY - mousePressY);
var rotatedWDiff = cosFraction * wDiff + sinFraction * hDiff;
var rotatedHDiff = cosFraction * hDiff - sinFraction * wDiff;
var newW = initW,
newH = initH,
newX = initX,
newY = initY;
if (xResize) {
if (left) {
newW = initW - rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = initW - minWidth;
}
} else {
newW = initW + rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = minWidth - initW;
}
}
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
}
if (yResize) {
if (top) {
newH = initH - rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = initH - minHeight;
}
} else {
newH = initH + rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = minHeight - initH;
}
}
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
}
resize(newW, newH);
repositionElement(newX, newY);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}
rightMid.addEventListener('mousedown', e => resizeHandler(e, false, false, true, false));
leftMid.addEventListener('mousedown', e => resizeHandler(e, true, false, true, false));
topMid.addEventListener('mousedown', e => resizeHandler(e, false, true, false, true));
bottomMid.addEventListener('mousedown', e => resizeHandler(e, false, false, false, true));
leftTop.addEventListener('mousedown', e => resizeHandler(e, true, true, true, true));
rightTop.addEventListener('mousedown', e => resizeHandler(e, false, true, true, true));
rightBottom.addEventListener('mousedown', e => resizeHandler(e, false, false, true, true));
leftBottom.addEventListener('mousedown', e => resizeHandler(e, true, false, true, true));
// handle rotation
var rotate = document.getElementById("rotate");
rotate.addEventListener('mousedown', function(event) {
// if (event.target.className.indexOf("dot") > -1) {
// return;
// }
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
var arrow = document.querySelector("#box");
var arrowRects = arrow.getBoundingClientRect();
var arrowX = arrowRects.left + arrowRects.width / 2;
var arrowY = arrowRects.top + arrowRects.height / 2;
function eventMoveHandler(event) {
var angle = Math.atan2(event.clientY - arrowY, event.clientX - arrowX) + Math.PI / 2;
rotateBox(angle * 180 / Math.PI);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
resize(220, 300);
repositionElement(200, 200);
.box {
background-color: #00BCD4;
position: relative;
user-select: none;
transform: translate(-50%, -50%);
}
.box-wrapper {
position: absolute;
transform-origin: top left;
user-select: none;
}
.dot {
height: 10px;
width: 10px;
background-color: #1E88E5;
position: absolute;
border-radius: 100px;
border: 1px solid white;
user-select: none;
}
.dot:hover {
background-color: #0D47A1;
}
.dot.left-top {
top: -5px;
left: -5px;
/* cursor: nw-resize; */
}
.dot.left-bottom {
bottom: -5px;
left: -5px;
/* cursor: sw-resize; */
}
.dot.right-top {
top: -5px;
right: -5px;
/* cursor: ne-resize; */
}
.dot.right-bottom {
bottom: -5px;
right: -5px;
/* cursor: se-resize; */
}
.dot.top-mid {
top: -5px;
left: calc(50% - 5px);
/* cursor: n-resize; */
}
.dot.left-mid {
left: -5px;
top: calc(50% - 5px);
/* cursor: w-resize; */
}
.dot.right-mid {
right: -5px;
top: calc(50% - 5px);
/* cursor: e-resize; */
}
.dot.bottom-mid {
bottom: -5px;
left: calc(50% - 5px);
/* cursor: s-resize; */
}
.dot.rotate {
top: -30px;
left: calc(50% - 5px);
cursor: url('https://findicons.com/files/icons/1620/crystal_project/16/rotate_ccw.png'), auto;
}
.rotate-link {
position: absolute;
width: 1px;
height: 15px;
background-color: #1E88E5;
top: -20px;
left: calc(50% + 0.5px);
z-index: -1;
}
#box {
aspect-ratio: var(--ratio);
display: flex;
}
#box p {
margin: auto;
text-align: center;
}
<div class="box-wrapper" id="box-wrapper">
<div class="box" id="box">
<p></p>
<div class="dot rotate" id="rotate"></div>
<div class="dot left-top" id="left-top"></div>
<div class="dot left-bottom" id="left-bottom"></div>
<div class="dot top-mid" id="top-mid"></div>
<div class="dot bottom-mid" id="bottom-mid"></div>
<div class="dot left-mid" id="left-mid"></div>
<div class="dot right-mid" id="right-mid"></div>
<div class="dot right-bottom" id="right-bottom"></div>
<div class="dot right-top" id="right-top"></div>
<div class="rotate-link"></div>
</div>
</div>
<button onclick="resize(150,150);resetSize();setCssRatio();return false;">set a square</button>
<button onclick="resize(200,100);;resetSize();setCssRatio();return false;">set a 200x100</button>
<button onclick="resize(100,200);;resetSize();setCssRatio();return false;">set a 100x200</button>
in eventMoveHandler set aspect ratio and remove xResize and yResize check it will work.
var box = document.getElementById("box");
var boxWrapper = document.getElementById("box-wrapper");
const minWidth = 40;
const minHeight = 40;
var initX, initY, mousePressX, mousePressY, initW, initH, initRotate;
function repositionElement(x, y) {
boxWrapper.style.left = x + 'px';
boxWrapper.style.top = y + 'px';
}
function resize(w, h) {
box.style.width = w + 'px';
box.style.height = h + 'px';
}
function getCurrentRotation(el) {
var st = window.getComputedStyle(el, null);
var tm = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform")
"none";
if (tm != "none") {
var values = tm.split('(')[1].split(')')[0].split(',');
var angle = Math.round(Math.atan2(values[1], values[0]) * (180 / Math.PI));
return (angle < 0 ? angle + 360 : angle);
}
return 0;
}
function rotateBox(deg) {
boxWrapper.style.transform = `rotate(${deg}deg)`;
}
// drag support
boxWrapper.addEventListener('mousedown', function (event) {
if (event.target.className.indexOf("dot") > -1) {
return;
}
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
function eventMoveHandler(event) {
repositionElement(initX + (event.clientX - mousePressX),
initY + (event.clientY - mousePressY));
}
boxWrapper.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
boxWrapper.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
// done drag support
// handle resize
var rightMid = document.getElementById("right-mid");
var leftMid = document.getElementById("left-mid");
var topMid = document.getElementById("top-mid");
var bottomMid = document.getElementById("bottom-mid");
var leftTop = document.getElementById("left-top");
var rightTop = document.getElementById("right-top");
var rightBottom = document.getElementById("right-bottom");
var leftBottom = document.getElementById("left-bottom");
function resizeHandler(event, left = false, top = false, xResize = false, yResize = false) {
initX = boxWrapper.offsetLeft;
initY = boxWrapper.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
initW = box.offsetWidth;
initH = box.offsetHeight;
acptRatio = initW/initH;
initRotate = getCurrentRotation(boxWrapper);
var initRadians = initRotate * Math.PI / 180;
var cosFraction = Math.cos(initRadians);
var sinFraction = Math.sin(initRadians);
function eventMoveHandler(event) {
var wDiff = (event.clientX - mousePressX);
var hDiff = (event.clientY - mousePressY);
if(wDiff > hDiff) hDiff = wDiff/acptRatio;
else wDiff = hDiff*acptRatio;
var rotatedWDiff = cosFraction * wDiff + sinFraction * hDiff;
var rotatedHDiff = cosFraction * hDiff - sinFraction * wDiff;
var newW = initW, newH = initH, newX = initX, newY = initY;
//if (xResize || true) {
if (left) {
newW = initW - rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = initW - minWidth;
}
} else {
newW = initW + rotatedWDiff;
if (newW < minWidth) {
newW = minWidth;
rotatedWDiff = minWidth - initW;
}
}
newX += 0.5 * rotatedWDiff * cosFraction;
newY += 0.5 * rotatedWDiff * sinFraction;
// }
//if (yResize || true) {
if (top) {
newH = initH - rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = initH - minHeight;
}
} else {
newH = initH + rotatedHDiff;
if (newH < minHeight) {
newH = minHeight;
rotatedHDiff = minHeight - initH;
}
}
newX -= 0.5 * rotatedHDiff * sinFraction;
newY += 0.5 * rotatedHDiff * cosFraction;
// }
resize(newW, newH);
repositionElement(newX, newY);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}
rightMid.addEventListener('mousedown', e => resizeHandler(e, false, false, true, false));
leftMid.addEventListener('mousedown', e => resizeHandler(e, true, false, true, false));
topMid.addEventListener('mousedown', e => resizeHandler(e, false, true, false, true));
bottomMid.addEventListener('mousedown', e => resizeHandler(e, false, false, false, true));
leftTop.addEventListener('mousedown', e => resizeHandler(e, true, true, true, true));
rightTop.addEventListener('mousedown', e => resizeHandler(e, false, true, true, true));
rightBottom.addEventListener('mousedown', e => resizeHandler(e, false, false, true, true));
leftBottom.addEventListener('mousedown', e => resizeHandler(e, true, false, true, true));
// handle rotation
var rotate = document.getElementById("rotate");
rotate.addEventListener('mousedown', function (event) {
// if (event.target.className.indexOf("dot") > -1) {
// return;
// }
initX = this.offsetLeft;
initY = this.offsetTop;
mousePressX = event.clientX;
mousePressY = event.clientY;
var arrow = document.querySelector("#box");
var arrowRects = arrow.getBoundingClientRect();
var arrowX = arrowRects.left + arrowRects.width / 2;
var arrowY = arrowRects.top + arrowRects.height / 2;
function eventMoveHandler(event) {
var angle = Math.atan2(event.clientY - arrowY, event.clientX - arrowX) + Math.PI / 2;
rotateBox(angle * 180 / Math.PI);
}
window.addEventListener('mousemove', eventMoveHandler, false);
window.addEventListener('mouseup', function eventEndHandler() {
window.removeEventListener('mousemove', eventMoveHandler, false);
window.removeEventListener('mouseup', eventEndHandler);
}, false);
}, false);
resize(200, 200);
repositionElement(200, 200);
.box {
background-color: #00BCD4;
position: relative;
user-select: none;
transform: translate(-50%, -50%);
}
.box-wrapper {
position: absolute;
transform-origin: top left;
user-select: none;
}
.dot {
height: 10px;
width: 10px;
background-color: #1E88E5;
position: absolute;
border-radius: 100px;
border: 1px solid white;
user-select: none;
}
.dot:hover {
background-color: #0D47A1;
}
.dot.left-top {
top: -5px;
left: -5px;
/* cursor: nw-resize; */
}
.dot.left-bottom {
bottom: -5px;
left: -5px;
/* cursor: sw-resize; */
}
.dot.right-top {
top: -5px;
right: -5px;
/* cursor: ne-resize; */
}
.dot.right-bottom {
bottom: -5px;
right: -5px;
/* cursor: se-resize; */
}
.dot.top-mid {
top: -5px;
left: calc(50% - 5px);
/* cursor: n-resize; */
}
.dot.left-mid {
left: -5px;
top: calc(50% - 5px);
/* cursor: w-resize; */
}
.dot.right-mid {
right: -5px;
top: calc(50% - 5px);
/* cursor: e-resize; */
}
.dot.bottom-mid {
bottom: -5px;
left: calc(50% - 5px);
/* cursor: s-resize; */
}
.dot.rotate {
top: -30px;
left: calc(50% - 5px);
cursor: url('https://findicons.com/files/icons/1620/crystal_project/16/rotate_ccw.png'), auto;
}
.rotate-link {
position: absolute;
width: 1px;
height: 15px;
background-color: #1E88E5;
top: -20px;
left: calc(50% + 0.5px);
z-index: -1;
}
<div class="box-wrapper" id="box-wrapper">
<div class="box" id="box">
<div class="dot rotate" id="rotate"></div>
<div class="dot left-top" id="left-top"></div>
<div class="dot left-bottom" id="left-bottom"></div>
<div class="dot top-mid" id="top-mid"></div>
<div class="dot bottom-mid" id="bottom-mid"></div>
<div class="dot left-mid" id="left-mid"></div>
<div class="dot right-mid" id="right-mid"></div>
<div class="dot right-bottom" id="right-bottom"></div>
<div class="dot right-top" id="right-top"></div>
<div class="rotate-link"></div>
</div>
</div>

div Resizing with inner content and maintain aspect ratio

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>

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

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