Reputation: 363
I'm exploring SVG manipulation with plain JS. Here below the code I created (svg image is just something random for testing purposes):
const svgCode = `<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<g id="mainGroup">
<rect x="59.638" y="67.625" width="305.644" height="27.689"
style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0); transform-box: fill-box; transform-origin: 29.4425% 42.3077%;"
transform="matrix(0.875498, 0.483221, -0.483221, 0.875498, -59.105443, -22.364276)" />
<rect x="59.638" y="67.625" width="305.644" height="27.689"
style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0); transform-origin: 149.627px 79.34px;"
transform="matrix(0.793105, -0.609085, 0.609085, 0.793105, -43.863688, 64.15233)" />
</g>
</svg>`;
let baseViewBox = new DOMRect();
let curViewBox = new DOMRect();
function update() {
let parser = new DOMParser().parseFromString(svgCode, 'image/svg+xml');
let svgNode = document.importNode(parser.documentElement, true);
let svgMapNode = svgNode.cloneNode(true);
svgNode.classList.add('mainSvg');
//svgNode must be appended BEFORE calculating width and height or they will be 0
container.appendChild(svgNode);
baseViewBox = svgNode.getBBox();
curViewBox = baseViewBox;
setViewBox(svgNode, curViewBox);
let mapViewPort = document.createElementNS('xmlns="http://www.w3.org/2000/svg"', 'rect');
mapViewPort.setAttribute('x', '10');
mapViewPort.setAttribute('y', '10');
mapViewPort.setAttribute('width', '100');
mapViewPort.setAttribute('height', '100');
svgMapNode.appendChild(mapViewPort);
map.appendChild(svgMapNode);
setViewBox(svgMapNode, baseViewBox);
}
function setViewBox(svgArg, rectArg) {
svgArg.setAttribute('viewBox', `${rectArg.x} ${rectArg.y} ${rectArg.width} ${rectArg.height}`);
}
window.addEventListener('load', update);
const container = document.querySelector('#container');
const map = document.querySelector('#map');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
background-color: rgb(250, 235, 215);
border: solid 1px black;
}
#container {
width: 90lvw;
height: 90lvh;
}
#map {
background-color: rgba(250, 235, 215, 0.9);
position: absolute;
top: 5lvh;
right: 5lvh;
width:12lvw;
height:auto;
padding: 3px 3px 0px 3px;
}
<!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="./css/svg-006.css" />
</head>
<body>
<div id="container">
</div>
<div id="map">
</div>
</body>
<script src="./js/svg-006.js">
</script>
</html>
In this page I'm showing the same SVG image in the div#container and in the div#map as a sort of thumbnail. Once i parsed the SVG code to create a document element, I made a deep clone of it in order to append it in the div#map. Then I want to add a rectangle in the div#map to overlap the image (I didn't define any style yet, just black rectangle to test).
The problem is that when I'm inspecting the page I can see the code for the <rect>
element was added but it is not rendered nor seems to be inspectable by the browser.
Instead, in developer console, if I delete manually the <rect>
element and re-add it by editing the code of parent <svg>
then the rectangle is correctly rendered apparently with the same identical code generated by the script.
An other way I found to show the rectangle is to add it with JS at the end of the .innerHTML
property of containing <svg>
element.
I could use this method to add the rectangle, but I'd like to understand why the code I wrote is not working.
Thanks
Upvotes: 0
Views: 47