I've tried to create more circles with button, but it doesnt work. Theyre shown in the Mozilla Inspector after click:
inspector
but theyre not visible for me. I've seen similiar problems here, but there wasn't single one that works. Can you help me please? Atm I have no idea what to do.
circle.js
class Circle {
constructor(id, posx, posy, r, fill) {
this.id = id;
this.posx = posx;
this.posy = posy;
this.r = r;
this.fill = fill;
}}
creator.js
function createCircle() {
let color = ["blue", "black", "red", "green", "purple", "orange", "yellow"]
const circle = new Circle("node", 100, 100, 50, color[0]);
var node = document.createElement("CIRCLE");
node.setAttribute("id", "node");
node.setAttribute("cx", circle.posx);
node.setAttribute("cy", circle.posy);
node.setAttribute("r", circle.r);
node.setAttribute("fill", circle.fill);
document.getElementById("frame").appendChild(node);
console.log(circle.fill);}
body and from index.html
<body onload="myFunction()">
<svg id="sss" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="frame" width="1020px" height="820px" viewBox="0 0 1020 820">
<circle id="circle0" cx="100" cy="100" r="50" fill="black" />
</svg>
</svg>
<button onclick="createCircle()">Create circle</button></body>
SVG elements are from a different namespace than typical HTML elements. An HTML document can mix tags from different XML dialects, for example XHTML, which are the standard HTML elements, but also different dialects as well, like the SVG namespace. In order to create the right element from the correct namespace you need to use a different JavaScript method that lets you specify the namespace:
document.createElementNS(namespace, element);
The first argument is the namespace so you should use: "http://www.w3.org/2000/svg", and the second is the element, in this case "circle". So try:
var node = document.createElementNS("http://www.w3.org/2000/svg", "circle");
If you're more interested, check out MDN docs:
https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course
https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS
#gdanielyan's answer is a good answer. Here is a demo:
class Circle {
constructor(id, posx, posy, r, fill) {
this.id = id;
this.posx = posx;
this.posy = posy;
this.r = r;
this.fill = fill;
}}
function createCircle() {
let color = ["blue", "red", "green", "purple", "orange", "yellow"]
const circle = new Circle("node", 100, 100, 50, color[0]);
var node = document.createElementNS("http://www.w3.org/2000/svg","circle");
node.setAttributeNS(null,"id", "node");
node.setAttributeNS(null,"cx", circle.posx + Math.random()*100);
node.setAttributeNS(null,"cy", circle.posy + Math.random()*100);
node.setAttributeNS(null,"r", circle.r);
let _color=color[~~(Math.random()*(color.length))];
//console.log(_color)
node.setAttributeNS(null,"fill", _color);
document.getElementById("frame").appendChild(node);
}
<svg id="sss" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="frame" width="1020px" height="820px" viewBox="0 0 1020 820">
<circle id="circle0" cx="100" cy="100" r="50" fill="black" />
</svg>
</svg>
<button onclick="createCircle()">Create circle</button>
Related
I'm trying to work on a way to detect if a path of an svg file that is within a canvas is clicked on. My code works in Firefox however it does not work on Chromium browsers. I have surrounded the code with try and catch and I receive no errors on Firefox and everything works however on Chromium browsers I receive the error:
TypeError: Failed to execute 'isPointInFill' on 'SVGGeometryElement': parameter 1 is not of type 'SVGPoint'.
at getIdOfElementAtPoint (main.js:39:27)
at HTMLCanvasElement.<anonymous> (main.js:70:9)
However on the next piece of code no error is thrown.
This is my code:
function getIdOfElementAtPoint(event) {
var paths = svg.getElementsByTagName("path");
//loop through all the path element in svg
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
// Check if point (x, y) is inside the fill of the path
let inFill = false;
try {
inFill = path.isPointInFill(new DOMPoint(event.clientX, event.clientY))
} catch(error) {
console.log(error)
try {
const point = svg.createSVGPoint();
// Get the coordinates of the click
point.x = event.clientX;
point.y = event.clientY;
inFill = path.isPointInFill(point)
} catch(error) {
console.log(error)
}
}
if (inFill) {
console.log("The point is inside the element with id: " + path.getAttribute("id"));
return path.getAttribute("id");
}
}
console.log("The point is outside of any element.");
}
As commented by #Kaiido:
document.elementsFromPoint() or
document.elementFromPoint()
are probably the better options to get SVG elements at certain cursor positions.
However you address several issues:
browser support for DOMPoint() used for SVG methods (firefox vs. chromium vs. webkit)
translation between HTML DOM coordinates (e.g. via mouse inputs) to SVG user units
retrieving all underlying elements at certain coordinates
Example snippet
/**
* static example: is #circleInside within #circle2
*/
let isInfill = false;
let p1 = { x: circleInside.cx.baseVal.value, y: circleInside.cy.baseVal.value };
let inFill1 = isPointInFill1(circle2, p1);
if (inFill1) {
circleInside.setAttribute("fill", "green");
}
function isPointInFill1(el, p) {
let log = [];
let point;
try {
point = new DOMPoint(p.x, p.y);
el.isPointInFill(point);
log.push("DOMPoint");
} catch {
let svg = el.nearestViewportElement;
point = svg.createSVGPoint();
[point.x, point.y] = [p.x, p.y];
log.push("SVGPoint");
}
console.log(log.join(" "));
let inFill = el.isPointInFill(point);
return inFill;
}
document.addEventListener("mousemove", (e) => {
let cursorPos = { x: e.clientX, y: e.clientY };
// move svg cursor
let svgCursor = screenToSVG(svg, cursorPos);
cursor.setAttribute("cx", svgCursor.x);
cursor.setAttribute("cy", svgCursor.y);
/**
* pretty nuts:
* we're just testing the reversal of svg units to HTML DOM units
* just use the initial: e.clientX, e.clientY
*/
// move html cursor
let domCursorPos = SVGToScreen(svg, svgCursor);
cursorDOM.style.left = domCursorPos.x + "px";
cursorDOM.style.top = domCursorPos.y + "px";
// highlight
let elsInPoint = document.elementsFromPoint(cursorPos.x, cursorPos.y);
let log = ['elementsFromPoint: '];
elsInPoint.forEach((el) => {
if (el instanceof SVGGeometryElement && el!==cursor) {
log.push(el.id);
}
});
result.textContent = log.join(" | ");
});
/**
* helper function to translate between
* svg and HTML DOM coordinates:
* based on #Paul LeBeau's anser to
* "How to convert svg element coordinates to screen coordinates?"
* https://stackoverflow.com/questions/48343436/how-to-convert-svg-element-coordinates-to-screen-coordinates/48354404#48354404
*/
function screenToSVG(svg, p) {
let pSvg = svg.createSVGPoint();
pSvg.x = p.x;
pSvg.y = p.y;
return pSvg.matrixTransform(svg.getScreenCTM().inverse());
}
function SVGToScreen(svg, pSvg) {
let p = svg.createSVGPoint();
p.x = pSvg.x;
p.y = pSvg.y;
return p.matrixTransform(svg.getScreenCTM());
}
body{
margin: 0em
}
svg{
width:25%;
border:1px solid #ccc
}
.highlight{
opacity:0.5
}
.cursorDOM{
display:block;
position:absolute;
top:0;
left:0;
margin-left:-0.5em;
margin-top:-0.5em;
font-size:2em;
width:1em;
height:1em;
outline: 1px solid green;
border-radius:50%;
pointer-events:none;
}
<p id="result"></p>
<p id="resultNext"></p>
<div id="cursorDOM" class="cursorDOM"></div>
<svg id="svg" viewBox="0 0 100 100">
<rect id="rectBg" x="0" y="0" width="100%" height="100%" fill="#eee" />
<circle id="circle0" cx="75" cy="50" r="66" fill="#ccc" />
<circle id="circle1" cx="75" cy="50" r="50" fill="#999" />
<circle id="circle2" cx="75" cy="50" r="33" />
<circle id="circleInside" cx="95" cy="50" r="5" fill="red" />
<circle id="cursor" cx="0" cy="0" r="2" fill="red" />
</svg>
1. DOMPoint() or createSVGPoint() for pointInFill()?
You're right: DOMPoint() is currently (as of 2023) not supported by chromium (blink) for some svg related methods.
createSVGPoint() works well in chromium as well as in firefox – although it's classified as deprecated.
Quite likely chromium will catch up to firefox.
But isPointInFill() or isPointInStroke() are used for checking point intersection for single elements.
2. Translate coordinates
Depending on your layout, you probably need to convert coordinates.
See #Paul LeBeau's answer: "How to convert svg element coordinates to screen coordinates?"
3. Get all underlying elements
document.elementsFromPoint() is probably the best way to go.
However, this method will also return HTML DOM elements.
So you might need some filtering for svg geometry elements like so:
let elsInPoint = document.elementsFromPoint(cursorPos.x, cursorPos.y);
elsInPoint.forEach((el) => {
if (el instanceof SVGGeometryElement) {
console.log(el)
}
});
HTML code:
<div class="dots" id="dotsSlider">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="30" viewBox="0 0 400 60" id="ante">
<rect width="100%" height="100%" fill="none" />
</svg>
</div>
Javascript code:
for (let i = 0; i < 10; i++) {
// targeting the svg itself
const svgns = "http://www.w3.org/2000/svg";
// variable for the namespace
var svg = document.querySelector("svg");
var x = i.toString();
var name = "newCircle" + x;
var name2 = name;
var counter = i + 1;
var position = 36 * counter;
// make a simple rectangle
var name = document.createElementNS(svgns, "circle");
// set attributes of new circle
gsap.set(name, {attr: {
cx: position,
cy: 25,
r: 8,
width: 30,
height: 30,
fill: "black",
id: name2
}});
// append the new rectangle to the svg
svg.appendChild(name);
}
So far so good I created 10 SVGs (dots for a slider). For loop is written inside a function that runs when the page loads. My problem is that I do not know how to access the fill property of these SVGs in order to be able to change it in a dynamic way inside another function. I tried everything related to getElement parsing it to a variable, but propably I am writing something wrong. Any help is much appreciated.
Try this:
var circle = document.getElementById("newCircle3"); // etc
circle.style.fill = "red";
The code below animates a SVG circle changing color and works as expected.
If the call to SVG.addAnimatedCircle(this.root) is made from within the callback method (instead of where it is below, inside the constructor), the animation starts when the document is loaded — and is therefore invisible unless the window is clicked — rather than when the event is triggered.
class SVG {
constructor() {
const root = document.createElementNS(
'http://www.w3.org/2000/svg', 'svg');
root.setAttribute('viewBox', '-50 -50 100 100');
this.root = root;
this.callback = this.callback.bind(this);
window.addEventListener('click', this.callback);
SVG.addAnimatedCircle(this.root);
}
callback() {
// SVG.addAnimatedCircle(this.root);
}
static addAnimatedCircle(toElement) {
const el = document.createElementNS(
'http://www.w3.org/2000/svg', 'circle');
el.setAttribute('cx', '0');
el.setAttribute('cy', '0');
el.setAttribute('r', '10');
el.setAttribute('fill', 'red');
toElement.appendChild(el);
const anim = document.createElementNS(
'http://www.w3.org/2000/svg', 'animate');
anim.setAttribute('attributeName', 'fill');
anim.setAttribute('from', 'blue');
anim.setAttribute('to', 'red');
anim.setAttribute('dur', '3s');
el.appendChild(anim);
}
}
const svg = new SVG();
document.body.appendChild(svg.root);
(The above doesn't need to be inside a class of course, I'm simplifying a more complex class).
Why is that? Isn't the animation supposed to start when the element is created and added to the DOM?
The <animate> element you create will have its begin attribute computed to 0s (since unset).
This 0s value is relative to the "document begin time", which itself in this HTML document corresponds to the root <svg>'s current time.
This means that if you do create such an <animate> element after its root <svg> element has been in the DOM, its animation state will depend on how long the root <svg> element has been in the DOM:
const root = document.querySelector("svg");
const circles = document.querySelectorAll("circle");
const duration = 3;
// will fully animate
circles[0].append(makeAnimate());
// will produce only half of the animation
setTimeout(() => {
circles[1].append(makeAnimate());
}, duration * 500);
// will not animate
setTimeout(() => {
circles[2].append(makeAnimate());
}, duration * 1000);
function makeAnimate() {
const anim = document.createElementNS("http://www.w3.org/2000/svg", "animate");
anim.setAttribute("attributeName", "fill");
anim.setAttribute("from", "blue");
anim.setAttribute("to", "red");
anim.setAttribute("fill", "freeze");
anim.setAttribute("dur", duration + "s");
return anim;
}
circle { fill: blue }
<svg height="60">
<circle cx="30" cy="30" r="25"/>
<circle cx="90" cy="30" r="25"/>
<circle cx="150" cy="30" r="25"/>
</svg>
<p>left circle starts immediately, and fully animates</p>
<p>middle circle starts after <code>duration / 2</code> and matches the same position as left circle</p>
<p>right circle starts after <code>duration</code>, the animation is already completed by then, nothing "animates"</p>
We can set the <svg>'s current time trough its SVGSVGElement.setCurrentTime() method.
So to create an <animate> that would start at the time it got created, no matter when it is, we could use this, however, this will also affect all the other <animate> that are already in the <svg>:
const root = document.querySelector("svg");
const circles = document.querySelectorAll("circle");
const duration = 3;
circles[0].append(makeAnimate());
root.setCurrentTime(0); // reset <animate> time
setTimeout(() => {
circles[1].append(makeAnimate());
root.setCurrentTime(0); // reset <animate> time
}, duration * 500);
setTimeout(() => {
circles[2].append(makeAnimate());
root.setCurrentTime(0); // reset <animate> time
}, duration * 1000);
function makeAnimate() {
const anim = document.createElementNS("http://www.w3.org/2000/svg", "animate");
anim.setAttribute("attributeName", "fill");
anim.setAttribute("from", "blue");
anim.setAttribute("to", "red");
anim.setAttribute("fill", "freeze");
anim.setAttribute("dur", duration + "s");
return anim;
}
circle { fill: blue }
<svg height="60">
<circle cx="30" cy="30" r="25"/>
<circle cx="90" cy="30" r="25"/>
<circle cx="150" cy="30" r="25"/>
</svg>
So, while it may do for some users, in most cases it's probably better to instead set only the <animate>'s begin attribute.
Luckily, we can also get the current time, with the SVGSVGElement.getCurrentTime() method.
const root = document.querySelector("svg");
const circles = document.querySelectorAll("circle");
const duration = 3;
circles[0].append(makeAnimate());
setTimeout(() => {
circles[1].append(makeAnimate());
}, duration * 500);
setTimeout(() => {
circles[2].append(makeAnimate());
}, duration * 1000);
function makeAnimate() {
const anim = document.createElementNS("http://www.w3.org/2000/svg", "animate");
anim.setAttribute("attributeName", "fill");
anim.setAttribute("from", "blue");
anim.setAttribute("to", "red");
anim.setAttribute("fill", "freeze");
anim.setAttribute("dur", duration + "s");
// set the `begin` to "now"
anim.setAttribute("begin", root.getCurrentTime() + "s");
return anim;
}
circle { fill: blue }
<svg height="60">
<circle cx="30" cy="30" r="25"/>
<circle cx="90" cy="30" r="25"/>
<circle cx="150" cy="30" r="25"/>
</svg>
But the way we usually do this is to use the API fully and control it all through JS, since you already did start using JS.
To do so, we set the begin attribute to "indefinite", so that it doesn't start automatically, and then we call the SVGAnimateElement (<animate>)'s beginElement() method, which will start the animation manually, when we want:
const root = document.querySelector("svg");
const circles = document.querySelectorAll("circle");
const duration = 3;
{
const animate = makeAnimate();
circles[0].appendChild(animate);
animate.beginElement();
}
setTimeout(() => {
const animate = makeAnimate();
circles[1].appendChild(animate);
animate.beginElement();
}, duration * 500);
setTimeout(() => {
const animate = makeAnimate();
circles[2].appendChild(animate);
animate.beginElement();
}, duration * 1000);
function makeAnimate() {
const anim = document.createElementNS("http://www.w3.org/2000/svg", "animate");
anim.setAttribute("attributeName", "fill");
anim.setAttribute("from", "blue");
anim.setAttribute("to", "red");
anim.setAttribute("fill", "freeze");
anim.setAttribute("dur", duration + "s");
// set the `begin` to "manual"
anim.setAttribute("begin", "indefinite");
return anim;
}
circle { fill: blue }
<svg height="60">
<circle cx="30" cy="30" r="25"/>
<circle cx="90" cy="30" r="25"/>
<circle cx="150" cy="30" r="25"/>
</svg>
(Not the answer, just presentation of the problem for possible accomodation into the question and/or proper answer suggested by OP in their comment.
<style>svg {outline: #0FF6 solid; outline-offset: -2px;}</style>
<table role="presentation" border><tr><td>
1. Static SVG with animated circle:
<td>
<svg viewBox="-50 -50 100 100" width="30" height="30">
<circle r="40" fill="black">
<animate begin="0.5s" fill="freeze" attributeName="fill" from="blue" to="red" dur="5s"></animate>
</circle>
</svg>
<tr><td>
2. Empty SVG,
<button onclick='
emptySVG.innerHTML = document.querySelector("circle").outerHTML;
'>Put similar animated circle into it</button>:
<td>
<svg id="emptySVG" viewBox="-50 -50 100 100" width="30" height="30">
<!-- empty -->
</svg>
<tr><td>
3. <button onclick='
sampleCell.innerHTML = document.querySelector("svg").outerHTML
'>Create new SVG with animated circle</button>:
<td id="sampleCell">
(here.)
</table>
<p>
<button onclick="location.reload()">Reload page</button>
<button onclick="
[...document.querySelectorAll('animate')].forEach(a=>{
//a.setAttribute('begin','indefinite'); // does not seem to be necessary
a.beginElement();
})
">Reset all animations</button>
Putting animated circle to second SVG produces state that corresponds with already elapsed duration in existing empty SVG: it matches the first one, so it either runs in sync or is finished. Goal is to run the animation upon circle's appearance.
(UPDATED) I'm having some issues regarding svg and javascript. What I want to create is a series of circles on top of one another, with their radius (r) values increasing by one each time the loop goes round, so that it creates some sort of a pattern. Here is what I have so far(for loop values are from another forum post, I would rather do it with a while loop that would execute 10 times) -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Dynamic SVG!</title>
</head>
<defs>
<svg height="10000" width="10000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="cir1" cx="300" cy="300" r="40" stroke="yellow" stroke-width="" fill="none"/>
</svg>
</defs>
<script>
var svgns = "http://www.w3.org/2000/svg";
for (var x = 0; x < 5000; x += 50) {
for (var y = 0; y < 3000; y += 50) {
var circle = document.createElementNS(svgns, 'circle');
circle.setAttributeNS(null, 'x', x);
circle.setAttributeNS(null, 'y', y);
circle.setAttributeNS(null, 'height', '50');
circle.setAttributeNS(null, 'width', '50');
document.getElementById('cir1').appendChild(circle);
}
}
</script>
<body>
</body>
</html>
Any help out there?
Thanks.
Ok, so this is, what I had to fix in order to get your code working:
You append to the circle element, but should append to the svg-container. A circle element has no child elements.
You did not set any styles for the circles, so they were transparent.
The coordinates in a circle element are called cx and cy instead of x and y.
The <defs> element should be a child of the <svg> element. Also everything within it wont be rendered.
JavaScript
var svgns = "http://www.w3.org/2000/svg",
container = document.getElementById( 'cont' );
for (var x = 0; x < 500; x += 50) {
for (var y = 0; y < 300; y += 50) {
var circle = document.createElementNS(svgns, 'circle');
circle.setAttributeNS(null, 'cx', x);
circle.setAttributeNS(null, 'cy', y);
circle.setAttributeNS(null, 'r', 50);
circle.setAttributeNS(null, 'style', 'fill: none; stroke: blue; stroke-width: 1px;' );
container.appendChild(circle);
}
}
HTML
<svg id="cont" height="1000" width="1000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="cir1" cx="300" cy="300" r="40" stroke="yellow" stroke-width="" fill="none" />
</svg>
Example Fiddle
I also adjusted your sizes as for a mere test, they were quite big.
What is the proper way to get the dimensions of an svg element?
http://jsfiddle.net/langdonx/Xkv3X/
Chrome 28:
style x
client 300x100
offset 300x100
IE 10:
stylex
client300x100
offsetundefinedxundefined
FireFox 23:
"style" "x"
"client" "0x0"
"offset" "undefinedxundefined"
There are width and height properties on svg1, but .width.baseVal.value is only set if I set the width and height attributes on the element.
The fiddle looks like this:
HTML
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red" />
<circle cx="150" cy="50" r="40" stroke="black" stroke-width="1" fill="green" />
<circle cx="250" cy="50" r="40" stroke="black" stroke-width="1" fill="blue" />
</svg>
JS
var svg1 = document.getElementById('svg1');
console.log(svg1);
console.log('style', svg1.style.width + 'x' + svg1.style.height);
console.log('client', svg1.clientWidth + 'x' + svg1.clientHeight);
console.log('offset', svg1.offsetWidth + 'x' + svg1.offsetHeight);
CSS
#svg1 {
width: 300px;
height: 100px;
}
Use the getBBox function:
The SVGGraphicsElement.getBBox() method allows us to determine the coordinates of the smallest rectangle in which the object fits. [...]
http://jsfiddle.net/Xkv3X/1/
var bBox = svg1.getBBox();
console.log('XxY', bBox.x + 'x' + bBox.y);
console.log('size', bBox.width + 'x' + bBox.height);
FireFox have problemes for getBBox(), i need to do this in vanillaJS.
I've a better Way and is the same result as real svg.getBBox() function !
With this good post : Get the real size of a SVG/G element
var el = document.getElementById("yourElement"); // or other selector like querySelector()
var rect = el.getBoundingClientRect(); // get the bounding rectangle
console.log( rect.width );
console.log( rect.height);
I'm using Firefox, and my working solution is very close to obysky. The only difference is that the method you call in an svg element will return multiple rects and you need to select the first one.
var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;
SVG has properties width and height. They return an object SVGAnimatedLength with two properties: animVal and baseVal. This interface is used for animation, where baseVal is the value before animation. From what I can see, this method returns consistent values in both Chrome and Firefox, so I think it can also be used to get calculated size of SVG.
This is the consistent cross-browser way I found:
var heightComponents = ['height', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'],
widthComponents = ['width', 'paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'];
var svgCalculateSize = function (el) {
var gCS = window.getComputedStyle(el), // using gCS because IE8- has no support for svg anyway
bounds = {
width: 0,
height: 0
};
heightComponents.forEach(function (css) {
bounds.height += parseFloat(gCS[css]);
});
widthComponents.forEach(function (css) {
bounds.width += parseFloat(gCS[css]);
});
return bounds;
};
From Firefox 33 onwards you can call getBoundingClientRect() and it will work normally, i.e. in the question above it will return 300 x 100.
Firefox 33 will be released on 14th October 2014 but the fix is already in Firefox nightlies if you want to try it out.
Use .getAttribute()!
var height = document.getElementById('rect').getAttribute("height");
var width = document.getElementById('rect').getAttribute("width");
var x = document.getElementById('rect').getAttribute("x");
alert("height: " + height + ", width: " + width + ", x: " + x);
<svg width="500" height="500">
<rect width="300" height="100" x="50" y="50" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" id="rect"/>
</svg>
A save method to determine the width and height unit of any element (no padding, no margin) is the following:
let div = document.querySelector("div");
let style = getComputedStyle(div);
let width = parseFloat(style.width.replace("px", ""));
let height = parseFloat(style.height.replace("px", ""));