The original article is reprinted from liu Yue’s Technology blog v3u.cn/a_id_148

In previous articles, Scalable Vector (SVG), a popular image technology in the industry, was introduced Graphics), such as Iconfont(vector icon) + Iconmoon (icon SVG interconversion) and javascript to create our own personalized social sharing system. We can use SVG to create exquisite and cool small sharing ICONS. This time we used Python to convert the normal static website logo image into SVG image with path, so that the website logo can become dynamic. As a website logo is not uncomfortable, a cool animation will naturally satisfy our desire to make it. It also strikes at our vanity.

The first step is to transform the static image. Take the logo of this site as an example. The principle is to transcode its pixels in the ordinary RGB image array and output them as svG-specific path attributes

import sys  
import os  
from PIL import Image  
  
def convertPixel(r, g, b, a=1):  
    color = "#%02X%02X%02X" % (r, g, b)  
    opacity = a  
    return (color, opacity)  
  
for r in sys.argv[1:]:  
    root, ext = os.path.splitext(r)  
  
    image = Image.open(r)  
    mode = image.mode  
    pixels = image.load()  
    width, height = image.size  
  
    print(image.mode)  
  
    if "RGB" in mode:  
        output = "<svg width="%d" height="%d" viewBox="0 0 %d %d" xmlns="http://www.w3.org/2000/svg">" % (width, height, width, height)  
  
        for r in range(height):  
            for c in range(width):  
                color, opacity = convertPixel(*pixels[c, r])  
                output += "<rect x="%d" y="%d" width="1" height="1" fill="%s" fill-opacity="%s"/ >" % (c, r, color, opacity)  
  
        output += "</svg>"  
  
        with open(root + ".svg"."w") as f:  
            f.write(output)
Copy the code

Write a script and simply execute the script with the argument as the image name to generate an SVG image with the same name

python3 png_to_svg.py logo.png
Copy the code

Note that there is a pit here, when carrying out pixel vector conversion, the image mode only supports RGB three-color mode, take PNG as an example, if it is full color 24-bitmap is supported, but the 8-bit PNG image obviously cannot be converted, because its image mode is P mode, in this case, Before converting an image using a Python script, it is recommended to use Photoshop for a simple mode conversion

OK, after we have converted the image, we can open the image in SVG format with the editor

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"  
 width="255.000000 pt" height="200.000000 pt" viewBox="0 0 255.000000 200.000000"  
 preserveAspectRatio="xMidYMid meet">  
  
<g class="v3u-icon-group" transform="Translate (0.000000, 200.000000) scale (0.100000, 0.100000)"  
fill="#2b2b2b" stroke="none">  
<path class="v3u-icon1"   d="M1500 1950 c0 -27 -49 -39 -175 -45 -231 -10 -298 -27 -374 -91 -53 -44 -79 -119 -65 -190 l7 -35 31 29 c36 34 87 62 113 62 10 0-4-13-32-29-69-39-191-170-222-238-55-119 10-194 193-223 38-6 72-14 76-18 3-4 8-20 10-37 6-61 143-105 330-105 181 0 238 22 238 93 0 32-15 48-132 145-109 89-157 105-234 75-10-4-12 0-8 11 5 13-2 16-42 16-35 0-45 3-34 10 21 14 100 13 100-1 0-7 12-9 34-5 48 9 103-13 173-67 33-26 69-47 80-47 35 0 142 37 179 62 32 22 64 79 64 116 0 65 -53 147 -114 179 -108 56 -326 58 -436 4 l-25 -12 23 20 c84 73 382 68 478 -8 35 -28 47 -16 48 48 1 65-25 100-90 123-65 23-129 22-298-3-137-20-208-21-228-1 6 9 7 39 5 26-3 104 4 172 16 68 12 143 21 167 21 43 0 44 1 38 28 -11 43 -32 80 -53 92 -24 13 -31 13 -31 0z m-125 -784 c39 -17 45 -40 16 -56 -28 -15 -46 -13 -72 9 -23 19 -24 19 -5 40 23 25 18 24 61 7z"/>  
<path class="v3u-icon1" d="M1340 1146 c0 -14 5 -26 10 -26 6 0 10 9 10 19 0 11 -4 23 -10 26 -6 4 -10 -5 -10 -19z"/>  
  
<path class="v3u-icon1"  d="M45 738 c-20 -50 -29 -108 -16 -108 8 0 11 -44 11 -140 l0 -140 128 0 127 0 80 140 c43 77 85 140 92 140 12 0 25 36 39 108  l7 33 -98 -3 -98 -3 -18 -65 c-10 -36 -14 -66 -9 -68 8 -3 -39 -115 -54 -130 -3 -3 -6 20 -6 51 0 34 5 61 14 69 12 13 46 112 46 137 0 7 -38 11 -116 11 l-115 0 -14 -32z"/>  
<path class="v3u-icon1"  d="M626 760 c-37 -12 -66 -38 -82 -77 -27 -64 -23 -68 62 -65 65 3 77 6 81 23 6 23 23 25 23 3 0 -29 -21 -54 -44 -54 -16 0 -26 -7 -30 -22 -9 -35 -8 -38 20 -38 21 0 24 -4 20 -20 -3 -11 -9 -29 -12 -40 -9 -33 -26 -24 -19 10 l7 30 -85 0 -86 0 -12 -53 c-21 -97 6 -117 164 -117 77 0 110 4 137 18 43 21 76 69 85 123 6 33 3 45 -14 63 l-21 23 23 12 c32 17 47 45 54 100 5 43 3 50 -22 69 -24 19 -40 22 -124 21 -53 0 -109 -5 -125 -9z"/>  
<path class="v3u-icon1"  d="M970 746 c-22 -59 -31 -109 -21 -115 7 -5 2 -37 -14 -96 -29 -104 -32 -157 -9 -176 27 -22 114 -23 156 -1 30 16 38 17 42 6  4 -10 27 -14 88 -14 l83 0 17 63 c10 39 12 64 6 68 -13 9 20 130 41 147 16 13 52 128 43 137 -3 3 -47 5 -98 5 -79 0 -95 -3 -102-17-5-10-24-74-42-143-32-120-44-150-55-139-2 3 13 68 34 145 21 76 36 142 34 147-2 4-47 7-99 7-90 0 -95 -1 -104 -24z"/>  
<path class="v3u-icon1"  d="M1705 751 c-55 -25 -69 -50 -110 -198 -55 -200 -42 -217 159 -211 109 3 124 5 155 27 32 23 61 75 75 134 l6 27 -89 0 -90 0  -11 -40 c-6 -22 -15 -40 -20 -40 -14 0 -13 0 16 112 15 54 31 98 37 98 9 0 7 -23 -9 -84 l-6 -26 89 0 89 0 27 95 c15 52 27  102 27 110 0 23 -115 21 -128 -1 -9 -16 -11 -16 -33 0 -32 22 -132 21 -184 -3z"/>  
<path class="v3u-icon1"  d="M2101 747 c-23 -60 -32 -110 -22 -116 14 -9 -22 -139 -43 -155 -11 -8 -46 -102 -46 -123 0 -2 42 -3 93 -3 l94 0 12 41 c9 31 10 44 1 49 -8 5 -8 14 0 36 14 36 24 21 35 -50 11 -79 6 -76 114 -76 l97 0 16 62 c10 35 13 65 8 68 -13 8 20 132 40 150 9 8 24 41 33 73 19 70 20 69 -88 65 l-79 -3 -12 -47 c-7 -29 -8 -48 -2 -50 11 -4 0 -58 -12 -58 -5 0 -12 21 -15 48 -4 26 -10 61 -14 77 l-7 30 -97 3 c-95 3 -97 2 -106 -21z"/>  
<path class="v3u-icon1" d="M1377 473 c-3 -5 -10 -27 -17 -51 -6 -24 -14 -50 -17 -58 -4 -11 9 -14 74 -14 l79 0 14 53 c7 28 15 58 17 65 4 9 -14 12 -70 12 -42 0 -78 -3 -80 -7z"/>  
<path class="v3u-icon1" d="M1258 204 c-9 -8 3 -44 13 -38 11 7 12 44 1 44 -5 0 -11 -3 -14 -6z"/>  
<path d="M480 130 l0 -70 45 0 c33 0 45 4 45 15 0 9 -9 15 -25 15 -24 0 -25 3 -25 55 0 48 -2 55 -20 55 -18 0 -20 -7 -20 -70z"/>  
<path d="M600 130 c0 -56 3 -70 15 -70 12 0 15 14 15 70 0 56 -3 70 -15 70 -12 0 -15 -14 -15 -70z"/>  
<path d="M660 152 c0 -60 21 -92 60 -92 44 0 60 23 60 86 0 40 -4 54 -14 54 -11 0 -16 -15 -18 -52 -3 -45 -6 -53 -23 -53 -17 0 -20 8 -23 53 -3 44 -6 52 -23 52 -16 0 -19 -7 -19 -48z"/>  
<path d="M834 156 c14 -25 26 -56 26 -70 0 -19 5 -26 19 -26 14 0 18 5 14 20 -3 11 6 39 21 64 14 25 26 47 26 50 0 16 -27 3 -46 -21  l-22 -28 -13 28 c-7 16 -20 27 -32 27 -18 0 -17 -3 7 -44z"/>  
<path d="M970 147 c0 -61 19 -87 63 -87 41 0 57 24 57 86 0 40 -4 54 -14 54 -11 0 -16 -15 -18 -52 -3 -45 -6 -53 -23 -53 -17 0 -20 8 -23 53 -3 44 -6 52 -23 52 -16 0 -19 -7 -19 -53z"/>  
<path d="M1120 130 l0 -70 55 0 c42 0 55 3 55 15 0 11 -11 15 -40 15 -22 0 -40 5 -40 10 0 6 11 10 25 10 31 0 34 27 3 32 -41 6 -32 28 11 28 30 0 41 4 41 15 0 12 -13 15 -55 15 l-55 0 0 -70z"/>  
<path d="M1330 185 c-23 -28 -4 -56 55 -79 7 -2 7 -7 0 -14 -8 -8 -18 -7 -38 3 -25 13 -29 12 -34 -1 -8 -21 14 -34 58 -34 66 0 80 53 21 79 -40 18 -42 36 -3 28 20 -4 31 -2 34 8 11 26 -71 36 -93 10z"/>  
<path d="M1520 130 l0 -70 49 0 c30 0 53 5 61 15 13 16 5 55 -13 55 -8 0 -8 3 1 12 16 16 15 23 -4 42 -9 9 -32 16 -55 16 l-39 0 0 -70z m70 30 c0 -5 -9 -10 -20 -10 -11 0 -20 5 -20 10 0 6 9 10 20 10 11 0 20 -4 20 -10z m8 -62 c-7 -20 -48 -23 -48 -4 0 11  9 16 26 16 16 0 24 -5 22 -12z"/>  
<path d="M1660 130 l0 -70 51 0 c36 0 49 4 47 13 -3 6 -17 13 -31 15 -26 3 -27 6 -27 58 0 47 -2 54 -20 54 -18 0 -20 -7 -20 -70z"/>  
<path d="M1791 174 c-12 -15 -21 -34 -21 -44 0 -10 9 -29 21 -44 41 -52 129 -23 129 44 0 67 -88 96 -129 44z m89 -24 c22 -40 -26 -80 -58 -48 -25 25 -6 68 30 68 9 0 22 -9 28 -20z"/>  
<path d="M1970 180 c-43 -43 -11 -120 49 -120 49 0 61 9 61 46 0 30 -3 34 -25 34 -16 0 -25 -6 -25 -15 0 -8 5 -15 10 -15 6 0 10 -4 10 -10 0 -5 -11 -10 -25 -10 -32 0 -50 32 -34 61 9 17 17 20 45 16 36 -6 56 9 33 24 -25 16 -78 10 -99 -11z"/>  
</g>  
</svg>
Copy the code

As you can see, a complex PNG bitmap has been decomposed into n paths. These paths can be arbitrarily added with selectors, which can dynamically add cool animations to them.

Some people say, “I don’t know Python, is there any other way to convert an image?” The answer is yes, for example, Adobe Illustrator can manually outline an image path and convert it. There is also an online conversion platform called Convertio. co that can do similar operations.

After processing the image, we can use our imagination to add our favorite animation to the logo. How does Kwok sing? Move, move, move

It’s worth noting that SVG’s Path tag fully supports CSS3’s Transform animation, and the two work perfectly together

Using the Transform property, I can do some small effects, like I want the logo to hover in a different color and shift vertically

.v3u-icon-group{  
  
    pointer-events: fill;  
}  
  
.v3u-icon1 {  
      
  transition: 600ms all;  
}  
  
.v3u-icon-group:hover .v3u-icon1 {  
    
  transform:translateY(-100px);  
  fill: #4099ff;  
}
Copy the code

It works like this:

Does it feel cool, or do you want it to be thinner

.v3u-icon-group{  
  
    pointer-events: fill;  
}  
  
.v3u-icon1 {  
      
  transition: 600ms all;  
}  
  
.v3u-icon-group:hover .v3u-icon1 {  
    
  transform: rotateY(80deg);  
  fill: #4099ff;  
}
Copy the code

Or just want to flip over

.v3u-icon-group{  
  
    pointer-events: fill;  
}  
  
.v3u-icon1 {  
      
  transition: 600ms all;  
}  
  
.v3u-icon-group:hover .v3u-icon1 {  
    
  fill: #4099ff;  
  transform:rotate(45deg);  
}
Copy the code

Of course, these are relatively simple animations, and more interesting special effects still need to be combined and designed. It is worth mentioning that we use an interesting attribute: Pointer-events

Pointer-events is a property that both CSS and SVG have. It starts with auto and has the same effect as if the pointer-events attribute was not defined. The mouse does not penetrate the current layer. In SVG, this value has the same effect as visiblePainted. Bounding-box is a new attribute added to the SVG2.0 standard documentation. When bounding-box is configured, defined event interactions can also be received in the bounding rectangle surrounding the element, but browser support is not very good. So far only chrome65 + is supported. When pointer-events is None, the element is no longer the target of mouse events, and the mouse is no longer listening for the current layer but for elements in the layer below. However, if its child element has pointer-events set to another value, such as auto, the mouse will still listen for that child element. In other words, the mouse will prevent the hover element from triggering the animation twice during the execution of the animation motion, resulting in “shake”.

Conclusion: Using PYTHon3 combined with SVG can make your website more lively and interesting. Now browsers are getting better and better support for SVG. You can use pointer-Events with confidence and improve the interactive experience of SVG.

The original article is reprinted from liu Yue’s Technology blog v3u.cn/a_id_148