How could you make a pacman by moving your mouth with pure CSS?

16

In order to delve deeper into CSS, I would like to know different ways to make animations. My goal is to know some new properties and features that CSS has been implementing.

In the specific case, I would like to know what would be the simplest way to make a Pacman by mouth.

I have a small sketch of what I could learn from SVG and CSS:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <style>
        .circle {
        stroke-dasharray: 151, 158;
        animation: packman .4s infinite ease;
        stroke-width: 50;
        stroke: yellow;
        fill: transparent;
        }

        @keyframes packman{
        
        from {
            stroke-dasharray: 151, 158;
        }
        
        to {
            stroke-dasharray: 158, 158;
        }
        
        }
    </style>
    <circle r='25' cy='50' cx='50' class="circle"></circle>
</svg>

How could I, in other ways, do this animation above?

Note : Not a request for help for something real, but just for learning

    
asked by anonymous 02.08.2018 / 21:23

2 answers

14

In HTML you can think of creating 3 elements:

  • The third element will be the main element, which receives the pseudo elements

The pseudo elements ::before and ::after will be the "body", since the main element will be what will adjust the position of the sub (pseudo) -elements

The ::before will be the bottom and will receive ::after to turn a circle, with ::after we make it only half filled.

% will be the top, it's identical, you could simply reverse the order of the colors in border-radius: 100% , but I personally find it much more practical to do this using linear-gradient that will become the leading element (I understand that you can rotate in different ways, but the effect is the same at the end):

The static example with no animation to see the body ready:

body {
    background: black;
}

/* todos elementos devem ter a mesma altura, a não ser que queira aplicar margens */
.pacman-css, .pacman-css::before, .pacman-css::after {
    width: 100px;
    height: 100px;
}

.pacman-css {
     position: relative;
}

.pacman-css::before, .pacman-css::after {
    content: "";
    display: block;

    /*posiciona ambos elementos no mesmo lugar*/
    position: absolute;
    top: 0;
    left: 0;

    /* aplica a borda para transformar em um circulo */
    border-radius: 100%;

    background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,
                                           rgba(0,0,0,0) 50%,
                                           yellow 50%);
    /*Aplica o amarelo do 50% até o 100%, ou seja NÃO é necessário aplicar yellow 100% depois */
}

/* o before deve ser a de cima */
.pacman-css::before {
     transform: rotate(180deg);
}
<div class="pacman-css">
</div>

Now, we have the base of our pacman, the second part is to apply the animation, but for this we need to create an animation for the top and the other for the bottom.

The ::before will normally animate from the rotation linear-gradient to the desired rotation (in the example I applied transform: rotate(180deg); but you can change it) and then return to ::before (I know you can adjust the return in the 0deg itself, but the effect is the same and is for didactic purposes, suggestions comment)

The 30deg will animate the bottom, so it will start from 0deg and you can apply the lower value so that the bottom does the reverse rotation, in the example I used animate , you can adjust that too.

You can also change the movement of the bottom or the top, you can also apply different speeds, changing ::after of each 180deg , it is at your discretion, the example is simple and totally customizable:

body {
    background: black;
}

.pacman-css, .pacman-css::before, .pacman-css::after {
    width: 100px;
    height: 100px;
}

.pacman-css {
     position: relative;
}

.pacman-css::before, .pacman-css::after {
    content: "";
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 100%;
    background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,
                                           rgba(0,0,0,0) 50%,
                                           yellow 50%);
}

.pacman-css::before {
     transform: rotate(180deg);
     animation: anima-pacman-cima .5s infinite;
}

.pacman-css::after {
     animation: anima-pacman-baixo .5s infinite;
}

@keyframes anima-pacman-cima
{
    0%   { transform: rotate(180deg); }
    50%  { transform: rotate(150deg); }
    100% { transform: rotate(180deg); }
}

@keyframes anima-pacman-baixo
{
    0%   { transform: rotate(0deg);  }
    50%  { transform: rotate(30deg); }
    100% { transform: rotate(0deg);  }
}
<div class="pacman-css">
</div>
    
02.08.2018 / 22:19
18

Here are just examples with CSS.

Option 1: Made with border-radius

In this option you do not need to use position relative or absolute , nor do you need to put div s inside a container Only two divs with border-radius .

Then you make a simple% change by rotating one to one side and another to the other and pac-man makes the move!

body { background: black; }

.topo, .base {
    background-color: gold;
    width: 200px;
    height: 100px;
    border-radius: 100px 100px 0 0;
    animation: comex 500ms linear infinite;
}
.base {
    border-radius: 0 0 100px 100px;
    animation: comey 500ms linear infinite;
}
@keyframes comex {
    50% {
        transform: rotate(-15deg);
    }
}
@keyframes comey {
    50% {
        transform: rotate(15deg);
    }
}
<div class="topo"></div>
<div class="base"></div>

Option 2: made with borders

The rub is simple, there are two overlapping divs with keyframe . One has the yellow top edges and the transparent bottom edges. The second position:absolute is the opposite with the transparent top.

Here is the same principle of div by rotating @keyframes s inversely. Notice that it's all done with borders ...

Follow the example.

html {
width: 100%;
height: 100%;
background-image: linear-gradient(to bottom, tomato, skyblue);
background-repeat: no-repeat;
}

.container {
    position: relative;
    width: 200px;
    height: 200px;
}
.pac, .boca {
    position: absolute;
    box-sizing: border-box;
    border: 100px solid gold;
    border-radius: 50%;
    transform: rotate(-45deg);
}
.pac {

    border-bottom-color: transparent;
    border-left-color: transparent;
    animation: comex 500ms linear infinite;
}
.boca {
    border-top-color: transparent;
    border-right-color: transparent;
    animation: comey 500ms linear infinite;
}
@keyframes comex {
    50% {
        transform: rotate(-75deg);
    }
}
@keyframes comey {
    50% {
        transform: rotate(-15deg);
    }
}
<div class="container">
    <div class="pac"></div>
    <div class="boca"></div>
</div>

No Future

OBS: Soon the CSS "4" should implement the conic-gradient () and with it this kind of animation will get easier. Here is the link documentation

Conic-gradient article: link

Polyfill: link

  • Application example for the conic-gradient. To make Pacman would be something like done in the third example.

CurrentBrowserSupport: link

    
02.08.2018 / 21:53