In the second part, I animate the letters and I define their positioning and colors.
Animating the letters
animate
element's attributes
attributeName
Name of the attribute that will change during the animation, the d
attribute in this animation.
values
List of values used throughout the animation. In this animation, the d
attribute assumes 3 values.
In the first row letters: normal version, stretched version and normal version again. In the second row: stretched version, normal version and stretched version again.
calcMode
Interpolation mode (process that calculates the animation's intermediate values), which is spline
in this animation. It allows the use of Bézier curves to define the time function, enabling smooth transitions.
keyTimes
List of values that defines the animation's rhythm, each value ranges between 0
and 1
. With calcMode spline
, for every values
value, there must be a keyTimes
value.
In this animation, the list is 0; 0.5; 1
. That is, the first value of values
is used at the beginning of the animation, the second value is used at the middle of the animation, and the third value is used at the end of the animation.
keySplines
List of values defining the Bézier curves (x1, y1, x2, y2
) used in the intervals between the keyTimes
attribute's values.
In this animation, the list is 0.45, 0.05, 0.55, 0.95; 0.45, 0.05, 0.55, 0.95
(the same curve on both values). That is, between 0; 0.5
the first value is used, and between 0.5; 1
the second value is used.
begin
Defines when the animation should start. I used it to delay the start of each column's animation to create the wave motion.
dur
The animation duration, which is 1s
in this animation.
repeatCount
Number of repetitions, which is indefinite
in this animation.
Attributes of this animation
I left the path
element's d
attribute empty, as it is defined in the animate
element's values
attribute. The only animate
element's attributes that change from one letter to another are values
and begin
, the other attributes have the same value for all letters.
<svg viewBox="0 0 10 20"> <path d=""> <animate attributeName="d" begin="column based value" dur="1s" repeatCount="indefinite" calcMode="spline" keySplines="0.45, 0.05, 0.55, 0.95; 0.45, 0.05, 0.55, 0.95" keyTimes="0; 0.5; 1" values="d commands; d commands; d commands" /> </path></svg>
In the following views I didn't set the begin
attribute, because I was still dealing with each letter individually. I show the final position in the section Positioning.
In these sections I used a viewBox
that holds only one letter:
<svg viewBox="0 0 10 20" width="200"> <!-- other elements go here --></svg>
First row
In each view, I omitted the svg
and path
elements that would wrap the animate
element, as well as its other attributes, to keep the code concise.
<animate values=" regular version; stretched version; regular version "/>
Letter G
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,4.6 L6,4.6 L6,4 C6,3 4,3 4,4 L4,6 C4,7 6,7 6,6 L5,6 L5,5 L10,5 L10,10 L7,10 L6.6,9 Q6,10 4,10 Q0,10 0,6z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,14.6 L6,14.6 L6,4 C6,3 4,3 4,4 L4,16 C4,17 6,17 6,16 L5,16 L5,15 L10,15 L10,20 L7,20 L6.6,19 Q6,20 4,20 Q0,20 0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,4.6 L6,4.6 L6,4 C6,3 4,3 4,4 L4,6 C4,7 6,7 6,6 L5,6 L5,5 L10,5 L10,10 L7,10 L6.6,9 Q6,10 4,10 Q0,10 0,6z "/>
Letter O
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L4,10 Q0,10 0,6 L4,6 C4,7 6,7 6,6 L6,4 C6,3 4,3 4,4 L4,6 L0,6z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L4,10 Q0,10 0,6 L4,6 C4,7 6,7 6,6 L6,4 C6,3 4,3 4,4 L4,6 L0,6z "/>
Letter D
<animate values=" M0,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L0,10 L0,7 L4,7 Q6,7 6,6 L6,4 Q6,3 4,3 L4,7 L0,7z; M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z; M0,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L0,10 L0,7 L4,7 Q6,7 6,6 L6,4 Q6,3 4,3 L4,7 L0,7z "/>
Second row
In each view, I omitted the svg
and path
elements that would wrap the animate
element, as well as its other attributes, to keep the code concise.
<animate values=" stretched version; regular normal; stretched version "/>
Letter M
<animate values=" M0,0 L4,0 L5,6 L6,0 L10,0 L10,20 L7,20 L7,7 L6,20 L4,20 L3,7 L3,20 L0,20z; M0,10 L4,10 L5,14 L6,10 L10,10 L10,20 L7,20 L7,15 L6,20 L4,20 L3,15 L3,20 L0,20z; M0,0 L4,0 L5,6 L6,0 L10,0 L10,20 L7,20 L7,7 L6,20 L4,20 L3,7 L3,20 L0,20z "/>
Letter O
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z; M0,14 Q0,10 4,10 L6,10 Q10,10 10,14 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,14 C6,13 4,13 4,14 L4,16 L0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z "/>
Letter D
<animate values=" M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z; M0,10 L6,10 Q10,10 10,14 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,14 Q6,13 4,13 L4,17 L0,17z; M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z "/>
Positioning
defs
and use
elements
I defined the id
attribute of each path
element and placed them inside the defs
element, so that later I could reference them with use
elements by the href
attribute.
With the use
element, I defined the position of each letter with the x
and y
attributes, following the grid. I put a number at the id
attribute value's end of repeating letters, as they must be unique.
<!-- I omitted the animate elements' attributes to keep the code concise --><svg viewBox="0 0 63 51"> <defs> <!-- first row --> <path d="" id="letter-g"><animate /></path> <path d="" id="letter-o-1"><animate /></path> <path d="" id="letter-o-2"><animate /></path> <path d="" id="letter-d-1"><animate /></path> <!-- second row --> <path d="" id="letter-m"><animate /></path> <path d="" id="letter-o-3"><animate /></path> <path d="" id="letter-o-4"><animate /></path> <path d="" id="letter-d-2"><animate /></path> </defs> <!-- first row --> <use href="#letter-g" x="10" y="10" /> <use href="#letter-o-1" x="21" y="10" /> <use href="#letter-o-2" x="32" y="10" /> <use href="#letter-d-1" x="43" y="10" /> <!-- second row --> <use href="#letter-m" x="10" y="21" /> <use href="#letter-o-3" x="21" y="21" /> <use href="#letter-o-4" x="32" y="21" /> <use href="#letter-d-2" x="43" y="21" /></svg>
Defining the begin
attribute
Following the original animation, when the first column is stretched up, the last column is stretched down. As the animation has 1s, I set the first column's begin
attribute value as -1
(negative values mean that there is no delay when starting the animation), and the last column as -0.5
. That is, when the first column completes one animation cycle, the last column completes half a cycle.
To obtain the begin
attribute's value of the other columns, I calculated the time interval that should exist between the animation's beginning of each of the 4 columns: 0.5 / 3 ≈ 0.1666
. With that, I calculated the value of the begin
attribute of each column:
- First column:
-1
- Second column:
-1 + 0.1666 ≈ -0.8333
- Third column:
-0.8333 + 0.1666 ≈ -0.6666
- Fourth column:
-0.6666 + 0.1666 ≈ -0.5
<!-- I omitted the animate elements' other attributes to keep the code concise --><svg viewBox="0 0 63 51"> <defs> <!-- first row --> <path d="" id="letter-g"> <animate begin="-1" /> </path> <path d="" id="letter-o-1"> <animate begin="-0.8333" /> </path> <path d="" id="letter-o-2"> <animate begin="-0.6666" /> </path> <path d="" id="letter-d-1"> <animate begin="-0.5" /> </path> <!-- second row --> <path d="" id="letter-m"> <animate begin="-1" /> </path> <path d="" id="letter-o-3"> <animate begin="-0.8333" /> </path> <path d="" id="letter-o-4"> <animate begin="-0.6666" /> </path> <path d="" id="letter-d-2"> <animate begin="-0.5" /> </path> </defs> <!-- first row --> <use href="#letter-g" x="10" y="10" /> <use href="#letter-o-1" x="21" y="10" /> <use href="#letter-o-2" x="32" y="10" /> <use href="#letter-d-1" x="43" y="10" /> <!-- second row --> <use href="#letter-m" x="10" y="21" /> <use href="#letter-o-3" x="21" y="21" /> <use href="#letter-o-4" x="32" y="21" /> <use href="#letter-d-2" x="43" y="21" /></svg>
Colors
I set the colors of each letter in the use
element, and the background color with a rect
element. The order of elements matters, the rect
must be drawn before the letters, otherwise the rect
would be drawn on top of the letters.
<div class="wrapper"> <div class="container"> <svg viewBox="0 0 63 51"> <defs> <!-- I omitted the defs element's code to keep the code concise --> </defs> <!-- background --> <rect width="63" height="51" fill="#000" /> <!-- first row --> <use href="#letter-g" x="10" y="10" fill="#FFFFFF" /> <use href="#letter-o-1" x="21" y="10" fill="#FFFFFF" /> <use href="#letter-o-2" x="32" y="10" fill="#FFFFFF" /> <use href="#letter-d-1" x="43" y="10" fill="#FFFFFF" /> <!-- second row --> <use href="#letter-m" x="10" y="21" fill="#FFB200" /> <use href="#letter-o-3" x="21" y="21" fill="#006BF5" /> <use href="#letter-o-4" x="32" y="21" fill="#FD002D" /> <use href="#letter-d-2" x="43" y="21" fill="#FF769F" /> </svg> </div></div>
To center the animation, I added CSS.
/* simple reset */*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0;}/* the wrapper has the viewport's height */.wrapper { display: flex; min-height: 100vh;}/* the animation is centered */.container { margin: auto; width: 800px; max-width: 100%;}
Conclusion
Having the animation done and the colors defined, I proceeded to the filters: GOOD MOOD part 3: applying filters.