Small changes in Logo, big differences in mood, SVG vector animation format website Logo picture production and practice tutorial (Python 3)

Posted by richierich on Wed, 23 Feb 2022 17:06:16 +0100

The original text is reproduced from "Liu Yue's technology blog" https://v3u.cn/a_id_207

Once upon a time, SVG(Scalable Vector Graphics) vector animation was known as a technology cursed by browsers because of poor hardware support (IE) and endless compatibility tuning (Safari). However, today in 2022, everything is different. It is the so-called 30 years east and 30 years West. The Edge browser developed by Microsoft using the Chromium kernel as an alternative to IE is expected to surpass Safari and become the second largest desktop browser. Safari, once criticized for not supporting keyframe animation, has also unified the standard. In addition to the old dish ie on the market, Almost all platforms (including mobile terminals) have been friendly enough to SVG, which allows us to confidently and boldly apply SVG vector animation on the website.

At present, SVG vector format has been adopted by relatively advanced technology platforms at home and abroad, such as Netflix, a giant in online media, Twitter, a social platform, and station B in China:

In general, there are many advantages of using SVG format image. Because SVG image is a vector image, it can be scaled infinitely, and there is no problem in image quality degradation. Why? Because SVG images are built using XML tags, the browser prints them by drawing each point and line. This ensures that the SVG image can adapt to different screen sizes and resolutions. The traditional image format (such as PNG, GIF or JPG) fills the color space through predefined pixels, which leads to the impact of screen quality on the imaging quality of the image.

For example, the traditional pixel image is like the baked cake in the canteen. It is as big as it is. If the cake is not big enough, it will have an impact. While SVG defines the outline and technical parameters of the cake through XML technology, which is drawn in real time by the browser. It can adapt the size of the cake according to the size of the appetite and achieve the purpose of vector. At the same time, because it is defined in XML, SVG images are more flexible than JPG or PNG images, and we can interact with them using CSS and JavaScript. In addition, from the perspective of file volume, SVG is not larger than PNG, but smaller after compression. Finally, as a web page format of XML, it is directly parsed in the browser, so there is no need for separate bandwidth for requests, which saves the number of network requests and benefits without harm.

The next traditional program should introduce the basic syntax of SVG, then draw a few simple vector diagrams to show the characteristics of SVG. Finally, it's too boring. This time, let's order "fast food", simply and rudely convert the PNG Logo image directly into SVG format, and skip the step of "drawing", Let your website Logo "Wuhu take off" directly in five minutes.

SVG image conversion and compression

Take the Logo of our website as an example. First, we need a PNG vector diagram:

Note that the smaller the number of image color bits is, the better. In this way, the transformed image will not be too large. At the same time, the background should be transparent, because the transparent elements will not be marked by the XML file, so as to save space. Here we take the PNG imitation color 4-bit bitmap as an example.

There are many conversion methods, which can be through the third-party image library of Python 3:

pip3 install Pillow

Write the conversion script test py:

import sys  
import os  
import operator  
from collections import deque  
import io  
from optparse import OptionParser  
from PIL import Image  
  
  
def add_tuple(a, b):  
    return tuple(map(operator.add, a, b))  
  
  
def sub_tuple(a, b):  
    return tuple(map(operator.sub, a, b))  
  
  
def neg_tuple(a):  
    return tuple(map(operator.neg, a))  
  
  
def direction(edge):  
    return sub_tuple(edge[1], edge[0])  
  
  
def magnitude(a):  
    return int(pow(pow(a[0], 2) + pow(a[1], 2), .5))  
  
  
def normalize(a):  
    mag = magnitude(a)  
    assert mag > 0, "Cannot normalize a zero-length vector"  
    return tuple(map(operator.truediv, a, [mag] * len(a)))  
  
  
def svg_header(width, height):  
    return """<?xml version="1.0" encoding="UTF-8" standalone="no"?>  
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"   
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">  
<svg width="%d" height="%d"  
     xmlns="http://www.w3.org/2000/svg" version="1.1">  
""" % (width, height)  
  
  
def rgba_image_to_svg_pixels(im):  
    s = io.StringIO()  
    s.write(svg_header(*im.size))  
  
    width, height = im.size  
    for x in range(width):  
        for y in range(height):  
            here = (x, y)  
            rgba = im.getpixel(here)  
            if not rgba[3]:  
                continue  
            s.write(  
                """  <rect x="%d" y="%d" width="1" height="1" style="fill:rgb%s; fill-opacity:%.3f; stroke:none;" />\n"""  
                % (x, y, rgba[0:3], float(rgba[3]) / 255))  
        print("Converting pixels: " + str(x * 100 / width) + "%")  
    s.write("""</svg>\n""")  
    return s.getvalue()  
  
  
def joined_edges(assorted_edges, keep_every_point=False):  
    pieces = []  
    piece = []  
    directions = deque([  
        (0, 1),  
        (1, 0),  
        (0, -1),  
        (-1, 0),  
    ])  
    while assorted_edges:  
        if not piece:  
            piece.append(assorted_edges.pop())  
        current_direction = normalize(direction(piece[-1]))  
        while current_direction != directions[2]:  
            directions.rotate()  
        for i in range(1, 4):  
            next_end = add_tuple(piece[-1][1], directions[i])  
            next_edge = (piece[-1][1], next_end)  
            if next_edge in assorted_edges:  
                assorted_edges.remove(next_edge)  
                if i == 2 and not keep_every_point:  
                    # same direction  
                    piece[-1] = (piece[-1][0], next_edge[1])  
                else:  
                    piece.append(next_edge)  
                if piece[0][0] == piece[-1][1]:  
                    if not keep_every_point and normalize(direction(  
                            piece[0])) == normalize(direction(piece[-1])):  
                        piece[-1] = (piece[-1][0], piece.pop(0)[1])  
                        # same direction  
                    pieces.append(piece)  
                    piece = []  
                break  
        else:  
            raise Exception("Failed to find connecting edge")  
    return pieces  
  
  
def rgba_image_to_svg_contiguous(im, keep_every_point=False):  
  
    # collect contiguous pixel groups  
  
    adjacent = ((1, 0), (0, 1), (-1, 0), (0, -1))  
    visited = Image.new("1", im.size, 0)  
  
    color_pixel_lists = {}  
  
    width, height = im.size  
    for x in range(width):  
        for y in range(height):  
            here = (x, y)  
            if visited.getpixel(here):  
                continue  
            rgba = im.getpixel((x, y))  
            if not rgba[3]:  
                continue  
            piece = []  
            queue = [here]  
            visited.putpixel(here, 1)  
            while queue:  
                here = queue.pop()  
                for offset in adjacent:  
                    neighbour = add_tuple(here, offset)  
                    if not (0 <= neighbour[0] <  
                            width) or not (0 <= neighbour[1] < height):  
                        continue  
                    if visited.getpixel(neighbour):  
                        continue  
                    neighbour_rgba = im.getpixel(neighbour)  
                    if neighbour_rgba != rgba:  
                        continue  
                    queue.append(neighbour)  
                    visited.putpixel(neighbour, 1)  
                piece.append(here)  
  
            if not rgba in color_pixel_lists:  
                color_pixel_lists[rgba] = []  
            color_pixel_lists[rgba].append(piece)  
        print("Converting image: " + str(round(x * 100 / width, 2)) + "%")  
    del adjacent  
    del visited  
  
    # calculate clockwise edges of pixel groups  
  
    edges = {  
        (-1, 0): ((0, 0), (0, 1)),  
        (0, 1): ((0, 1), (1, 1)),  
        (1, 0): ((1, 1), (1, 0)),  
        (0, -1): ((1, 0), (0, 0)),  
    }  
  
    color_edge_lists = {}  
  
    counter = 0  
    for rgba, pieces in color_pixel_lists.items():  
        for piece_pixel_list in pieces:  
            edge_set = set([])  
            for coord in piece_pixel_list:  
                for offset, (start_offset, end_offset) in edges.items():  
                    neighbour = add_tuple(coord, offset)  
                    start = add_tuple(coord, start_offset)  
                    end = add_tuple(coord, end_offset)  
                    edge = (start, end)  
                    if neighbour in piece_pixel_list:  
                        continue  
                    edge_set.add(edge)  
            if not rgba in color_edge_lists:  
                color_edge_lists[rgba] = []  
            color_edge_lists[rgba].append(edge_set)  
        counter = counter + 1  
        print("Calculating edges: " +  
              str(round(counter * 100 / len(color_pixel_lists.items()), 2)) +  
              "%")  
    del color_pixel_lists  
    del edges  
  
    # join edges of pixel groups  
  
    color_joined_pieces = {}  
  
    for color, pieces in color_edge_lists.items():  
        color_joined_pieces[color] = []  
        for assorted_edges in pieces:  
            color_joined_pieces[color].append(  
                joined_edges(assorted_edges, keep_every_point))  
  
    s = io.StringIO()  
    s.write(svg_header(*im.size))  
  
    counter = 0  
    for color, shapes in color_joined_pieces.items():  
        for shape in shapes:  
            s.write(""" <path d=" """)  
            for sub_shape in shape:  
                here = sub_shape.pop(0)[0]  
                s.write(""" M %d,%d """ % here)  
                for edge in sub_shape:  
                    here = edge[0]  
                    s.write(""" L %d,%d """ % here)  
                s.write(""" Z """)  
            s.write(  
                """ " style="fill:rgb%s; fill-opacity:%.3f; stroke:none;" />\n"""  
                % (color[0:3], float(color[3]) / 255))  
        counter = counter + 1  
        print("Joining edges: " +  
              str(round(counter * 100 / len(color_joined_pieces.items()), 2)) +  
              "%")  
    s.write("""</svg>\n""")  
    return s.getvalue()  
  
  
def png_to_svg(filename, contiguous=None, keep_every_point=None):  
    try:  
        im = Image.open(filename)  
    except IOError as e:  
        sys.stderr.write('%s: Could not open as image file\n' % filename)  
        sys.exit(1)  
    im_rgba = im.convert('RGBA')  
  
    if contiguous:  
        return rgba_image_to_svg_contiguous(im_rgba, keep_every_point)  
    else:  
        return rgba_image_to_svg_pixels(im_rgba)  
  
  
if __name__ == "__main__":  
    parser = OptionParser()  
    parser.add_option(  
        "-p",  
        "--pixels",  
        action="store_false",  
        dest="contiguous",  
        help=  
        "Generate a separate shape for each pixel; do not group pixels into contiguous areas of the same colour",  
        default=True)  
    parser.add_option(  
        "-1",  
        "--one",  
        action="store_true",  
        dest="keep_every_point",  
        help=  
        "1-pixel-width edges on contiguous shapes; default is to remove intermediate points on straight line edges. ",  
        default=None)  
    (options, args) = parser.parse_args()  
  
if (len(sys.argv)) < 2:  
    for file in os.listdir("."):  
        if file.endswith(".png"):  
            print("Converting " + file)  
            f = open(file.replace(".png", ".svg"), 'w')  
            f.write(  
                png_to_svg(file,  
                           contiguous=options.contiguous,  
                           keep_every_point=options.keep_every_point))  
else:  
    for file in sys.argv:  
        if file.endswith(".png"):  
            print("Converting " + file)  
            f = open(file.replace(".png", ".svg"), 'w')  
            f.write(  
                png_to_svg(file,  
                           contiguous=options.contiguous,  
                           keep_every_point=options.keep_every_point))

Run script file:

python3 test.py test.png

Test with the same name will be directly generated svg file, open with vscode (install svg preview control):

The principle is to traverse the pixels of the original bitmap and convert them into the path format of SVG. Each bitmap element block will be a separate path label. If there is no need to operate on a single element block, it can also be combined into a path label.

Next, compress the converted svg file, and the compressed volume will be reduced accordingly. At the same time, some path s can also be merged. Install the compression software svgo:

npm install -g svgo

Execute the compression command, test SVG is the source file, my SVG is a compressed file:

svgo test.svg -o my.svg

Get the compressed svg:

<svg xmlns="http://www.w3.org/2000/svg" width="250"  viewBox="0 0 400 313.725">  
   
    <path  d="M231.828 11.305c-3.763 2.949-7.266 3.479-30.517 4.623-46.344 2.278-61.703 11.6-61.703 37.45v9.581l4.839-3.636c7.122-5.353 14.345-8.975 17.906-8.982 2.225-.005 1.454.883-2.652 3.051-8.485 4.482-31.488 27.939-35.476 36.176-9.856 20.362.264 32.59 30.95 37.395 10.341 1.619 13.209 3.617 11.781 8.208-5.166 16.617 80.367 23.977 87.191 7.503 2.614-6.311.889-11.626-5.131-15.81-2.802-1.948-9.967-7.7-15.923-12.784-14.324-12.226-19.669-14.14-31.915-11.43-4.296.951-4.944.731-4.127-1.399.812-2.117-.114-2.455-5.715-2.085-9.411.622-9.816-2.778-.483-4.057 5.39-.739 8.043-.415 9.634 1.176 1.428 1.428 4.214 1.925 7.969 1.421 7.532-1.01 14.472 2.028 25.819 11.301l9.177 7.5 8.078-1.812c24.986-5.605 33.798-15.992 30.135-35.52-4.175-22.251-53.429-34.124-83.234-20.063l-4.706 2.22 3.717-3.226c13.698-11.889 56.459-11.57 74.326.555 6.558 4.45 7.448 3.51 7.448-7.864 0-18.854-18.5-23.967-61.832-17.088-17.292 2.744-31.119 2.595-34.083-.369-1.105-1.105.531-1.381 5.19-.876 3.742.405 15.189-.734 25.438-2.531 10.249-1.796 22.072-3.266 26.274-3.266 9.076 0 10.213-3.562 4.056-12.699-4.358-6.466-6.887-7.008-12.431-2.663M215.737 130.9c6.031 2.521 7.046 6.169 2.405 8.653-7.504 4.016-17.052-2.06-12.003-7.639 3.538-3.909 2.844-3.836 9.598-1.014m-5.541 3.125c0 2.208.706 4.014 1.569 4.014.862 0 1.568-1.37 1.568-3.044 0-1.675-.706-3.481-1.568-4.015-.89-.549-1.569.768-1.569 3.045M5.839 203.529c-1.456 5.21-1.896 9.241-1.042 9.543.832.294 1.478 10.421 1.478 23.184v22.661l19.933-.439 19.933-.439 12.084-21.096c6.647-11.602 13.134-21.863 14.416-22.8 1.765-1.29 7.359-15.836 7.359-19.134 0-.274-6.686-.499-14.858-.499H50.284l-2.439 8.389c-1.342 4.614-2.02 9.482-1.508 10.817 1.026 2.672-8.309 22.482-9.862 20.929-1.831-1.831-.255-18.929 1.898-20.591 1.163-.899 2.926-4.649 3.918-8.334.992-3.685 2.194-7.715 2.67-8.955.722-1.883-2.223-2.255-17.868-2.255H8.359l-2.52 9.019m88.643-7.092c-4.02 1.937-8.873 9.28-10.389 15.72l-1.016 4.314h11.689c10.312 0 11.807-.37 12.685-3.138.995-3.134 2.585-3.951 4.316-2.219 2.318 2.317-2.36 10.062-6.077 10.062-2.643 0-4.275 1.231-5.337 4.024-2.064 5.43-2.083 5.388 2.517 5.388 3.889 0 4.479 5.745 1.167 11.373-1.871 3.178-3.952.753-3.083-3.593l.954-4.769-12.746.456-12.746.455-2.07 7.024c-4.424 15.015-1.162 17.292 24.767 17.284 26.011-.008 31.009-3.079 34.928-21.461.834-3.908.349-5.713-2.228-8.289l-3.294-3.294 5.343-5.044c6.691-6.316 8.977-16.391 5.072-22.35-2.821-4.306-36.497-5.778-44.452-1.943m55.95 7.444c-1.607 6.168-1.884 9.557-.81 9.915 1.024.341.046 6.455-2.623 16.408-4.903 18.284-5.207 22.736-1.789 26.155 3.537 3.536 22.107 3.427 26.064-.154 2.704-2.447 3.022-2.443 4.861.072 1.629 2.228 4.114 2.611 14.418 2.227l12.45-.465 2.273-9.33c1.484-6.092 1.716-9.516.668-9.865-2.218-.739 4.443-23.327 7.629-25.87 1.985-1.585 6.035-13.389 6.035-17.59 0-.481-6.896-.874-15.325-.874h-15.324l-3.73 13.725c-6.592 24.261-9.634 33.334-11.174 33.334-2.44 0-1.81-3.858 3.984-24.422 3.02-10.717 5.49-20.194 5.49-21.061 0-.948-6.105-1.576-15.327-1.576h-15.328l-2.442 9.371m112.181-4.261c-4.796 4.396-6.336 7.744-11.004 23.922-9.813 34.013-9.05 35.284 21.183 35.276 27.768-.008 33.534-3.39 37.222-21.83l.966-4.831h-26.969l-1.293 4.991c-1.424 5.496-5.081 7.938-5.054 3.375.009-1.582 1.088-6.405 2.397-10.719 1.309-4.314 3.093-10.49 3.965-13.726.914-3.391 2.556-5.882 3.878-5.882 2.679 0 2.718.208.953 4.996-.736 1.997-1.816 5.6-2.398 8.007l-1.06 4.375 13.715-.453 13.714-.454 3.341-11.765c1.839-6.471 3.819-13.706 4.401-16.078l1.058-4.314h-10.226c-8.044 0-10.226.502-10.226 2.353 0 1.294-.403 2.353-.896 2.353s-1.955-1.059-3.249-2.353c-5.034-5.034-27.917-3.201-34.418 2.757m65.074 4.261c-1.504 5.773-1.848 9.568-.897 9.885 2.306.769-3.529 22.871-6.473 24.519-1.361.762-3.653 5.694-5.095 10.961l-2.622 9.578h28.713l1.774-6.648c1.148-4.3 1.23-6.983.233-7.6-2.082-1.286.12-9.573 2.347-8.831.969.323 2.74 5.673 3.936 11.887l2.173 11.3 14.88-.446 14.881-.447 2.753-8.909c1.836-5.941 2.231-9.433 1.185-10.479-2.066-2.065 3.146-22.253 6.434-24.924 1.326-1.077 3.613-5.842 5.082-10.588l2.669-8.629h-27.769l-1.965 6.556c-1.45 4.842-1.497 6.711-.176 7.151 1.288.43 1.338 1.883.179 5.209-2.181 6.257-4.094 5.799-5.3-1.269-.553-3.235-1.671-8.53-2.485-11.765l-1.481-5.882h-30.534l-2.442 9.371m-112.089 36.903c-.261.863-1.513 5.303-2.784 9.867l-2.311 8.299 11.835-.455 11.835-.456 2.105-7.059c3.515-11.782 3.528-11.764-9.027-11.764-6.149 0-11.393.706-11.653 1.568m-17.951 42.353c0 1.294.706 2.353 1.569 2.353.862 0 1.568-1.059 1.568-2.353 0-1.294-.706-2.353-1.568-2.353-.863 0-1.569 1.059-1.569 2.353m-121.274.229c-.594.593-1.079 5.549-1.079 11.013v9.935h7.059c4.716 0 7.059-.671 7.059-2.023 0-1.176-1.806-1.997-4.314-1.961-4.168.06-4.319-.227-4.465-8.485-.14-7.955-1.693-11.046-4.26-8.479m17.745 9.967c0 8.715.485 10.981 2.353 10.981 1.867 0 2.353-2.266 2.353-10.981 0-8.714-.486-10.98-2.353-10.98-1.868 0-2.353 2.266-2.353 10.98m9.411-3.137c0 12.177 9.456 18.732 16.228 11.249 3.493-3.859 3.687-19.092.243-19.092-1.765 0-2.353 1.882-2.353 7.529 0 8.705-2.181 11.917-6.515 9.597-2.219-1.188-2.897-3.371-2.897-9.338 0-5.877-.577-7.788-2.353-7.788-1.777 0-2.353 1.917-2.353 7.843m27.432-1.6c2.167 3.434 3.941 8.375 3.941 10.981 0 3.165.781 4.737 2.353 4.737 1.525 0 2.353-1.528 2.353-4.342 0-2.388 1.765-6.939 3.921-10.113 4.579-6.738 4.736-7.506 1.535-7.506-1.312 0-3.19 1.765-4.173 3.922-.983 2.156-2.298 3.921-2.923 3.921s-2.293-1.765-3.706-3.921c-1.413-2.157-3.621-3.922-4.906-3.922-1.801 0-1.433 1.431 1.605 6.243m21.542 2.619c1.015 12.236 9.26 17.547 15.881 10.23 3.493-3.859 3.687-19.092.243-19.092-1.764 0-2.352 1.882-2.352 7.529 0 8.705-2.181 11.917-6.515 9.597-2.22-1.188-2.897-3.371-2.897-9.338 0-6.141-.539-7.788-2.547-7.788-2.137 0-2.429 1.428-1.813 8.862m23.183 2.036v11.063h7.843c5.261 0 7.844-.651 7.844-1.976 0-1.184-2.029-1.97-5.059-1.961-3.572.011-5.22-.792-5.605-2.73-.407-2.045.483-2.745 3.49-2.745 2.22 0 4.036-.706 4.036-1.569 0-.862-1.764-1.568-3.921-1.568-6.549 0-4.808-4.443 1.961-5.004 8.742-.723 7.117-3.553-2.353-4.098l-8.236-.474v11.062m33.855-8.834c-4.079 2.983-2.494 7.781 3.433 10.39 7.54 3.318 4.217 7.372-3.798 4.633-.992-.339-2.051.072-2.352.914-.825 2.3 7.059 4.556 11.779 3.371 5.827-1.463 6.039-9.856.285-11.3-2.122-.532-4.672-1.949-5.667-3.149-2.507-3.02 1.892-4.623 6.264-2.283 2.594 1.388 3.26 1.287 3.26-.495 0-4.216-8.461-5.549-13.204-2.081m28.89 8.916v10.981h6.147c9.758 0 15.815-6.318 9.687-10.105-.782-.483-1.025-2.395-.54-4.249 1.136-4.346-3.195-7.607-10.103-7.607h-5.191v10.98m23.53 0v10.981h6.274c4.076 0 6.275-.709 6.275-2.023 0-1.176-1.806-1.997-4.314-1.961-4.159.06-4.33-.26-4.784-8.957-.668-12.8-3.451-11.219-3.451 1.96m20.304-8.087c-2.416 1.956-3.572 4.574-3.572 8.087 0 9.948 12.212 14.654 19.073 7.35 9.723-10.35-4.406-24.421-15.501-15.437m26.868 1.24c-7.54 9.587 1.045 20.207 13.612 16.839 4.862-1.303 5.249-11.163.424-10.807-4.346.32-5.861 2.278-3.124 4.038 2.027 1.303 2.022 1.667-.036 2.989-3.051 1.96-8.465-1.512-9.118-5.848-.677-4.496 5.425-8.61 9.52-6.418 3.969 2.124 7.98-1.06 4.282-3.399-4.707-2.976-12.149-1.729-15.56 2.606m-15.121 2.025c5.815 6.425-2.308 15.742-8.407 9.643-4.05-4.05-4.068-5.573-.115-9.527 3.899-3.898 5.085-3.915 8.522-.116m-44.6.901c0 1.307-1.395 2.353-3.137 2.353-1.743 0-3.138-1.046-3.138-2.353 0-1.307 1.395-2.353 3.138-2.353 1.742 0 3.137 1.046 3.137 2.353m1.363 7.595c2.196 2.647.744 4.169-3.978 4.169-2.614 0-3.66-.896-3.66-3.137 0-3.647 4.916-4.311 7.638-1.032" />  
  
</svg>

Here, we combine multiple path paths into one. If you don't want to use the local code script for conversion and compression, you can also use the online corresponding network tools to convert svg: https://www.pngtosvg.com/ Compress svg: https://jakearchibald.github....

The effect of online transformation is similar to that of local transformation.

SVG interaction effect

In fact, the above code can be directly used by directly putting it into the page. Here, the display area of svg picture is calibrated by specifying the four coordinates in the viewBox attribute of svg, that is, the "canvas" we understand, and then the proportional expansion and reduction are realized by controlling the width attribute. It is very convenient. The effect is as follows:

Except that the resolution can adapt to the screen and appear more fine, there seems to be no difference between other places and traditional png? Let's make a difference. svg can realize "animation" special effects through css style, such as stroke:

<svg xmlns="http://www.w3.org/2000/svg" width="250"  viewBox="0 0 400 313.725">  
   
    <path  class="path" stroke-opacity="0.2" stroke-width="7" stroke="black"   d="M231.828 11.305c-3.763 2.949-7.266 3.479-30.517 4.623-46.344 2.278-61.703 11.6-61.703 37.45v9.581l4.839-3.636c7.122-5.353 14.345-8.975 17.906-8.982 2.225-.005 1.454.883-2.652 3.051-8.485 4.482-31.488 27.939-35.476 36.176-9.856 20.362.264 32.59 30.95 37.395 10.341 1.619 13.209 3.617 11.781 8.208-5.166 16.617 80.367 23.977 87.191 7.503 2.614-6.311.889-11.626-5.131-15.81-2.802-1.948-9.967-7.7-15.923-12.784-14.324-12.226-19.669-14.14-31.915-11.43-4.296.951-4.944.731-4.127-1.399.812-2.117-.114-2.455-5.715-2.085-9.411.622-9.816-2.778-.483-4.057 5.39-.739 8.043-.415 9.634 1.176 1.428 1.428 4.214 1.925 7.969 1.421 7.532-1.01 14.472 2.028 25.819 11.301l9.177 7.5 8.078-1.812c24.986-5.605 33.798-15.992 30.135-35.52-4.175-22.251-53.429-34.124-83.234-20.063l-4.706 2.22 3.717-3.226c13.698-11.889 56.459-11.57 74.326.555 6.558 4.45 7.448 3.51 7.448-7.864 0-18.854-18.5-23.967-61.832-17.088-17.292 2.744-31.119 2.595-34.083-.369-1.105-1.105.531-1.381 5.19-.876 3.742.405 15.189-.734 25.438-2.531 10.249-1.796 22.072-3.266 26.274-3.266 9.076 0 10.213-3.562 4.056-12.699-4.358-6.466-6.887-7.008-12.431-2.663M215.737 130.9c6.031 2.521 7.046 6.169 2.405 8.653-7.504 4.016-17.052-2.06-12.003-7.639 3.538-3.909 2.844-3.836 9.598-1.014m-5.541 3.125c0 2.208.706 4.014 1.569 4.014.862 0 1.568-1.37 1.568-3.044 0-1.675-.706-3.481-1.568-4.015-.89-.549-1.569.768-1.569 3.045M5.839 203.529c-1.456 5.21-1.896 9.241-1.042 9.543.832.294 1.478 10.421 1.478 23.184v22.661l19.933-.439 19.933-.439 12.084-21.096c6.647-11.602 13.134-21.863 14.416-22.8 1.765-1.29 7.359-15.836 7.359-19.134 0-.274-6.686-.499-14.858-.499H50.284l-2.439 8.389c-1.342 4.614-2.02 9.482-1.508 10.817 1.026 2.672-8.309 22.482-9.862 20.929-1.831-1.831-.255-18.929 1.898-20.591 1.163-.899 2.926-4.649 3.918-8.334.992-3.685 2.194-7.715 2.67-8.955.722-1.883-2.223-2.255-17.868-2.255H8.359l-2.52 9.019m88.643-7.092c-4.02 1.937-8.873 9.28-10.389 15.72l-1.016 4.314h11.689c10.312 0 11.807-.37 12.685-3.138.995-3.134 2.585-3.951 4.316-2.219 2.318 2.317-2.36 10.062-6.077 10.062-2.643 0-4.275 1.231-5.337 4.024-2.064 5.43-2.083 5.388 2.517 5.388 3.889 0 4.479 5.745 1.167 11.373-1.871 3.178-3.952.753-3.083-3.593l.954-4.769-12.746.456-12.746.455-2.07 7.024c-4.424 15.015-1.162 17.292 24.767 17.284 26.011-.008 31.009-3.079 34.928-21.461.834-3.908.349-5.713-2.228-8.289l-3.294-3.294 5.343-5.044c6.691-6.316 8.977-16.391 5.072-22.35-2.821-4.306-36.497-5.778-44.452-1.943m55.95 7.444c-1.607 6.168-1.884 9.557-.81 9.915 1.024.341.046 6.455-2.623 16.408-4.903 18.284-5.207 22.736-1.789 26.155 3.537 3.536 22.107 3.427 26.064-.154 2.704-2.447 3.022-2.443 4.861.072 1.629 2.228 4.114 2.611 14.418 2.227l12.45-.465 2.273-9.33c1.484-6.092 1.716-9.516.668-9.865-2.218-.739 4.443-23.327 7.629-25.87 1.985-1.585 6.035-13.389 6.035-17.59 0-.481-6.896-.874-15.325-.874h-15.324l-3.73 13.725c-6.592 24.261-9.634 33.334-11.174 33.334-2.44 0-1.81-3.858 3.984-24.422 3.02-10.717 5.49-20.194 5.49-21.061 0-.948-6.105-1.576-15.327-1.576h-15.328l-2.442 9.371m112.181-4.261c-4.796 4.396-6.336 7.744-11.004 23.922-9.813 34.013-9.05 35.284 21.183 35.276 27.768-.008 33.534-3.39 37.222-21.83l.966-4.831h-26.969l-1.293 4.991c-1.424 5.496-5.081 7.938-5.054 3.375.009-1.582 1.088-6.405 2.397-10.719 1.309-4.314 3.093-10.49 3.965-13.726.914-3.391 2.556-5.882 3.878-5.882 2.679 0 2.718.208.953 4.996-.736 1.997-1.816 5.6-2.398 8.007l-1.06 4.375 13.715-.453 13.714-.454 3.341-11.765c1.839-6.471 3.819-13.706 4.401-16.078l1.058-4.314h-10.226c-8.044 0-10.226.502-10.226 2.353 0 1.294-.403 2.353-.896 2.353s-1.955-1.059-3.249-2.353c-5.034-5.034-27.917-3.201-34.418 2.757m65.074 4.261c-1.504 5.773-1.848 9.568-.897 9.885 2.306.769-3.529 22.871-6.473 24.519-1.361.762-3.653 5.694-5.095 10.961l-2.622 9.578h28.713l1.774-6.648c1.148-4.3 1.23-6.983.233-7.6-2.082-1.286.12-9.573 2.347-8.831.969.323 2.74 5.673 3.936 11.887l2.173 11.3 14.88-.446 14.881-.447 2.753-8.909c1.836-5.941 2.231-9.433 1.185-10.479-2.066-2.065 3.146-22.253 6.434-24.924 1.326-1.077 3.613-5.842 5.082-10.588l2.669-8.629h-27.769l-1.965 6.556c-1.45 4.842-1.497 6.711-.176 7.151 1.288.43 1.338 1.883.179 5.209-2.181 6.257-4.094 5.799-5.3-1.269-.553-3.235-1.671-8.53-2.485-11.765l-1.481-5.882h-30.534l-2.442 9.371m-112.089 36.903c-.261.863-1.513 5.303-2.784 9.867l-2.311 8.299 11.835-.455 11.835-.456 2.105-7.059c3.515-11.782 3.528-11.764-9.027-11.764-6.149 0-11.393.706-11.653 1.568m-17.951 42.353c0 1.294.706 2.353 1.569 2.353.862 0 1.568-1.059 1.568-2.353 0-1.294-.706-2.353-1.568-2.353-.863 0-1.569 1.059-1.569 2.353m-121.274.229c-.594.593-1.079 5.549-1.079 11.013v9.935h7.059c4.716 0 7.059-.671 7.059-2.023 0-1.176-1.806-1.997-4.314-1.961-4.168.06-4.319-.227-4.465-8.485-.14-7.955-1.693-11.046-4.26-8.479m17.745 9.967c0 8.715.485 10.981 2.353 10.981 1.867 0 2.353-2.266 2.353-10.981 0-8.714-.486-10.98-2.353-10.98-1.868 0-2.353 2.266-2.353 10.98m9.411-3.137c0 12.177 9.456 18.732 16.228 11.249 3.493-3.859 3.687-19.092.243-19.092-1.765 0-2.353 1.882-2.353 7.529 0 8.705-2.181 11.917-6.515 9.597-2.219-1.188-2.897-3.371-2.897-9.338 0-5.877-.577-7.788-2.353-7.788-1.777 0-2.353 1.917-2.353 7.843m27.432-1.6c2.167 3.434 3.941 8.375 3.941 10.981 0 3.165.781 4.737 2.353 4.737 1.525 0 2.353-1.528 2.353-4.342 0-2.388 1.765-6.939 3.921-10.113 4.579-6.738 4.736-7.506 1.535-7.506-1.312 0-3.19 1.765-4.173 3.922-.983 2.156-2.298 3.921-2.923 3.921s-2.293-1.765-3.706-3.921c-1.413-2.157-3.621-3.922-4.906-3.922-1.801 0-1.433 1.431 1.605 6.243m21.542 2.619c1.015 12.236 9.26 17.547 15.881 10.23 3.493-3.859 3.687-19.092.243-19.092-1.764 0-2.352 1.882-2.352 7.529 0 8.705-2.181 11.917-6.515 9.597-2.22-1.188-2.897-3.371-2.897-9.338 0-6.141-.539-7.788-2.547-7.788-2.137 0-2.429 1.428-1.813 8.862m23.183 2.036v11.063h7.843c5.261 0 7.844-.651 7.844-1.976 0-1.184-2.029-1.97-5.059-1.961-3.572.011-5.22-.792-5.605-2.73-.407-2.045.483-2.745 3.49-2.745 2.22 0 4.036-.706 4.036-1.569 0-.862-1.764-1.568-3.921-1.568-6.549 0-4.808-4.443 1.961-5.004 8.742-.723 7.117-3.553-2.353-4.098l-8.236-.474v11.062m33.855-8.834c-4.079 2.983-2.494 7.781 3.433 10.39 7.54 3.318 4.217 7.372-3.798 4.633-.992-.339-2.051.072-2.352.914-.825 2.3 7.059 4.556 11.779 3.371 5.827-1.463 6.039-9.856.285-11.3-2.122-.532-4.672-1.949-5.667-3.149-2.507-3.02 1.892-4.623 6.264-2.283 2.594 1.388 3.26 1.287 3.26-.495 0-4.216-8.461-5.549-13.204-2.081m28.89 8.916v10.981h6.147c9.758 0 15.815-6.318 9.687-10.105-.782-.483-1.025-2.395-.54-4.249 1.136-4.346-3.195-7.607-10.103-7.607h-5.191v10.98m23.53 0v10.981h6.274c4.076 0 6.275-.709 6.275-2.023 0-1.176-1.806-1.997-4.314-1.961-4.159.06-4.33-.26-4.784-8.957-.668-12.8-3.451-11.219-3.451 1.96m20.304-8.087c-2.416 1.956-3.572 4.574-3.572 8.087 0 9.948 12.212 14.654 19.073 7.35 9.723-10.35-4.406-24.421-15.501-15.437m26.868 1.24c-7.54 9.587 1.045 20.207 13.612 16.839 4.862-1.303 5.249-11.163.424-10.807-4.346.32-5.861 2.278-3.124 4.038 2.027 1.303 2.022 1.667-.036 2.989-3.051 1.96-8.465-1.512-9.118-5.848-.677-4.496 5.425-8.61 9.52-6.418 3.969 2.124 7.98-1.06 4.282-3.399-4.707-2.976-12.149-1.729-15.56 2.606m-15.121 2.025c5.815 6.425-2.308 15.742-8.407 9.643-4.05-4.05-4.068-5.573-.115-9.527 3.899-3.898 5.085-3.915 8.522-.116m-44.6.901c0 1.307-1.395 2.353-3.137 2.353-1.743 0-3.138-1.046-3.138-2.353 0-1.307 1.395-2.353 3.138-2.353 1.742 0 3.137 1.046 3.137 2.353m1.363 7.595c2.196 2.647.744 4.169-3.978 4.169-2.614 0-3.66-.896-3.66-3.137 0-3.647 4.916-4.311 7.638-1.032" />  
  
</svg>

Here, we add a pseudo class to the path attribute, and add an outer border to the logo through the stroke attribute, with a transparency of 0.2 and a width of 7 pixels. Then, write the key frame animation:

@keyframes pinap {  
  to {  
    stroke-dashoffset: 0;  
  }  
  0% {fill-opacity: 0; }  
   
    100% {fill-opacity: 1;    filter: drop-shadow(0px 0px 2px var(--logo-color));}   
  
}

When the page is loaded, specify the stroke dasharray attribute to traverse the stroked path, and increase the color transparency of the logo ontology from 0 to 1:

If you feel that you are not satisfied, you can use the hover attribute to trigger the special effect again when hovering the Logo:

path.path:hover{  
stroke-dasharray: 1000;  
  stroke-dashoffset: 1000;  
  animation: dash 3s linear forwards;  
  /* fill:white; */  
  fill-opacity: 1;  
}

Remember the previous experiment on the website "dark mode"? Use CSS3 custom properties to add "dark mode" (dark mode / DarkMode) to the website At that time, we used custom attributes to switch the dark mode while switching another dark Logo to achieve the effect of brightness and darkness. The cost is to use one light and one dark picture together. Now, there is no need for redundant pictures, just by simply defining the color:

:root{--logo-color:#2b2b2b}  
  
path.path{  
    fill:var(--logo-color);  
}

svg's fill attribute can directly render the picture color:

Simple and convenient, what are you waiting for? Abandon the outdated PNG.

With the filter, you can also create neon light effects:

filter: drop-shadow(0px 0px 2px var(--logo-color));

Conclusion: "in the old days, Wang Xietang and Qianyan flew into the homes of ordinary people". By eliminating backward production capacity, increasing large production capacity and reducing small production capacity, and strengthening technological innovation, we can use SVG Technology to create an image display scheme with lower cost and higher scalability. Why not? Finally, I would like to present the address of the demonstration project: https://github.com/zcxey2911/svg \_ website\_logo, Bojun, a sun.

The original text is reproduced from "Liu Yue's technology blog" https://v3u.cn/a_id_207

Topics: Front-end svg