How to draw a Penrose triangle which does not exist in the world with pure CSS

Keywords: Front-end github

Effect preview

Online demo

Press the "click preview" button on the right to preview on the current page, and click the link to preview in full screen.


https://codepen.io/comehope/pen/RyvgMZ


Interactive video tutorial


This video is interactive. You can pause the video at any time and edit the code in the video.


Please use chrome, safari, edge to open and watch.


https://scrimba.com/c/czPkasr


Source code download


Download locally

Please download all the source code of the daily front-end combat series from github:


https://github.com/comehope/front-end-daily-challenges


Code interpretation


Define dom, a container contains three < span >:

&lt;div class="penrose"&gt;
    &lt;span&gt;&lt;/span&gt;
    &lt;span&gt;&lt;/span&gt;
    &lt;span&gt;&lt;/span&gt;
&lt;/div&gt;

Center:

html,
body {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
}

Define container size:

.penrose {
    width: 20em;
    height: 20em;
}

Draw a container with 3 sides:

.penrose {
    position: relative;
}

.penrose span {
    position: absolute;
    width: 100%;
    height: 100%;
}

.penrose span:nth-child(1) {
    transform: rotate(0deg);
}

.penrose span:nth-child(2) {
    transform: rotate(120deg);
}

.penrose span:nth-child(3) {
    transform: rotate(240deg);
}

Color the container to which the 3 edges belong:

.penrose {
    color: red;
}

.penrose span {
    background-color: currentColor;
}

.penrose span:nth-child(1) {
    filter: brightness(1);
}

.penrose span:nth-child(2) {
    filter: brightness(0.66);
}

.penrose span:nth-child(3) {
    filter: brightness(0.33);
}

Use the mask to cut out each edge to form Penrose triangle:

.penrose span {
    clip-path: polygon(57% 0, 75% 0, 26% 85%, 89.5% 85%, 98.4% 100%, 0 100%);
}

.penrose span:nth-child(2) {
    top: 18.3%;
    left: 43.3%;
}

.penrose span:nth-child(3) {
    top: 46.5%;
    left: 5.9%;
}

Define the rotation Animation:

.penrose {
    animation: rotating 30s linear infinite;
    transform-origin: 66% 66%;
}

@keyframes rotating {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

Finally, increase the effect of discoloration during rotation:

@keyframes rotating {
    0% {
        color: red;
        transform: rotate(0deg);
    }

    20% {
        color: yellow;
    }

    40% {
        color: lime;
    }

    60% {
        color: blue;
    }

    80% {
        color: fuchsia;
    }

    100% {
        color: red;
        transform: rotate(720deg);
    }
}

be accomplished!

Original address: https://segmentfault.com/a/119000014946883

Posted by Illusionist on Wed, 04 Dec 2019 12:31:03 -0800