#StackBounty: #javascript #html #jquery #svg #fabricjs Fabric.js svg elements to pop up on click to be edited and then return to its pr…

Bounty: 50

I am developing an app in html5 and need at some point to make the paths from an svg to pop up when clicked in order to be edited on a closer view as thier real size is quite small and it will display on mobile screens. This is what I have done until now:

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><meta name="HandheldFriendly" content="true"><meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no, width=device-width"><meta name="viewport" content="width=device-width">
</head><body>
<div>
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 570 770" onload="makeDraggable(evt)">
 <defs><style> body { background: #fff;} svg { border-radius: 10px;} .fgcolor { fill: #fff; opacity: 1; stroke:#1a1a1a; stroke-width:1.5; } .selected { fill: #d50000; opacity: 1; stroke:#1a1a1a; stroke-width:1.5; } .selected2 { fill: #0d47a1; opacity: 1; stroke:#1a1a1a; stroke-width:1.5; } .selected3 { fill: #1a1a1a; opacity: 1; stroke:#1a1a1a; stroke-width:1.5; } .selected4 { fill: #0d47a1; opacity: 1; stroke:#d50000; stroke-width:1.5; }.trans { transition: all 2s ease-in-out 0.5s; } #circle1 #circle2 { z-index:1000;height: 100px;width: 100px;text-align: center;margin: 0 auto; } .grow:hover { transform-origin: 512px 110px;transform: scale(10.0);} .static { cursor: not-allowed; } .draggable, .draggable-group { cursor: move; }</style>
    <script type="text/javascript"><![CDATA[
      function makeDraggable(evt) {
        var svg = evt.target;
        svg.addEventListener('mousedown', startDrag);
        svg.addEventListener('mousemove', drag);
        svg.addEventListener('mouseup', endDrag);
        svg.addEventListener('mouseleave', endDrag);
        svg.addEventListener('touchstart', startDrag);
        svg.addEventListener('touchmove', drag);
        svg.addEventListener('touchend', endDrag);
        svg.addEventListener('touchleave', endDrag);
        svg.addEventListener('touchcancel', endDrag);
        var selectedElement, offset, transform,
            bbox, minX, maxX, minY, maxY, confined;
        var boundaryX1 = 10;
        var boundaryX2 = 560;
        var boundaryY1 = 10;
        var boundaryY2 = 760;
        function getMousePosition(evt) {
          var CTM = svg.getScreenCTM();
          if (evt.touches) { evt = evt.touches[0]; }
          return {
            x: (evt.clientX - CTM.e) / CTM.a,
            y: (evt.clientY - CTM.f) / CTM.d
          };
        }
        function startDrag(evt) {
          if (evt.target.classList.contains('draggable')) {
            selectedElement = evt.target;
            offset = getMousePosition(evt);
            // Make sure the first transform on the element is a translate transform
            var transforms = selectedElement.transform.baseVal;
            if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
              // Create an transform that translates by (0, 0)
              var translate = svg.createSVGTransform();
              translate.setTranslate(0, 0);
              selectedElement.transform.baseVal.insertItemBefore(translate, 0);
            }
            // Get initial translation
            transform = transforms.getItem(0);
            offset.x -= transform.matrix.e;
            offset.y -= transform.matrix.f;
            confined = evt.target.classList.contains('confine');
            if (confined) {
                bbox = selectedElement.getBBox();
                minX = boundaryX1 - bbox.x;
                maxX = boundaryX2 - bbox.x - bbox.width;
                minY = boundaryY1 - bbox.y;
                maxY = boundaryY2 - bbox.y - bbox.height;
            }
          }
        }
        function drag(evt) {
          if (selectedElement) {
            evt.preventDefault();
            var coord = getMousePosition(evt);
            var dx = coord.x - offset.x;
            var dy = coord.y - offset.y;
            if (confined) {
                if (dx < minX) { dx = minX; }
                else if (dx > maxX) { dx = maxX; }
                if (dy < minY) { dy = minY; }
                else if (dy > maxY) { dy = maxY; }
            }
            transform.setTranslate(dx, dy);
          }
        }
        function endDrag(evt) {
          selectedElement = false;
        }
      }
    ]]> </script>
    <script type="application/ecmascript"> <![CDATA[

     var defaultAction = "task";

     function setAction(param) {
         defaultAction = param;
        }

        function click(evt) {
         if (evt.target.classList.contains("fgcolor")) {
         if (defaultAction == "circleschart") {
            hotCircleschartClick(evt.target);
         } else {
            hotTaskClick(evt.target);
            }
         }
        }

        function hotTaskClick(hot) {
            var str = hot.getAttribute("id");
            var hot_id = str.substring(1, str.length);

         if (hot.classList.contains('fgcolor')) {
            hot.classList.add('selected');
            }
        }
     ]]> </script></defs>
 <path id="bg" style="fill:#555;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-opacity:1" d="m 569.48439,0.51561093 0,768.96877907 -568.96877907,0 0,-768.96877907 z"/>
  <path id="circlesmask" style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1.5;stroke-opacity:1" d="m 494.84341,141.33148 a 9.5804669,9.5804669 0 0 0 3.77981,-13.0109 9.5804669,9.5804669 0 0 0 -13.01092,-3.77981 9.5804669,9.5804669 0 0 0 -3.77978,13.01092 9.5804669,9.5804669 0 0 0 13.01089,3.77979 z m 1.99086,-1.2983 c 3.75292,-3.7878 3.79944,-9.90488 0.0548,-13.70535 l 8.46819,-8.34965 c 8.33458,8.49033 8.23285,22.12334 -0.30978,30.3914 z m 0.0915,-13.92778 c -3.83518,-3.70451 -9.95225,-3.67355 -13.70495,0.11906 l -8.45622,-8.36179 c 8.38404,-8.4415 22.0172,-8.51269 30.39291,-0.0756 z m -13.74675,-0.10709 c -3.75291,3.7878 -3.79945,9.90486 -0.0548,13.70536 l -8.46818,8.34965 c -8.3346,-8.49032 -8.23284,-22.12335 0.30978,-30.39141 z m -0.1842,13.84308 c 3.78702,3.75369 9.90405,3.80157 13.70533,0.0577 l 8.34729,8.47053 c -8.49206,8.33279 -22.12509,8.22809 -30.39133,-0.31635 z m 2.64893,-63.1438 a 9.5804669,9.5804669 0 0 0 -3.82845,12.99668 9.5804669,9.5804669 0 0 0 12.9967,3.82844 9.5804669,9.5804669 0 0 0 3.82842,-12.99669 9.5804669,9.5804669 0 0 0 -12.99667,-3.82843 z m -1.9957,1.29085 c -3.76706,3.77374 -3.83646,9.8906 -0.10601,13.70505 l -8.49937,8.31792 c -8.30277,-8.52144 -8.15005,-22.15398 0.42344,-30.39003 z m -0.1436,13.92734 c 3.82131,3.71883 9.93845,3.71075 13.70531,-0.0678 l 8.42488,8.39336 c -8.41555,8.41008 -22.04888,8.43028 -30.39297,-0.038 z m 13.74626,0.1585 c 3.76705,-3.77374 3.83647,-9.89058 0.10603,-13.70505 l 8.49934,-8.31793 c 8.30279,8.52144 8.15004,22.15399 -0.42345,30.39004 z m 0.23598,-13.84229 C 493.71373,74.46416 487.59692,74.3934 483.78167,78.123 l -8.31556,-8.50169 c 8.52317,-8.30097 22.15571,-8.14528 30.38994,0.43002 z"/>
  <g id="circles" onclick="javascript:click(evt);">
  <g id="circle1" class="trans grow">
    <path class="fgcolor" id="v1" d="M 497.48669,78.23199 C 493.71373,74.46416 487.59692,74.3934 483.78167,78.123 l -8.31556,-8.50169 c 8.52317,-8.30097 22.15571,-8.14528 30.38994,0.43002 z"/>
    <path class="fgcolor" transform-center-y="-0.035180283" transform-center-x="-9.0648938" d="m 497.25071,92.07428 c 3.76705,-3.77374 3.83647,-9.89058 0.10603,-13.70505 l 8.49934,-8.31793 c 8.30279,8.52144 8.15004,22.15399 -0.42345,30.39004 z" id="p1"/>
    <path class="fgcolor" d="m 483.50445,91.91578 c 3.82131,3.71883 9.93845,3.71075 13.70531,-0.0678 l 8.42488,8.39336 c -8.41555,8.41008 -22.04888,8.43028 -30.39297,-0.038 z" transform-center-x="-0.15829128" transform-center-y="9.0368236" id="pa1"/>
    <path class="fgcolor" transform-center-y="0.03518" transform-center-x="9.0648894" d="m 483.64805,77.98844 c -3.76706,3.77374 -3.83646,9.8906 -0.10601,13.70505 l -8.49937,8.31792 c -8.30277,-8.52144 -8.15005,-22.15398 0.42344,-30.39003 z" id="d1"/>
    <path class="fgcolor" d="m 485.64375,76.69759 a 9.5804669,9.5804669 0 0 0 -3.82845,12.99668 9.5804669,9.5804669 0 0 0 12.9967,3.82844 9.5804669,9.5804669 0 0 0 3.82842,-12.99669 9.5804669,9.5804669 0 0 0 -12.99667,-3.82843 z" id="o1"/>
  </g>
  <g id="circle2" class="trans grow">
    <path class="fgcolor" id="v2" d="m 482.99482,139.84139 c 3.78702,3.75369 9.90405,3.80157 13.70533,0.0577 l 8.34729,8.47053 c -8.49206,8.33279 -22.12509,8.22809 -30.39133,-0.31635 z"/>
    <path class="fgcolor" id="p2" d="m 483.17902,125.99831 c -3.75291,3.7878 -3.79945,9.90486 -0.0548,13.70536 l -8.46818,8.34965 c -8.3346,-8.49032 -8.23284,-22.12335 0.30978,-30.39141 z" transform-center-x="-9.0648938" transform-center-y="-0.035180283"/>
    <path class="fgcolor" id="pa2" transform-center-y="9.0368236" transform-center-x="-0.15829128" d="m 496.92577,126.1054 c -3.83518,-3.70451 -9.95225,-3.67355 -13.70495,0.11906 l -8.45622,-8.36179 c 8.38404,-8.4415 22.0172,-8.51269 30.39291,-0.0756 z"/>
    <path class="fgcolor" id="d2" d="m 496.83427,140.03318 c 3.75292,-3.7878 3.79944,-9.90488 0.0548,-13.70535 l 8.46819,-8.34965 c 8.33458,8.49033 8.23285,22.12334 -0.30978,30.3914 z" transform-center-x="9.0648894" transform-center-y="0.03518"/>
    <path class= "fgcolor" id="o2" d="m 494.84341,141.33148 a 9.5804669,9.5804669 0 0 0 3.77981,-13.0109 9.5804669,9.5804669 0 0 0 -13.01092,-3.77981 9.5804669,9.5804669 0 0 0 -3.77978,13.01092 9.5804669,9.5804669 0 0 0 13.01089,3.77979 z"/>
  </g>
  </g>
  <path class="static" id="red" style="opacity:1;fill:#d50000;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="m 541.2398,608.99416 c 1e-5,12.28836 -9.96168,22.25005 -22.25005,22.25004 -12.28836,10e-6 -22.25004,-9.96168 -22.25004,-22.25004 10e-6,-12.28836 9.96169,-22.25002 22.25004,-22.25002 12.28836,0 22.25005,9.96166 22.25005,22.25002 z"/>
   <path class="static" style="fill:#0000ff;fill-opacity:1;stroke:#1a1a1a;stroke-width:2.73460841;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 394.64632,689.14759 -27.8083,-28.0013 m 27.90481,0.0965 -28.0013,27.80834 M 402.37488,675.039 c 0,11.94741 -9.68528,21.6327 -21.63269,21.6327 -11.94742,10e-6 -21.63271,-9.68528 -21.63271,-21.6327 0,-11.94741 9.6853,-21.6327 21.63271,-21.63269 11.9474,0 21.63269,9.68529 21.63269,21.63269 z"/>
</svg>
</div>
</body></html>

I need integrate this with jQuery and fabric as the rest of the project use those libraries.

Also need that the triggering of the element to pop up would be mouse click/touch-screen events.

The element should fill the whole superior half of the screen no matter the position it was before and after edited return to the exact same position on another mouse/touch event, or maybe via a close/save button appended to the pop up.

The svg objects on the inferior part are going to act as menu items. I need at least the red and another in blue to act as color pickers where the user touch one of them and then apply that color to the editable items above in the screen once they are poped up to be edited.

There will be a lot of this items on the canvas. If I just placed two of them here was for the obvious reason.

I’ve added more code from Peter Collingridge’s tutorial about draggable svg elements.

If someone knows how to solve it, or at least a part of it, I will be very thankfull.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.