Brad Woods Digital Garden

Notes

The Warhammer 40k Adeptus Mechanicus symbol

    The Weighted Companion Cube from Aperture
    Bézier curve

    Planted: 

    Status: seed

    Hits: 8

    Intended Audience: Front-end developers

    Tech: SVG, clip-path, path, scroll

    While browsing Twitter I saw @rauno share something he was working on.

    It has an interesting effect that looks like lines are being drawn down the page as the user scrolls. I had a go at replicating this.

    clip-path

    I reproduced the effect using the SVG <clipPath> element. First we define a shape within the element (a rectangle in this example):

    /index.html

    <clip-path id="myClipPath">
    <rect x="0" y="0" width="200" height="100" />
    </clip-path>

    You can then apply the clipPath to any svg element (a line in this example):

    /index.html

    <line x1="0" y1="0" x2="0" y2="400" clip-path="url(#myClipPath)" />

    The clip-path will hide (clip) any part line that doesn't overlap. Our line goes from y: 0 to 400. The clip-path is a rectangle going from y: 0 to 200. Therefore, the bottom half of the line will be hidden.

    To create a line drawn on scroll effect, we render a line down the page. Then, use a clip-path to show only part of it. As the user scrolls, we translate the clip-path down the page. Gradually revealing more of the line. The example below uses four lines and two clip-paths:

    • a straight gray line that isn't clipped,
    • a straight dark-blue line and curving blue-purple line whose bottom is clipped and
    • a straight light-blue line that is clipped at the top and bottom.
    Check
    Check
    Check
    Check
    Check
    Check

    path

    The curving line adds an elegance to the design. It is made using an SVG path element. It has a d attribute that takes a series of commands to define its shape.

    <path
    d="
    M 200 0
    L 200 100
    c 0 60 60 60 60 120
    c 0 60 -60 60 -60 120
    L 200 400
    "
    />
    0040408080120120160160200200240240280280320320360360400400200 0200 1000 6060 6060 1200 60-60 60-60 120200 400

    M 200 0

    Move to the point x: 200, y: 0.

    L 200 100

    Draw a straight line from the current position (set above) to x: 200, y:100.

    c 0 60 -60 60 -60 120

    Draw a bezier curve with control points x: 0, y: 60 and x: -60, y:60. End the line at x: -60, y: 120. I'm using a lowercase letter for this command (c), while the previous two used uppercase (M and L). Uppercase means use absolute coordinates (C <x> <y>). Lower case means relative coordinates (c <dx> <dy>). Take our first control point for example c 0 60. This means from our current position (x: 200, y: 100), move across 0, down 60 and position the control point. It's absolute position will be x: 200 + 0, y: 100 + 60. If instead we used an uppercase letter, C 0 60. The absolute position the control point will be x: 0, y: 60. Regardless of our current position. Any command can use an uppercase or lowercase letter.

    c 0 60 60 60 60 120

    Draw another bezier curve.

    L 200 400

    Draw another straight line.

    Mixing absolute and relative coordinates

    A SVG's grid is normally defined using the viewBox attribute, viewBox="<x> <y> <width> <height>". Where <x> <y> define the top left coordinates. In this example, I don't set the viewBox. So its value defaults to viewBox="0 0 <width of SVG element> <height of SVG element>". Using this, I can easily find the middle of the SVG to start drawing the straight part of the line. Getting the coordinates of the curves is more difficult because the only information we get is the y-position of HTML elements with a target class name. Switching from absolute to relative coordinates makes this easier. See SVG viewBox for more details.

    linearGradient

    The path's stroke color is a gradient. Moving from left to right, purple, then blue, then back to purple. SVG gradients have a gradientUnits attribute with default value objectBoundingBox. This scales the gradient to the size of the element it's applied to. Meaning we only need use values of 0 and 1 to define the graident direction.

    /index.html

    <linearGradient
    id="myGradient"
    x1="0" y1="0"
    x2="1" y2="0"
    >
    <stop offset="0%" stop-color="#c380f7" />
    <stop offset="50%" stop-color="#446482" />
    <stop offset="100%" stop-color="#c380f7" />
    </linearGradient>

    Feedback

    Have any good or bad things to say about this note? Let me know...

    Subscribe

    Where to next?

    SVG
    Arrow pointing downYOU ARE HERE
    A sci-fi robot taxi driver with no lower body