<!DOCTYPE html>
<html>

<head>
  <title>Liquid SVG</title>
  <style>
    html {
      padding: 0;
      margin: 0;
      height: 100%; /* Required for liquidity. The height of the HTML element will now be the height of the window - whatever its size may be. */
   }
   
    body {
      padding: 0;
      margin: 0;
      height: 100%; /* Required for liquidity. The height of the BODY element will now be the height of the its container - which is the HTML element. */
   }
   
   div#messageBox {
     position: absolute; /* Keep this out of the page flow. */
     left: 1em;
   }
   
   div#liquidTopMargin {
     height: 1%; /* Provides a small liquid margin between the top of the browser window and the SVG viewport. */
   }   
  </style>
  <script>
    function coordinateTransform(screenPoint, someSvgObject)
    /*
      Given a screen point (of type SVGPoint), returns the point relative to the coordinate system associated with someSvgObject. Assumes someSvgObject is some type of SVG object such as a circle object.
    */
    {
      var CTM = someSvgObject.getScreenCTM(); // Get the current transformation matrix (CTM) for someSvgObject. The CTM defines the mapping from the user coordinate system into the viewport coordinate system.

      return screenPoint.matrixTransform( CTM.inverse() ); // Return the point in the coordinate system associated with someSvgObject.
    }
    
    function reportMouseCoordinates(evt) 
    {     
      var screenXY = document.getElementById('screenXY'); // Required for Firefox.
      screenXY.textContent = "Screen: (" + evt.pageX + ", " + evt.pageY + ")"; // Display the screen coordinates for the mouse.

      var svgElement = document.getElementById('svgElement'); // Required for Firefox.
      var point = svgElement.createSVGPoint(); // Create a new SVG point object so that we can (ultimately) access its matrixTransform() method in function coordinateTransform().
      point.x = evt.pageX; // Transfer the screen coordinates of the mouse to the SVG point object.
      point.y = evt.pageY;
      
      var svgCircle = document.getElementById('svgCircle'); // Required for Firefox.
      point = coordinateTransform(point, svgCircle); // Map the screen coordinate to the coordinate system associated with svgCircle.
      
      var circleXY = document.getElementById('circleXY'); // Required for Firefox.      
      circleXY.textContent = "Circle: (" + point.x.toFixed(0) + ", " + point.y.toFixed(0) + ")"; // Display the mouse's position relative to the circle's coordinate system.
    }
    
    function mouseClick (e) 
    {
      var svg = document.getElementById('svgElement'); // Required for Firefox.
      var rect = document.getElementById('my-rect');
      var rectMatrix = rect.getCTM();
        
      debugger;
      
      // Absolute move
      var transformed = rectMatrix
        .inverse()
        .multiply(svg.createSVGMatrix().rotate(30).translate(10, 10));
        
      rect.transform.baseVal.initialize(svg.createSVGTransformFromMatrix(transformed));
    
      console.log("Click", e, rect);
    }
    
    function keyup (e) 
    {
      var svg = document.getElementById('svgElement'); // Required for Firefox.
      var rect = document.getElementById('my-rect');
      var rectMatrix = rect.getCTM();
      
      // This does not work
      var transformed = rectMatrix.rotate(60);
      
      rect.transform.baseVal.initialize(svg.createSVGTransformFromMatrix(transformed));
      
      
      console.log(e);
    }
    
    function init() 
    {
      window.addEventListener('mousemove', reportMouseCoordinates, false);
      window.addEventListener('click', mouseClick, false);
      window.addEventListener('keyup', keyup, false);
    }

    window.addEventListener("load", init, false); // Executes the init function only when the page has fully loaded.
  </script>
</head>

<body>
  <div id="messageBox"> <!-- This is not in the page flow since it's positioned absolutely. -->
    <p id="screenXY">Screen: mouse over circle</p> <!-- Display mouse coordinates relative to the screen's coordinate system. -->
    <p id="circleXY">Circle: mouse over circle</p> <!-- Display mouse coordinates relative to the circle's coordinate system. -->
  </div> 
  <div id="liquidTopMargin"></div> <!-- Provide a liquid upper margin for the SVG viewport. -->
  <svg id="svgElement" width="100%" height="98%" viewbox="0 0 800 800"> <!-- The percentages here are required for liquidity. The 98% provides a liquid bottom margin for the SVG viewport. -->
    <g transform="translate(400, 400) scale(1, -1)"> <!-- Create a Cartesian coordinate system for all child elements. -->
      <circle id="svgCircle" cx="0" cy="0" r="400" stroke="black"stroke-width="2" fill="orange" /> 
      <line x1="-400" y1="0" x2="400" y2="0" stroke="black" /> <!-- Dray x-axis -->
      <line x1="0" y1="-400" x2="0" y2="400" stroke="black" /> <!-- Draw y-axis -->  
      <g>
        <rect x="130" y="130" width="30" height="30" id="my-rect"></rect>
      </g>
      <g transform="scale(1, -1)"> <!-- Flip the text back the way it was. That is, right side up. -->
        <text x="356" y="-5">x-axis</text>
        <text x="5" y="-383">y-axis</text>
        <text x="5" y="-8">(0, 0)</text>
      </g>    
    </g>    
  </svg>
</body>

</html>
// Code goes here

/* Styles go here */