I am trying to write code that resizes an SVG overlay on top of an image. The server I am working with returns both the image and via an API, a list of polygon points I need to overlay on top of the image.
This is what it should look like (the image below is a correctly aligned SVG layer). The image size is 1280x720 (I've scaled it down)
What I need to do in my app (ionic v1 app) is to make sure the SVG overlay resizes as the browser window resizes and it seems to be very hard. Here is my approach:
I am trapping a window resize event and when the image is resized, I scale the SVG polygon points relative to the size of the drawn window as it seems there is really no way to "automatically" scale the SVG by the browser like it does with an image.
Here is my code pen as you see it doesn't work as intended when I rescale (and for that matter in when its full size the overlays are not accurate). The overlays don't look accurate and when I resize it all messed up. Can someone help?
Given SO needs a code block for codepen links here it is, but its just easier to look at the codepen if you want to run it
CSS:
.imagecontainer{position:relative; margin:0 auto;}
.zonelayer
{
position:absolute;
top:0;
left:0;
background:none;
}
.zonelayer polygon {
fill-opacity: 0.25;
stroke-width: 2px;
}
.Active {
stroke: #ff0000;
fill: #ff0000;
}
HTML code:
<ion-content>
image:{{disp}}<br/>
<small>points: <span ng-repeat="item in zoneArray">{{item}}</span></small>
<div class="imagecontainer">
<img id="singlemonitor" style="width:100vw; height:100vh;object-fit:contain" ng-src="http://m9.i.pbase.com/o9/63/103963/1/164771719.2SfdldRy.nphzms.jpeg" />
<div class="zonelayer">
<svg ng-attr-width="{{cw}}" ng-attr-height="{{ch}}" class="zonelayer" ng-attr-viewBox="0 0 {{cw}} {{ch}}">
<polygon ng-repeat="item in zoneArray" ng-attr-points="{{item}}" class="Active"/> </polygon>
</svg>
</div>
</div>
</ion-content>
JS controller:
window.addEventListener('resize', liveloaded);
liveloaded();
// credit: http://stackoverflow.com/questions/41411891/most-elegant-way-to-parse-scale-and-re-string-a-string-of-number-co-ordinates?noredirect=1#41411927
function scaleCoords(string, sx, sy) {
var f = [sx, sy];
return string.split(' ').map(function (a) {
return a.split(',').map(function (b, i) {
return Math.round(b * f[i]);
}).join(',');
}).join(' ');
}
function liveloaded()
{
$timeout (function () {
console.log ("IMAGE LOADED");
var img =document.getElementById("singlemonitor");
//var offset = img.getBoundingClientRect();
$scope.cw = img.clientWidth;
$scope.ch = img.clientHeight;
$scope.vx = img.offsetWidth;
$scope.vy = img.offsetHeight;
var rect = img.getBoundingClientRect();
//console.log(rect.top, rect.right, rect.bottom, rect.left);
$scope.disp = img.clientWidth+ "x"+img.clientHeight + " with offsets:"+$scope.vx+"/"+$scope.vy;
$scope.zoneArray = [
"598,70 700,101 658,531 516,436",
"531,243 687,316 663,593 360,717 191,520",
"929,180 1108,248 985,707 847,676",
"275,17 422,45 412,312 271,235",
];
var ow = 1280;
var oh = 720;
for (var i=0; i < $scope.zoneArray.length; i++)
{
var sx = $scope.cw/ow;
var sy = $scope.ch/oh;
$scope.zoneArray[i] = scaleCoords($scope.zoneArray[i],sx,sy);
console.log ("SCALED:"+$scope.zoneArray[i]);
}
});
}
There are a couple of issues with your code.
The main problem is you can't use ng-attr-viewBox, because angular will "normalise" the attribute to lower case. It turns the attribute into viewbox (lower case B) which is (currently) invalid. viewBox is case sensitive.
The solution is to use a special trick of Angular to preserve camel-case. If you use ng-attr-view_box, it will generate the correctly camel-cased attribute name of viewBox.
<svg width="100vw" height="100vh" class="zonelayer" ng-attr-view_box="0 0 {{cw}} {{ch}}">
The other thing is that you are using the wrong width and height values for the viewBox. You need to use the natural/intrinsic image dimensions in your viewBox.
$scope.cw = img.naturalWidth;
$scope.ch = img.naturalHeight;
Link to updated code pen
Related
I am trying to display parts from an image sheet into separate images.
There's a way to do it with CSS, as in how Reddit Flairs work on the old version of Reddit.
Below is an image that acts as a sheet. I am going to call it unicode_page_00.png
body {
background-color: rgb(20, 20, 20);
}
<body>
<div>
<div style="background: url(https://i.stack.imgur.com/GxJOx.png); image-rendering: pixelated; width: 64px; height: 64px; background-size: 1024px; background-position: -64px 0px;">
</div>
</div>
<br>
<div>
<img src="https://i.stack.imgur.com/GxJOx.png">
</div>
</body>
https://jsfiddle.net/0ztpr5cq/1/
The first part displays an image taken from the image sheet. For this example, the sheet is 256x256 pixels and each character is 16x16 pixels.
I took it and zoomed it in by 4. So the first image shows as 64x64. Then I've shifted the position to display the second character on the sheet from left to right.
And below is the entire image sheet for demonstration.
This is done with CSS. The issue is that you can not save the image the way it was cropped and modified with CSS. Even if it would be made possible with CSS, it would take the entire image sheet and save that instead.
I am trying to display every character on the image sheet as separate images. That you could then freely zoom in with the pixelated effect.
The idea that I have is to turn them into Base64 or something and make the modifications there or before. And at the end, display the final result back into an image, as base64 or blob or other. And that all with the help of JavaScript.
But how would it work? What would the actual process be?
A good solution I came up with was this https://jsfiddle.net/1rmya08u/
You would have to use the canvas element. Here's the solution:
<canvas id="canvas" width="64" height="64"></canvas>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false; // For pixelated drawing
var sheet = new Image();
sheet.src = "https://i.stack.imgur.com/GxJOx.png";
sheet.onload = function () {
var sx = 0;
var sy = 0;
var sWidth = 16;
var sHeight = 16;
var dx = 0;
var dy = 0;
var dWidth = 64;
var dHeight = 64;
ctx.drawImage(sheet, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
};
We're taking a 16x16 sample from the image sheet and rendering it at 64x64. For a better understanding of these arguments, take a look at the reference for ctx.drawImage()
And finally, you can get the result as an image with HTMLCanvasElement.toDataURL()
Is there a way to get the screen/window coordinates from a svg element ?
I have seen solutions for the other way around like:
function transformPoint(screenX, screenY) {
var p = this.node.createSVGPoint()
p.x = screenX
p.y = screenY
return p.matrixTransform(this.node.getScreenCTM().inverse())
}
But what i need in my case are the screen coordinates.
Sory if it's an obvious question, but i'm new to svg.
Thanks.
The code you included in your question converts screen coordinates to SVG coordinates. To go the other way, you have to do the opposite of what that function does.
getScreenCTM() returns the matrix that you need to convert the coordinates. Notice that the code calls inverse()? That is inverting the matrix so it does the conversion in the other direction.
So all you need to do is remove the inverse() call from that code.
var svg = document.getElementById("mysvg");
function screenToSVG(screenX, screenY) {
var p = svg.createSVGPoint()
p.x = screenX
p.y = screenY
return p.matrixTransform(svg.getScreenCTM().inverse());
}
function SVGToScreen(svgX, svgY) {
var p = svg.createSVGPoint()
p.x = svgX
p.y = svgY
return p.matrixTransform(svg.getScreenCTM());
}
var pt = screenToSVG(20, 30);
console.log("screenToSVG: ", pt);
var pt = SVGToScreen(pt.x, pt.y);
console.log("SVGToScreen: ", pt);
<svg id="mysvg" viewBox="42 100 36 40" width="100%">
</svg>
I was playing around with this snippet below when I wanted to do the same (learn which screen coordinates correspond to the SVG coordinates). I think in short this is what you need:
Learn current transformation matrix of the SVG element (which coordinates you are interested in), roughly: matrix = element.getCTM();
Then get screen position by doing, roughly: position = point.matrixTransform(matrix), where "point" is a SVGPoint.
See the snippet below. I was playing with this by changing browser window size and was altering svg coordinates to match those of the div element
// main SVG:
var rootSVG = document.getElementById("rootSVG");
// SVG element (group with rectangle inside):
var rect = document.getElementById("rect");
// SVGPoint that we create to use transformation methods:
var point = rootSVG.createSVGPoint();
// declare vars we will use below:
var matrix, position;
// this method is called by rootSVG after load:
function init() {
// first we learn current transform matrix (CTM) of the element' whose screen (not SVG) coordinates we want to learn:
matrix = rect.getCTM();
// then we "load" SVG coordinates in question into SVGPoint here:
point.x = 100; // replace this with the x co-ordinate of the path segment
point.y = 300; // replace this with the y co-ordinate of the path segment
// now position var will contain screen coordinates:
position = point.matrixTransform(matrix);
console.log(position)
// to validate that the coordinates are correct - take these x,y screen coordinates and apply to CSS #htmlRect to change left, top pixel position. You will see that the HTML div element will get placed into the top left corner of the current svg element position.
}
html, body {
margin: 0;
padding: 0;
border: 0;
overflow:hidden;
background-color: #fff;
}
svg {
position: fixed;
top:0%;
left:0%;
width:100%;
height:100%;
background:#fff;
}
#htmlRect {
width: 10px;
height: 10px;
background: green;
position: fixed;
left: 44px;
top: 132px;
}
<body>
<svg id="rootSVG" width="100%" height="100%" viewbox="0 0 480 800" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init()">
<g id="rect">
<rect id="rectangle" x="100" y="300" width="400" height="150"/>
</g>
</svg>
<div id="htmlRect"></div>
</body>
Not sure why it hasn't been suggested before, but `Element.getBoundingClientRect() should be enough:
const {
top, // x position on viewport (window)
left, // y position on viewport (window)
} = document.querySelector('rect').getBoundingClientRect()
I think other answers might be derived from a method promoted by Craig Buckler on SitePoint, where he explains using the SVGElement API (instead of getBoudingClientRect, from the - DOM - Element API) to convert DOM to SVG coordinates and vice-versa.
But 1. only DOM coordinates are required here 2. he claims that using getBoundingClientRect when transformations (via CSS or SVG) are applied will return incorrect values to translate to SVG coordinates, but the current specification for getBoundingClientRect takes those transformations into account.
The getClientRects() method, when invoked, must return the result of the following algorithm: [...]
If the element has an associated SVG layout box return a DOMRectList object containing a single DOMRect object that describes the bounding box of the element as defined by the SVG specification, applying the transforms that apply to the element and its ancestors.
Specification: https://drafts.csswg.org/cssom-view/#extension-to-the-element-interface
Support: https://caniuse.com/#feat=getboundingclientrect
2020
⚠️ Safari currently has several bugs that make this pretty difficult if you're working with SVGs (or SVG containers) that are transitioning, rotated, or scaled.
getScreenCTM() does not include ancestor scale and rotation transforms in the returned matrix. (If your svgs are neither rotated or scaled, then this is the way to go though.)
However, if you know the ancestor elements that are being scaled and/or rotated, and their transformation values, you can manually fix the matrix provided by getScreenCTM(). The workaround will look something like this:
let ctm = ele.getScreenCTM();
// -- adjust
let ancestorScale = // track yourself or derive from window.getComputedStyle()
let ancestorRotation = // track yourself or derive from window.getComputedStyle()
ctm = ctm.scale(ancestorScale)
ctm = ctm.rotate(ancestorRotation)
// !! Note: avoid ctm.scaleSelf etc. On some systems the matrix is a true blue SVGMatrix (opposed to a DOMMatrix) and may not support these transform-in-place methods
// --
// repeat 'adjust' for each ancestor, in order from closest to furthest from ele. Mind the order of the scale/rotation transformations on each ancestor.
If you don't know the ancestors... the best I've come up with is a trek up the tree looking for transformations via getComputedStyle, which could be incredibly slow depending on the depth of the tree...
getBoundingClientRect() may return incorrect values when transitioning. If you're not animating things but you are transforming things, then this may be the way to go, though I'm pretty sure it's notably less performant than getScreenCTM. Ideally, insert a very small element into the SVG such that its bounding rect will effectively be a point.
window.getComputedStyles().transform has the same issue as above.
Playing with innerWidth, screenX, clientX etc...
I'm not sure about what you are searching for, but as you question is arround screenX, screenY and SVG, I would let you play with snippet editor and some little tries.
Note that SVG bounding box is fixed to [0, 0, 500, 200] and show with width="100%" height="100%".
The last line of tspan with print x and y of pointer when circle is clicked.
function test(e) {
var sctm=new DOMMatrix();
var invs=new DOMMatrix();
sctm=e.target.getScreenCTM();
invs=sctm.inverse();
document.getElementById("txt1").innerHTML=
sctm.a+", "+sctm.b+", "+sctm.c+", "+sctm.d+", "+sctm.e+", "+sctm.f;
document.getElementById("txt2").innerHTML=
invs.a+", "+invs.b+", "+invs.c+", "+invs.d+", "+invs.e+", "+invs.f;
document.getElementById("txt3").innerHTML=
e.screenX+", "+e.screenY+", "+e.clientX+", "+e.clientY;
var vbox=document.getElementById("svg").getAttribute('viewBox').split(" ");
var sx=1.0*innerWidth/(1.0*vbox[2]-1.0*vbox[0]);
var sy=1.0*innerHeight/(1.0*vbox[3]-1.0*vbox[0]);
var scale;
if (sy>sx) scale=sx;else scale= sy;
document.getElementById("txt4").innerHTML=
e.clientX/scale+", "+e.clientY/scale;
}
<svg id="svg" viewBox="0 0 500 200" width="100%" height="100%" >
<circle cx="25" cy="25" r="15" onclick="javascript:test(evt);" />
<text>
<tspan x="10" y="60" id="txt1">test</tspan>
<tspan x="10" y="90" id="txt2">test</tspan>
<tspan x="10" y="120" id="txt3">test</tspan>
<tspan x="10" y="150" id="txt4">test</tspan>
</text>
</svg>
I haven't been able to calculate the click coordinates (x and y) relative to the element triggering the event. I have not found an easy example online.
I have a simple svg (with 100px left margin) in an HTML page. It contains a group (translated 30px 30px) which has an onclick listener attached. And inside that group I have a rect with 50px width and height.
After I click any part of the group element, I get an event object with coordinates relative to the HTML page (evt.clientX and evt.clientY).
What I need to know is where exactly the user clicked inside the group element (the element holding the onclick listener).
How do I convert clientX and clientY coordinates to the group element coordinates. So say, if I click the top leftmost part of the rect it should give me x=0 and y=0.
Here is currently what I have:
<!DOCTYPE html>
<html>
<head>
<style>
body{
background:black;
}
svg{
fill:white;
background:white;
position: absolute;
top:100px;
left:100px;
}
</style>
<script>
function clicked(evt){
alert("x: "+evt.clientX+" y:"+evt.clientY);
}
</script>
</head>
<body>
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<g transform="translate(30 30)" onclick="clicked(evt)">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</g>
</svg>
</div>
</body>
</html>
Tolokoban's solution has the limitation that it doesn't work if your viewBox deviates from the default, that is if it is different from viewBox="0 0 width height". A better solution that also takes viewBox into account is this:
var pt = svg.createSVGPoint(); // Created once for document
function alert_coords(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
// The cursor point, translated into svg coordinates
var cursorpt = pt.matrixTransform(svg.getScreenCTM().inverse());
console.log("(" + cursorpt.x + ", " + cursorpt.y + ")");
}
(Credit goes to Smerk, who posted the code)
If the viewBox is not set or set to the default, this script will return the same values as Tolokoban's script. But if you have an SVG like <svg width="100px" height="100" viewBox="0 0 200 200">, only this version will give you the correct results.
Try to use getBoundingClientRect(): http://jsfiddle.net/fLo4uatw/
function clicked(evt){
var e = evt.target;
var dim = e.getBoundingClientRect();
var x = evt.clientX - dim.left;
var y = evt.clientY - dim.top;
alert("x: "+x+" y:"+y);
}
The proposed solutions are great, but they won't work in all scenarios.
The OP's post is titled
How to get the click coordinates relative to SVG element holding the
onclick listener?
So if you put the onclick listener onto your root svg element, whenever you click on any of its child elements, getBoundingClientRect will give you the child's Rect and you won't get the click coordinates relative to the root svg.
This was my case as I needed the coordinates relative to the root at all times, and the solution that worked for me was to use e.target.farthestViewportElement. Here's an excerpt from my (JSX) code:
const onClickSvg = e => {
const { farthestViewportElement: svgRoot } = e.target;
const dim = svgRoot.getBoundingClientRect();
const x = e.clientX - dim.left;
const y = e.clientY - dim.top;
console.log(`x: ${x}, y: ${y}`);
};
<svg onClick={onClickSvg}>...</svg>
Adding notes after many researchs (and fails!).
For a css translated svg, to get the coordinates of a clicked point for drawing.
In my case, using a mouse wheel event to translateX, so the actual rendering depends of the screen size and of the actual translated value.
I recommend for your use case to make a little drawing like the following, it will help a lot for figuring out what's going on.
Let's say my svg has for id: shoke
To get the total computed width, in pixels:
shoke.getBoundingClientRect()["width"]
Need to know the actual translateX value. (From the right, so it is a negative number, on this case)
shoke.style.transform.substr(11).slice(0,-3)
Note that it return a string and not an integer, so:
+shoke.style.transform.substr(11).slice(0,-3)
Now to get the coordinates of the mouse, related to the pixel x0 of the screen.
let pt = document.querySelector('svg').createSVGPoint();
pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]
So, at the end, to obtain the precise x point:
svg_width - (svg_width + translated) + from_pixel x0 of the screen_click
Is something like this:
shoke.getBoundingClientRect()["width"] - (shoke.getBoundingClientRect()["width"] + +shoke.style.transform.substr(11).slice(0,-3)) + pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]
createSVGPoint is deprecated according to Mozilla. Use static method of DOMPoint.fromPoint(svg_element);
function dom_track_click(evt) {
//<svg onclick='dom_track_click(event); >
let pt = DOMPoint.fromPoint(document.getElementById('svg_canvas'));
pt.x = evt.clientX;
pt.y = evt.clientY;
// The cursor point, translated into svg coordinates
let cursorpt = pt.matrixTransform(document.getElementById('svg_canvas').getScreenCTM().inverse());
console.log("(" + cursorpt.x + ", " + (cursorpt.y) + ")");
}
Some issues using Javascript library html2canvas. The problem is that html2canvas is getting "div2" with a transparent (sometimes white) background, I want to include the body background (or is behind this div) on "div2".
<div id="div2" style="width: 150px; height: 50px;"></div>
html2canvas(document.getElementById("div2"), {
onrendered: function(canvas) {
var photostring = canvas.toDataURL("image/png");
console.log(photostring);
}
});
Logically the rendering works from the element you select.
So will not get the background, unless you select the "parent element" or "root element".
I have two solutions:
1 - Using Javascript/Jquery you can capture X and Y position from div#target
then you set background-image and background-position in div#target by X/Y position
2 - You capture <body> with html2canvas, then using canvas/javascript api you crop image by X/Y position and Width/Height from div#target, see example: #242 (comment)
Note: set width/height/x/y in these variables (see example):
var targetDiv = $("#target");
var sourceX = targetDiv.position().left;/*X position from div#target*/
var sourceY = targetDiv.position().top;/*Y position from div#target*/
var sourceWidth = targetDiv.width();/*clientWidth/offsetWidth from div#target*/
var sourceHeight = targetDiv.height();/*clientHeight/offsetHeight from div#target*/
Get background-image in parent/root element:
https://github.com/niklasvh/html2canvas/commit/281e6bbedf9f611846eba3af4d256eb97f608aa2
Crop canvas:
https://github.com/niklasvh/html2canvas/issues/242#issuecomment-20875688
I am trying to scale and translate svg polygon elements, depending on the browser window size.
Calculating how much I want to scale and translate is not the problem, but changing the polygons is for me.
I am hoping you can help...
I have broken the issue down so that I count the number of polygons (this is ok):
function countnumberofPolygons() {
numberofPolygons = document.getElementsByTagName("polygon").length;
return numberofPolygons;
}
and a function that creates a string for determining the transform="" attribute of the polygon - the transform attribute can be say - transform="translate(800,00) scale(1.2)"
function createsvgtransformattribute(){
transformattribute = '"translate('+ translateAmount +',0) scale(' + scaleAmount + ')"';
}
but looping through them and setting their attributes doesn't seem to work. I've broken it all down and built it back up - but end up with this - which is wrong, probably in some simple way....
function changeattributes(numberofPolygons, transformattribute){
for (var q=0;q< numberofPolygons;q++){
document.getElementsByTagname("polygon")[q].setAttribute("transform", transformattribute);
}
}
But even when inserting the value of the string transformattribute manually, it doesn't work. Can you help please?
When you set a transform attribute using setAttribute you don't put it in double quotes. So what you need is
transformattribute = 'translate('+ translateAmount +',0) scale(' + scaleAmount + ')';
In the html I used the document read Jquery function and onresize to call svgscale().
There are a few oddities in the script - like the left side nudge - but hopefully it should work for others.
I have converted images in image tags to a div that has the image as a background-image. The image maps are then pulled into svg. Then this script uses the transform attribute of the svg to scale and translate the polygons of the image map accordingly.
var winWidth;
var winHeight;
var MainImageHeight;
var MainImageWidth;
var HeightRatio;
var imageWidth;
var leftoffset;
var ImgVsOriginal;
var offsetnudge;
var offsetnudgescaled;
var los;
var translateAmount;
var scaleAmount;
var numberofNodes;
var numberofPolygons;
var polygonArray;
var transformattribute;
function setVariables(){
//Browser window widths and heights
winWidth = window.innerWidth;
winHeight = window.innerHeight;
//Widths and heights of the element with the MainImage id
MainImageHeight = document.getElementById('MainImage').offsetHeight;
MainImageWidth = document.getElementById('MainImage').offsetWidth;
//Establishes the ratio between the height of the element and the background image it displays,
//which has a height of 920px
//The MainImage resizes the background image so the ratio is needed to scale the svg/imagemap
HeightRatio = MainImageHeight/920;
//This establishes the width of the background image as presented - the background image file is 1400px
imageWidth = HeightRatio*1400;
//The Background image is centered and covers the screen. So there is space either side of the background image
//This space is worked out here, and halved to work out the left-hand side portion of the space
leftoffset = (winWidth-imageWidth)/2;
//The original imagemap was created based on an image displayed as 960px by 653px. This calculates the ratio between them.
ImgVsOriginal = MainImageHeight/653;
//The original image was based on images with a small border each side. This is a hard-adjustment for this.
offsetnudge = 30;
//Scales the offset for this border based on the background image size vs the original
offsetnudgescaled = offsetnudge*ImgVsOriginal;
//Creates an easy to type variable based on
//los = leftoffset + offsetnudgescaled;
translateAmount = leftoffset + offsetnudge;
scaleAmount = ImgVsOriginal;
//Creates variable for idname
var idname;
}
function createsvgtransformattribute(){
transformattribute = 'translate('+ translateAmount +',0) scale(' + scaleAmount + ')';
return transformattribute;
}
function countchildNodes(){
numberofNodes = document.getElementById("svgstuff").childNodes.length;
}
function printnumberofnodes(){
document.write('<span>Number of Nodes:' + numberofNodes + '</span>');
}
function countnumberofPolygons(){
numberofPolygons = document.getElementsByTagName("polygon").length;
return numberofPolygons;
}
function getpolygonArray(){
polygonArray = document.getElementsByTagName("polygon");
}
function printnumberofPolygons(){
document.write('<span>Number of Polygons:' + numberofPolygons + '</span>');
}
function changeattributes(){
document.getElementById('test1').innerHTML='changed';
for(q=0; q<polygonArray.length; q++){
//document.getElementsByTagName('polygon')[q].setAttribute("class", "blue");
document.getElementsByTagName('polygon')[q].setAttribute("transform", transformattribute);
}
}
function svgscale(){
setVariables();
getpolygonArray();
createsvgtransformattribute(translateAmount, scaleAmount);
changeattributes();
}
Here are some example polygons for you:
<div id="MainImage">
<svg onresize="svgscale()" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
style="position:absolute;"
width="2000" height="2000"
pointer-events="visible">
<a xlink:href="1.htm" xlink:title="1">');
<polygon id="p1" class="" points="736,378 680,363 680,233 736,209 736,378" transform="" fill="" >
</polygon>
</a>
<a xlink:href="2.htm" xlink:title="2">
<polygon id="p2"class="area" points="839,161,742,204,739,513,831,587,839,161" transform="" fill="">
</polygon>
</a>
<a xlink:href="3.htm" xlink:title="3">');
<polygon id="p3" class="area" points="521,286,521,296,557,297,555,287,521,286" transform="" fill="" >
</polygon>
</a>
<a xlink:href="4.htm" xlink:title="4">');
<polygon id="p4" class="area" points="562,218,562,240,657,242,657,219,562,218" transform="" fill="" >
</polygon>
</a>
<a xlink:href="5.htm" xlink:title="5">');
<polygon id="p5" class="area" points="952,273,909,275,905,276,902,347,858,344,846,351,845,356,855,361,845,542,849,546,849,572,846,573,845,575,841,652,954,652,952,273" transform="" fill="" >
</polygon>
</a>
</svg>
</div>
I put some ids in the polygons in case I couldn't cycle through by TagName, but it works by obtaining the polygons by tagname and cycling through via a for loop. :-)
The css for the #MainImage div is basically:
#MainImage {background-image: url('pix/file.jpg'); background-size: auto 100%;}