SVG - resizing a rectangle positioned at an angle - svg

All,
I have a SVG rectangle in my application which can be stretched horizontally by dragging the end bar (left & right) on either side of the rectangle. The rectangle can be
(1) resized (by stretching as per above),
(2)dragged,
(3)& rotated.
Everything works fine, however, one strange experience is that when I rotate the rectangle to a degree close to 90, & then try to resize the rectangle, it starts stretching from the opposite border of the rectangle instead of the original borders. (here is the image):
It appears to be getting confused between left and right when I use the rotate function.
Here is the revised HTML, JS & SVG:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<!-- <script type="text/javascript" src="CPolyline.js">
</script>-->
</head>
<body>
<object id="oo" data="rect2.svg" style="position:fixed;width: 800px;height:800px;bottom:-100px;right: 375px;">
</object>
path: <input type="button" id="path" onclick="X()">
path2: <input type="button" id="path2" onclick="Y()">
<input type="button" value="Rotate" onclick="Rotate1()">
<script type="text/javascript">
var ob=document.getElementById("oo")
var svgDoc=null;
var svgRoot=null;
var MyGroupObjectsObj = null;
var svgNS = "http://www.w3.org/2000/svg";
var dragTarget = null;
var rectTemplate = null;
var grabPoint = null;
var clientPoint = null;
var rectX = null;
var rectY = null;
var rectWidth = null;
var rectHeight = null;
var arr=new Array();
var resizingLeft = false;
var resizingRight = false;
var rectrot=null
ob.addEventListener("load", function(){
svgDoc=ob.contentDocument;
svgRoot=svgDoc.documentElement;
grabPoint = svgRoot.createSVGPoint();
clientPoint = svgRoot.createSVGPoint();
rectTemplate = svgDoc.getElementById('rectTemplate')
rectrot=svgDoc.getElementById("rect1")
}, false)
var angel=0
function Rotate1()
{
angel=angel+10
//alert(rectrot)
var c=rectTemplate.getAttribute("transform");
var widt=Number(rectTemplate.getAttribute("width"))/2;
var hie=Number(rectTemplate.getAttribute("height"))/2
var tran=c.match(/[\d\.]+/g);
var newxpo=Number(tran[0])+widt;
var newypo=Number(tran[1])+hie;
var r=Math.tan((newxpo)/(newypo))
rectTemplate.parentNode.setAttribute("transform","translate("+newxpo+" "+newypo+")"+"rotate("+angel+") translate("+(newxpo*-1)+" "+(newypo*-1)+")");
}
function MouseDown(evt)
{
var targetElement = evt.target;
var checkForResizeAttempt = false;
if (targetElement == rectTemplate)
{
//arr.push(cir ,cir1,rectTemplate)
dragTarget = targetElement;
checkForResizeAttempt = true;
var transMatrix = dragTarget.getCTM();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
}
var transMatrix = dragTarget.getCTM();
//var transMatrix = dragTarget.getCTM().inverse();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
if (window.console) console.log(grabPoint.x + " " + grabPoint.y);
if (window.console) console.log(evt.clientX + " " + evt.clientY);
if (checkForResizeAttempt)
{
clientPoint.x = evt.clientX;
clientPoint.y = evt.clientY;
rectX = Number(dragTarget.getAttributeNS(null, "x"));
rectY = Number(dragTarget.getAttributeNS(null, "y"));
rectWidth = Number(dragTarget.getAttributeNS(null, "width"));
rectHeight = Number(dragTarget.getAttributeNS(null, "height"));
if ((grabPoint.x - rectX) < 10)
{
resizingLeft = true;
}
else if (((rectX + rectWidth) - grabPoint.x) < 10)
{
resizingRight = true;
}
if (resizingLeft || resizingRight)
{
dragTarget.setAttributeNS(null,"stroke","green");
}
else
{
dragTarget.setAttributeNS(null,"stroke","black");
}
}
}
function MouseMove(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
if (resizingLeft)
{
if (window.console) console.log(evt.clientX + " " + evt.clientY);
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth + deltaX);
dragTarget.setAttributeNS(null,"x",rectX - deltaX);
}
else if (resizingRight)
{
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("rectWidth = " + rectWidth + " deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth - deltaX);
}
else
{
var newXX = evt.clientX-grabPoint.x;
var newYX = evt.clientY-grabPoint.y;
dragTarget.setAttributeNS(null,'transform','translate(' + newXX + ',' + newYX + ')');
}
}
function MouseUp(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
resizingLeft = false;
resizingRight = false;
resizingTop = false;
resizingBottom = false;
// var transMatrix = dragTarget.getCTM().inverse();
dragTarget.setAttributeNS(null,"stroke","blue");
dragTarget = null;
}
</script>
</body>
</html>
--
=======SVG ====
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="612px" height="792px" xml:space="preserve"
onmousedown="ecmascript:top.MouseDown(evt)"
onmousemove="ecmascript:top.MouseMove(evt)"
onmouseup="ecmascript:top.MouseUp(evt)">
<g id="rect1">
<rect id="rectTemplate" x="0" y="0" stroke="blue" width="100" height="30" />
</g>

I have posted a sample of dragging and resizing transformed SVG rects in my answer here:
SVG coordinates with transform matrix
You can see the working example on my site here:
http://phrogz.net/svg/drag_under_transformation.xhtml
The key is to:
When you start dragging (mousedown) record the mouse location (in SVG global space).
During dragging (mousemove) calculate the offset (in SVG global space) for the drag, and then
Transform that offset from global space into the local space of the object, and use that to inform your changes.
This works regardless of the transformation hierarchy applied (as shown in my example).

Have you tried to change your code to rotate the shape around the center of the shape?
Here is an excerpt of the W3C draft on transform:
rotate(<rotate-angle> [<cx> <cy>]),
which specifies a rotation by <rotate-angle> degrees about a given point.
If optional parameters <cx> and <cy> are not supplied, the rotate is about the origin of the current user coordinate system.
The operation corresponds to the matrix [cos(a) sin(a) -sin(a) cos(a) 0 0].
If optional parameters <cx> and <cy> are supplied, the rotate is about the point (cx, cy).
The operation represents the equivalent of the following specification:
translate(<cx>, <cy>) rotate(<rotate-angle>) translate(-<cx>, -<cy>).
If you set cx and cy to the center of your ribbon, this may help from what context I can pick up from your code.

Related

All fillTexted text crammed in one place in HTML5 canvas

I want to display an hexagonal grid where each cell displays its coordinate in the system (thus the top leftmost cell will have a1 written in it, the one immediately right to it will have b1 written in it, etc).
The code below is meant to achieve this (and nearly does it).
However all the texts are crammed in one small place (even though I specified the location on line 48 of the code, and this location seems correct since the rest of the image is fine). What am I doing wrong ?
<html>
<head>
<meta charset="utf-8">
<title>Hex board</title>
<script type="text/javascript">
var r = 20;
var w = r*2*(Math.sqrt(3)/2);
var ctx;
var mainWidth = 850;
var mainHeight = 600;
var dim = 11;
var i,x,y, txt;
var alphabet =["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
function textFromCoordinates(x,y)
{
return(alphabet[x]+(y+1));
}
function drawHexagon(c, x, y, r)
{
c.beginPath();
c.moveTo(x, y-r);
for(i=0; i<6; i++) {
c.lineTo(x+r*Math.cos(Math.PI*(1.5+1/3*i)), y+r*Math.sin(Math.PI*(1.5+1/3*i)));
}
c.closePath();
c.fill();
c.stroke();
}
function draw()
{
ctx.clearRect(0, 0, mainWidth, mainHeight);
ctx.lineWidth = 1;
ctx.strokeStyle = "white";
for(y=0; y<dim; y++)
{
for(x=0; x<dim; x++)
{
ctx.fillStyle = "rgb(" + (x+241) + "," + (y+220) + ",178)";
drawHexagon(ctx, (x+y)*w - (y-4)*(w/2), (y+2)*1.5*r, r);
txt = textFromCoordinates(x,y);
ctx.font = 'italic 40pt Calibri';
ctx.fillStyle = "black";
ctx.moveTo((x+y)*w - (y-4)*(w/2), (y+2)*1.5*r);
ctx.fillText(txt,mainWidth/dim,mainHeight/dim);
}
}
}
function load()
{
var canvas = document.getElementById("output");
ctx = canvas.getContext("2d");
draw();
}
</script>
</head>
<body onload="load()">
<canvas style="position:absolute,top:0px,left:20px" width="850" height="600" id="output">Canvas not supported...</canvas>
</body>
</html>
You need to draw the text at the same coordinates as the hexagon:
ctx.fillText(txt,(x+y)*w - (y-4)*(w/2),(y+2)*1.5*r);
Also I've changed the font to a smaller size, and I'm aligning it around the center:
ctx.font = 'italic 16px Calibri';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
I hope this is what you need.
var r = 20;
var w = r*2*(Math.sqrt(3)/2);
var ctx;
var mainWidth = 850;
var mainHeight = 600;
var dim = 11;
var i,x,y, txt;
var alphabet =["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
function textFromCoordinates(x,y)
{
return(alphabet[x]+(y+1));
}
function drawHexagon(c, x, y, r)
{
c.beginPath();
c.moveTo(x, y-r);
for(i=0; i<6; i++) {
c.lineTo(x+r*Math.cos(Math.PI*(1.5+1/3*i)), y+r*Math.sin(Math.PI*(1.5+1/3*i)));
}
c.closePath();
c.fill();
c.stroke();
}
function draw()
{
ctx.clearRect(0, 0, mainWidth, mainHeight);
ctx.lineWidth = 1;
ctx.strokeStyle = "white";
for(y=0; y<dim; y++)
{
for(x=0; x<dim; x++)
{
ctx.fillStyle = "rgb(" + (x+241) + "," + (y+220) + ",178)";
drawHexagon(ctx, (x+y)*w - (y-4)*(w/2), (y+2)*1.5*r, r);
txt = textFromCoordinates(x,y);
ctx.font = 'italic 16px Calibri';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "black";
ctx.fillText(txt,(x+y)*w - (y-4)*(w/2),(y+2)*1.5*r);
}
}
}
function load()
{
var canvas = document.getElementById("output");
ctx = canvas.getContext("2d");
draw();
}
load()
canvas{border:1px solid}
<canvas style="position:absolute,top:0px,left:20px" width="850" height="600" id="output">Canvas not supported...</canvas>

p5.js and node.js sync the position of x and y for little blobs

I'm currently making a agar.io like program for my school project using p5.js and node.js for the networking. However I'm having a problem setting all the little blobs in one locations for multiplayer mode because I wrote the program of setting the little blobs on a local javascript(circle.js). I tried to transfer the functions of the local javascript to the server.js(node.js) but when i call it, it only hangs up. This is the screenshot of the directory.
Here is the code of server.js
var express = require('express');
var app = express();
var server = app.listen(3000);
app.use(express.static('public'));
console.log("Running");
var socket = require('socket.io');
var io = socket(server);
io.sockets.on('connection', newConnection);
function newConnection(socket){
console.log('new connection' + socket.id);
}
function asd(){
fill(255);
ellipse(200, 200, 100 * 2, 100 * 2);
}
Here is the code of the index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>agar.io</title>
<script src="libraries/p5.js" type="text/javascript"></script>
<script src="libraries/p5.dom.js" type="text/javascript"></script>
<script src="libraries/p5.sound.js" type="text/javascript"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="sketch.js" type="text/javascript"></script>
<script src="circle.js" type="text/javascript"></script>
<script src="C:/Users/hp/Desktop/p5.js/Project/agario/server.js" type="text/javascript"></script>
<style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style>
</head>
<body>
</body>
</html>
Here is the code of Circle.js
function Circle(positionX, positionY, radius) {
this.position = createVector(positionX, positionY);
this.radius = radius;
this.velocity = createVector(0, 0);
this.show = function() {
fill(255);
ellipse(this.position.x, this.position.y, this.radius * 2, this.radius * 2);
}
this.update = function() {
var newVelocity;
velocity = createVector(mouseX - width / 2, mouseY - height / 2);
newVelocity = createVector(mouseX - width / 2, mouseY - height / 2);
newVelocity.setMag(3);
this.velocity.lerp(newVelocity, 0.2);
this.position.add(this.velocity);
}
this.eat = function(other) {
var distance = p5.Vector.dist(this.position, other.position);
if (distance < this.radius + other.radius) {
var area = Math.PI * Math.pow(this.radius, 2) + Math.PI * Math.pow(other.radius, 2);
this.radius = Math.sqrt(area / Math.PI);
return true;
} else {
return false;
}
}
}
Here is the code of sketch.js
var circle;
var circles = [];
var zoom = 1;
var newZoom;
var socket;
function setup() {
socket = io.connect('http://localhost:3000');
createCanvas(1366, 666);
circle = new Circle(0, 0, 64);
for (var x = 0; x < 410; x++) {
circles[x] = new Circle(random(-width, width * 4), random(-height, height * 4), 20);
}
}
function draw() {
background(60);
translate(width / 2, height / 2);
newZoom = (64 / circle.radius*1.5);
zoom = lerp(zoom, newZoom, 0.1);
scale(zoom);
translate(-circle.position.x, -circle.position.y);
for (var x = circles.length - 1; x >= 0; x--) {
if (circle.eat(circles[x])) {
circles.splice(x, 1);
}
}
circle.show();
circle.update();
for (var x = 0; x < circles.length; x++) {
circles[x].show();
}
asd();
}
As you can see, i tried to call a function on node.js just to try if it is valid to get an information from server.js to have a similar counts and positions of little blobs, my question is how I can make a server that gives an x and y position for the little blobs?
socket.on('mouse',
function(data) {
// Data comes in as whatever was sent, including objects
console.log("Received: 'mouse' " + data.x + " " + data.y);
// Send it to all other clients
socket.broadcast.emit('mouse', data);
// This is a way to send to everyone including sender
// io.sockets.emit('message', "this goes to everyone");
}
);

Error: How to draw circle using triangle fan in webgl?

I am not able to draw the circle using triangle fan.
The following code is of my JavaScript file.
My html contains canvas and shaders.
Also I have another JavaScript which initializes the vertex shaders and fragment shaders. Initializing shaders from the other javascript files has no issues at all becuase it is working properly with other codes.
Please help me with this code, finding what is wrong with it.
var xCenterOfCircle;
var yCenterOfCircle;
var centerOfCircle;
var radiusOfCircle = 200;
var ATTRIBUTES = 2;
var noOfFans = 80;
var anglePerFan;
var verticesData = [];
var canvas;
var gl;
window.onload = function init()
{
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
//
// Configure WebGL
//
gl.viewport( 0.0, 0.0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
// Load shaders and initialize attribute buffers
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
drawCircle();
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
gl.bufferData( gl.ARRAY_BUFFER, flatten(verticesData), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
render();
}
function drawCircle()
{
xCenterOfCircle = 400;
yCenterOfCircle = 400;
centerOfCircle = vec2(400, 400);
anglePerFan = (2*Math.PI) / noOfFans;
verticesData = [centerOfCircle];
for(var i = 0; i <= noOfFans; i++)
{
var index = ATTRIBUTES * i + 2;
var angle = anglePerFan * (i+1);
var xCoordinate = xCenterOfCircle + Math.cos(angle) * radiusOfCircle;
var yCoordinate = yCenterOfCircle + Math.sin(angle) * radiusOfCircle;
document.write(xCoordinate);
document.write("\n");
document.write(yCoordinate);
var point = vec2(xCoordinate, yCoordinate);
verticesData.push(point);
}
}
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays( gl.TRIANGLE_FAN, 0, verticesData.length/ATTRIBUTES );
}
This is my html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Supper Bug Zapper</title>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
void main(void)
{
gl_Position = vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 1.0, 0.5);
}
</script>
<script type="text/javascript" src="js/webgl-utils.js"></script>
<script type="text/javascript" src="js/MV.js"></script>
<script type="text/javascript" src="js/initShaders.js"></script>
<script type="text/javascript" src="js/superBugZapper.js"></script>
</head>
<body>
<canvas id="gl-canvas" width="800" height="800" style="border:1px solid #000000;">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
The viewport coordinates of the screen are define between -1 and 1. The center of the screen is [0, 0], the bottom left is [-1, -1] etc.
Your circle's radius is 200 and it's center is [400, 400], in your screen it's a huge circle way beyond in the top right corner.
Start creating a circle with let's say .5 radius in center [0, 0]. You should see something.
If you need to keep this scale in your buffer, you can also provide a matrix to your vertex shader to transform your space coordinate to the regular openGL viewport coordinates.

HTML SVG Line and applying transition to change in x1 y1 attributes in javascript

I have an SVG Line which after 5 seconds receives new x1 y1 coorindates. How do apply a transition to the line so that it smoothly moves. In the code attached, I'm able to change it's color through a smooth transition, but the location blinks from one spot to the other.
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<head>
</head>
<body>
<script language="JavaScript">
setInterval(function trackuser ()
{
var x_one = 45;
var y_one = 13;
var r_one = 50;
var x_two = 55;
var y_two = 85;
var r_two = 36;
var x_thr = 70;
var y_thr = 35;
var r_thr = 28;
var first = (-Math.pow(x_two,2)+Math.pow(x_thr,2)-Math.pow(y_two,2)+Math.pow(y_thr,2)+Math.pow(r_two,2)-Math.pow(r_thr,2))/(-2*y_two+2*y_thr);
var secon = (-Math.pow(x_one,2)+Math.pow(x_two,2)-Math.pow(y_one,2)+Math.pow(y_two,2)+Math.pow(r_one,2)-Math.pow(r_two,2))/(-2*y_one+2*y_two);
var third = ((2*x_one-2*x_two)/(-2*y_one+2*y_two))-((2*x_two-2*x_thr)/(-2*y_two+2*y_thr));
var x = (first-secon)/third;
var y = ((2*x_one-2*x_two)/(-2*y_one+2*y_two))*x+secon;
document.getElementById("line").setAttribute("x2", x+'%');
document.getElementById("line").setAttribute("y2", y+'%');
document.getElementById("line").style.stroke = "blue";
document.getElementById("line").style.WebkitTransition = "all 2s"; // Code for Safari 3.1 to 6.0
document.getElementById("line").style.transition = "all 2s"; // Standard syntax
},5000);
</script>
<div>
<svg height="100%" width="100%" style="position:absolute; top:0%; left:0%">
<line id="line" x1="45%" y1="13%" x2="55%" y2="70%" style="stroke:rgb(255,0,0);stroke-width:3"></line>
</svg>
</div>
</body>
</html>
You can't (yet) animate coordinates with CSS. You are going to have to animate them yourself with JS. Either manually (eg. with requestAnimationFrame, or a Timeout), or use one of the SVG javascript libraries.

SVG - Get untransformed points?

Say I have the following SVG:
<g id="g1" transform="translate(100, 250) rotate(90)" >
<path id="path1" d="M 100,100 c...
Is there a way to get the actual coordinates of the d attribute? Ideally I want some function such as untransform below:
var transform = $("g1").getAttribute("transform");
var d = $("path1").getAttribute("d");
var dUntransformed = untransform(d, transform);
$("g1").removeAttribute("transform");
$("path1").setAttribute("d", dUntransformed);
The idea is that if I ran this script the resulting image would be identical to the previous image.
The reason I want to do this is because I have an animation that follows this path. However because of the transform the animation is off. And if I add the transform to the animateMotion object the animation is still off. So my thought is to remove the path and put it back exactly where it is. So that I can get the animation to work. (The AnimateMotion is similar to this demo: https://mdn.mozillademos.org/files/3261/animateMotion.svg)
Here is an example to return screen points after tranformations : polygon, path, polyline. The path example does not work or arcs. Also, in some cases relative points may not return. This uses getCTM and matrixTransform. It may be possible to create an array to 'remember' the points at various time lines.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Return Screen Points After Tranformations</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:0px;font-family:arial'>
<center>
<h4>Return Screen Points After Tranformations : polygon, path, polyline</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:10px;'>
In many cases it is meaningful to return certain svg elements(polygon, polyline, and path) to their screen x,y values following transformations. This is accomplished using <b>getCTM</b>, and <b>matrixTransform</b>
Note: Use vector-effect="non-scaling-stroke" for elements with stroke(*not available in IE).
</div>
<div id="svgDiv" style="background-color:lightgreen;width:500px;height:500px;">
<svg id="mySVG" width="500" height="500">
<path id="myPath" vector-effect="non-scaling-stroke" transform="scale(.8)translate(120 50)skewY(15)rotate(-15)" fill="yellow" stroke="black" stroke-width="2"
d="M50,50 Q-30,100 50,150 100,230 150,150 230,100 150,50 100,-30 50,50"/>
<polyline vector-effect="non-scaling-stroke" id="myPolyline" transform="scale(.3)translate(700 620)" fill="red" stroke="black" stroke-width="3" points="122 60 150 450 500 400" />
<polygon vector-effect="non-scaling-stroke" id="myPolygon" transform="scale(3)translate(122 132)" fill="purple" stroke="white" stroke-width="3"points="15,0 10.6066,-10.6066 9.18486e-016,-15 -10.6066,-10.6066 -15,-1.83697e-015 -10.6066,10.6066 -2.75545e-015,15 10.6066,10.6066" />
</svg>
</div>
<button onClick=change2Screen()>change to screen values</button>
<br />SVG Source:<br />
<textarea id=mySVGValue style='font-size:120%;font-family:lucida console;width:90%;height:200px'></textarea>
<br />Javascript:<br />
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
</center>
<div id='browserDiv' style='padding:3px;position:absolute;top:5px;left:5px;background-color:gainsboro;'></div>
<script id=myScript>
//--button---
function change2Screen()
{
screenPolyline(myPolyline)
screenPolygon(myPolygon)
screenPath(myPath)
mySVGValue.value=svgDiv.innerHTML
}
function screenPolyline(myPoly)
{
var sCTM = myPoly.getCTM()
var svgRoot = myPoly.ownerSVGElement
var pointsList = myPoly.points;
var n = pointsList.numberOfItems;
for(var m=0;m<n;m++)
{
var mySVGPoint = svgRoot.createSVGPoint();
mySVGPoint.x = pointsList.getItem(m).x
mySVGPoint.y = pointsList.getItem(m).y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
pointsList.getItem(m).x=mySVGPointTrans.x
pointsList.getItem(m).y=mySVGPointTrans.y
}
//---force removal of transform--
myPoly.setAttribute("transform","")
myPoly.removeAttribute("transform")
}
//---except arc/relative paths---
function screenPath(path)
{
var sCTM = path.getCTM()
var svgRoot = path.ownerSVGElement
var segList=path.pathSegList
var segs=segList.numberOfItems
//---change segObj values
for(var k=0;k<segs;k++)
{
var segObj=segList.getItem(k)
if(segObj.x && segObj.y )
{
var mySVGPoint = svgRoot.createSVGPoint();
mySVGPoint.x = segObj.x
mySVGPoint.y = segObj.y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
segObj.x=mySVGPointTrans.x
segObj.y=mySVGPointTrans.y
}
if(segObj.x1 && segObj.y1)
{
var mySVGPoint1 = svgRoot.createSVGPoint();
mySVGPoint1.x = segObj.x1
mySVGPoint1.y = segObj.y1
mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
segObj.x1=mySVGPointTrans1.x
segObj.y1=mySVGPointTrans1.y
}
if(segObj.x2 && segObj.y2)
{
var mySVGPoint2 = svgRoot.createSVGPoint();
mySVGPoint2.x = segObj.x2
mySVGPoint2.y = segObj.y2
mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM)
segObj.x2=mySVGPointTrans2.x
segObj.y2=mySVGPointTrans2.y
}
}
//---force removal of transform--
path.setAttribute("transform","")
path.removeAttribute("transform")
}
//---changes all transformed points to screen points---
function screenPolygon(myPoly)
{
var sCTM = myPoly.getCTM()
var svgRoot = myPoly.ownerSVGElement
var pointsList = myPoly.points;
var n = pointsList.numberOfItems;
for(var m=0;m<n;m++)
{
var mySVGPoint = svgRoot.createSVGPoint();
mySVGPoint.x = pointsList.getItem(m).x
mySVGPoint.y = pointsList.getItem(m).y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
pointsList.getItem(m).x=mySVGPointTrans.x
pointsList.getItem(m).y=mySVGPointTrans.y
}
//---force removal of transform--
myPoly.setAttribute("transform","")
}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
mySVGValue.value=svgDiv.innerHTML
jsValue.value=myScript.text
}
</script>
</body>
</html>

Resources