Graphic selection-svg

Posted May 26, 20204 min read

The choice of graphics is inevitably encountered in visual interaction, and it has the highest probability of appearance in visual interviews.
I will talk about it from two directions here, namely svg and canvas. As for the choice of ordinary DOM, I will not say more.
Because the choice of svg is the simplest, let's talk about svg first.
The selection method of svg is the same as the selection method of ordinary DOM. For example, draw a triangle, and then add a normal mouse-in and out-out event:
image.png

<svg version = "1.1"
     baseProfile = "full"
     width = "700" height = "700"
     xmlns = "http://www.w3.org/2000/svg">
    <polygon points = "50 50, 450 50, 250 200" />
</svg>
<script>
    const poly = document.querySelector('polygon');
    poly.addEventListener('mouseover', function() {
        console.log('over');
        poly.setAttribute('fill', 'green');
    });
    poly.addEventListener('mouseout', function() {
        console.log('out');
        poly.setAttribute('fill', 'black');
    })
</script>

In actual work, we may make interactive choices for complex graphics. For example, there is a mountain resembling an elephant in the picture. When we mouse over the mountain, we need to make some corresponding prompts.

mount.jpg

At this time, we can use Illustrator to draw the outline of the mountain.

image.png

After drawing, ctrl + shift + S can be saved as svg file. When saving as, the svg configuration window will also pop up:

image.png

In the above window, we can click the "SVG code" button to view the corresponding SVG code:

<? xml version = "1.0" encoding = "utf-8"?>
<!-Generator:Adobe Illustrator 18.1.1, SVG Export Plug-In. SVG Version:6.00 Build 0)->
<svg version = "1.1" id = "scenery" xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" x = "0px" y = "0px"
     viewBox = "0 0 503 395" enable-background = "new 0 0 503 395" xml:space = "preserve">
<polygon id = "mount" fill-rule = "evenodd" clip-rule = "evenodd" fill = "none" stroke = "# 080102" stroke-miterlimit = "10" points = "
    211.7, 260.8 234.6, 236.6 241.2, 190.3 245.6, 165.2 255.7, 145.4 309.5, 95.2 358.4, 74.9 381.7, 115.9 388.8, 130.4 385.7, 137.9
    398,174.5 406.4,176.2 433.3,205.3 443.8,236.6 468.9,263 288.8,264.8 294.5,239.2 276,243.6 265.9,262.6 "/>
</svg>

As you can see from the SVG code, the name of the layer is the id of the SVG element.
After we have the SVG file, we need to import it into the HTML page. Because this file is generated using Adobe's Illustrator software, we will use the official Adobe recommended way to import the svg file:

<embed id = "svg"
       src = "./images/scenery.svg"
       width = "503"
       height = "395"
       type = "image/svg + xml"
       pluginspage = "http://www.adobe.com/svg/viewer/install/" />

After introducing the svg file using the src attribute of the tag, we need to add mouse events to the elements in svg. This process needs to consider two issues:

  1. The introduction of the svg file is an asynchronous event. We need to obtain the elements in the svg after the svg file is successfully imported.

  2. The elements in the elements in svg cannot be directly obtained from the document of the current page. The svg file has its own document object.
    The first problem can be solved by adding onload event for window or embed, such as:

    const embed = document.querySelector('embed');
    /* When the page content is loaded successfully * /
    window.onload = function() {

     const dom = embed.getSVGDocument();
     const mount = dom.querySelector('# mount');
     mount.setAttribute('fill', 'rgba(0,0,0,0)');
     mount.addEventListener('mouseover', function() {
         console.log('over');
         mount.setAttribute('fill', 'rgba(0,255,255,0.4)')
     });
     mount.addEventListener('mouseout', function() {
         console.log('out');
         mount.setAttribute('fill', 'rgba(0,0,0,0)')
     })

    };

The second problem is to use embed.getSVGDocument() method to get svg's own document object, and then use this document object to get the elements in SVG.
Complete code:

<embed id = "svg"
       src = "./images/scenery.svg"
       width = "503"
       height = "395"
       type = "image/svg + xml"
       pluginspage = "http://www.adobe.com/svg/viewer/install/" />

<script type = "module">
    const embed = document.querySelector('embed');
   /* When the page content is loaded successfully * /
    window.onload = function() {
        const dom = embed.getSVGDocument();
        const mount = dom.querySelector('# mount');
        mount.setAttribute('fill', 'rgba(0,0,0,0)');
        mount.addEventListener('mouseover', function() {
            console.log('over');
            mount.setAttribute('fill', 'rgba(0,255,255,0.4)')
        });
        mount.addEventListener('mouseout', function() {
            console.log('out');
            mount.setAttribute('fill', 'rgba(0,0,0,0)')
        })
    };
</script>

Page effect:
image.png

When svg drawing, if the number of graphics is very large, the rendering speed will be very slow, and it is not suitable for image processing. At this time, you need to select canvas.
Now that we choose canvas, we must consider how to select the graphics in canvas.
Next, I will tell you two methods:

  • The built-in isPointInPath(x, y) method of canvas.
  • Polygon meshing method.

Please see the next chapter: Graphic Selection -isPointInPath(x, y)

Source Address