📜 ⬆️ ⬇️

MailChimp UX Team: Patterns and SVG Animation [Part 5 of the Book]



[ Tl; dr ]

[ 1st part of the book ]
[ 2nd part of the book ]
[ 3rd part of the book ]
[ 4th part of the book ]
[ 6th part of the book ]
[ 7th part of the book ]
[ 8th part of the book ]
')

Understanding the pattern library


Federico Holgado

The book “ Refabricating Architecture, ” written by Stephen Kiran and James Timberlake, greatly influenced my understanding of design. The authors of this book compare the architecture with the automotive, aerospace and shipbuilding industry, discussing the almost complete immutability of construction processes (from a fundamental point of view) in the last 80 years in contrast to the rapid changes in other industries of production and design.

They write that in the traditional sense of the construction process is to deliver all the necessary components to the construction site and the subsequent assembly. The architect conducts site research, makes the necessary measurements and prepares the relevant drawings; further, the team of builders interprets the results of his work, prepares the site using various techniques, and begins to work with the foundation. As soon as the building structure is ready, they carry out communications and move on to finishing works.

Kiran and Timberlake compare this process with peers from other fields of activity. For example, in the automotive industry several processes are combined at once, which allows to optimize production, reduce costs and improve the quality of the produced equipment. Components of the car is not produced in a single plant, and ordered from third-party contractors. The modular approach has proven itself well in shipbuilding and aerospace.

When we started working on the redesign of our application in 2013, we decided to apply a similar breakdown of processes and modules. As a result, we had to get a system consisting of interchangeable parts or "atoms" - the smallest components. Larger components had to consist of such "atoms" and make up the core of the application. At the same time, consistency in the structure and design of the pages and subsystems of the application was necessary.

Our library of patterns has basic elements with ready-made components based on "atoms", allowing developers to create interfaces that are consistent with existing systems. Next, I will talk about the practical application of this library.

Practice

Being engaged in the redesign, we started with the most popular section of the application - the control panel. In the old version, we displayed data on a simple grid, but after working with sketches and prototypes, we decided to make changes. We tried to enter two modes: with beautiful cards and a more informative grid. The “visual” approach did not work due to the fact that most of the campaigns of our users look quite similar. At the same time, we knew that it was very important for our customers to be able to sort campaigns by their attributes, which excluded the “tabular” approach.



Thus, we came to the rack system, which allowed us to establish communication with various sections of the application. As a result, it was useful in three sections at once. Instead of sorting, we used filters (where appropriate) and ended up with a ready-made basis for our control panel. The few months spent developing the rack system paid off with a number of advantages. We did not need to spend time redesigning several other parts of the application. Below are the mobile versions of the campaign and export sections, the similarities of which are easy to notice. Adaptation of the rack system for the export control panel of the channel is just 45 minutes, taking into account the mobile version.



We applied the rack system in a number of sections of the application, which had not previously received enough attention from the design point of view, but it was with the patterns that allowed these sections to be integrated into the overall design concept and ensure operation even in a very modest screen space. Another advantage of this approach is that we were able to distribute the team’s human resources and organize parallel work on the rack system as well as on the general structure of pages, navigation, etc. Part of the team worked at the base, and the other part was engaged in the design, while everyone was aware of what was happening.

What else has been done

Through the use of this approach, we managed to ensure the modularity of not only the rack system, but also virtually all parts of the application: forms, buttons, tables, editor elements, etc. At the first stage of work, it was quite difficult to reflect on such a concept, when you were already used to preparing separate UI elements for each of the new ideas. Thus, we have come to relatively chaotic CSS, heterogeneous design and differences in the software implementation of elements.

Investments in the form of time spent paid off, and we learned a lot by borrowing experience from other industries: a modular approach, organization of development processes, etc. In the course of work, our team constantly exchanges ideas - front-end developers always keep in touch with engineers. Our designers helped us to understand the principles of vertical and horizontal rhythm, which allowed us to simplify the layout of pages. Now, back-end developers can prepare universal systems that can be reused. Of course, this reduces the time spent on development, providing an understanding of the standard interface states.

The general level of accuracy and consistency that we managed to achieve not only pleases us, but also allows our clients to more effectively solve their problems. Today we have a standardized system that allows for further development. It seems that we are on the right path, based on the knowledge that we have gained by studying other areas of production.

SVG, sit down, 5!


Caleb Andrews, Alvaro Sanchez

We have been researching the process of using our application by clients for quite a long time and carefully. Not only in order to make our product better, but also for a general understanding of the sensations and thoughts of customers arising in the process of working with them. Based on this experience, we understand that sending a newsletter is quite an exciting process due to the tight deadlines and the need to eliminate possible errors. What people just don't do before sending letters to their subscribers: bite their lips, rub their palms, and sometimes almost sweat. We ourselves go through all this, working on our own newsletter UX Newsletter.

Understanding the emotional context of this process, we wanted to support our clients by showing them our understanding of what is happening. We decided that Freddie [MailChimp mascot] can help us with this, who, according to the idea, “gives five” to everyone who has successfully coped with the shipment. Previously, we displayed Freddie’s static palm and decided to slightly revive this moment with the help of SVG animation .

SVG-animation is not some kind of new technology, but many only recently got to work with it. In order to structure our story, we split it into two parts: preparation for working with SVG and implementation using the example of Freddie’s palm.

Caleb: Better SVG

Let's start with the preparation of files. First you need to deal with the hierarchy of layers.

She is a key element in working on SVG illustrations in Illustrator. We decided to divide animated frames into groups so that in each illustration there is nothing superfluous: only the most necessary. It is important to be careful with the choice of names for groups, to understand what the elements they contain are for, and to correctly prescribe the path to them in a text editor (what you have to do in the process of writing the script).

Removing excess control points

The fewer points, contours and their groups each layer contains, the “easier” the SVG code will be executed. And if you install the set of scripts for Illustrator from Hiroyuki Sato, you can remove the extra reference points by simply opening the File> Scripts> Delete Anchor Points tab.

Masks are good, but only in moderation



In the figure above, the “give me five” gesture from Freddie was created from 3 groups of elements combined into one SVG file without using masks. These groups are animated frames that can be hidden or, conversely, made visible when it becomes necessary. Subsequently, we decided to create masks to make SVG animation more controllable and “cleaner”.

Disable the ability to edit in Illustrator.

Now you need to export your drawings from Illustrator as an SVG file. This point is easy to miss: when saving a file in SVG format, do not forget to turn off the “Save Editing in Illustrator” feature in the Options tab. This will allow you to make the final file much easier - in the browser, you will not need these features. Such a procedure should be performed only with the final version of the illustration - as it is easy to guess, after that the file will no longer be so easy to re-open and edit in Illustrator.

Figures against contours

You can open your SVG file in a text editor and evaluate the generated code. In the example, my SVG file contains two elements - a rectangle and a contour. In theory, these are two identical rectangles, but the code that generates them is fundamentally different. If it is unusual for you to work with contours, you can easily convert them using the command Object> Disassemble.

Conclusion



It's not all that complicated, right? A little thoughtful preparation, and creating SVG-animation, which will attract attention and not slow down the browser, it turns out to be quite simple.

Alvaro: that hides the gesture of "give five"

Caleb explained how we prepared our SVG animation, now I will try to go further and explain what we did next. I simplified my explanations, but at the end I provided a link to the source code in case you want to see all the components of the final animation.

Training

When I first took on the Freddie animation project, I was given a prototype of it, made in After Effects and then exported to GIF. Caleb helped me recreate objects from the prototype in Illustrator: Freddie's foot, fur, etc. After I arranged the elements each on the right layer, I exported them as SVG files. As a result, we got 3 SVG files, one for each image of Freddy's paw. Then I thought about how to animate the created images.

Having a little rummaged in JavaScript libraries, I decided to work with Snap.svg . Snap supports such functions as creating masks, cropping and alignment, creating patterns, gradients, grouping elements. It also provides a simple and intuitive API for animation.

The implementation of the animation function - “mina” (this is “anim” [from the word “animation”], on the contrary) uses the AnimationFrame request, so the animation plays in the browser without interruption, as Paul Irish explained .

(By the way, if you use a library that does not support the AnimationFrame request to animate elements, consider the possibility of such a phenomenon as “ layout thrashing .” It occurs when JavaScript adds and removes elements from the DOM again and again, thereby slowing down the browser) .

Motion animation

I created an animation of the “give five” gesture from 3 separate images of Freddie's paw, each of which reflected its different (paws) position. To make the final image look like a single object taking different positions, I needed to create “smoothed” transitions from one position to another. To do this, I applied a step-by-step animation technique and linked the three main images with additional “transitions”. (Why didn’t I just animate a single image? Accounting for all points on Freddie’s fur-covered foot, calculating and adjusting the angle of “twisting” of the foot in each position turned out to be too complicated in the context of a short project timeline).

To upload all three images, I used the Snap.load feature. At first, I called this function for each of the images separately. As a result, the final image was animated quite well in Firefox, but with Google animation, there were problems with the animation. In the end, I realized that Firefox "recognized" all the transitions and the initial values, regardless of how many times I called the Snap.load function. Chrome, however, did not save information about transitions and setpoints, because each new call to Snap.load created a new SVG fragment with its own viewing area and coordinate system. I solved this question by saving all the source materials (3 variations of the Freddie's foot position) in one SVG, so I only needed to call the function once instead of three.

The next step was to determine the order in which the elements appear in the final version of the animation.



To achieve this, I needed to use the Snap.svg function to group items. For example, for such a grouper:

// Order of grouping is important!!! // s = SVG canvas created by Snap var group = s.group( circleBG, hand1, hand2, hand3 ); 


Grouping also sets the order of the elements in the stack: the circleBG element will be at the very bottom, and hand3 will be at the top.

Then we created and applied a mask to the specified group, thanks to which the animation of the elements took place “inside” the contour defined by the mask - in this case - inside the circle.

We created the mask like this:

 // Create a circle at x:200 and y:200 // and 200px radius circleMask = s.circle( 200, 200, 200 ); // Fill with white circleMask.attr({ fill: "#FFFFFF" }); 


To apply a mask to the elements of a group, I added a mask attribute to it (the group):

 group.attr( {mask: circleMask} ); 




As soon as we created and applied the mask, I set the position of each element and made the necessary of them visible on the final image. For our “give me five” gesture, I uploaded 3 elements that I animated, one after the other and at different intervals.

I set the foot position in each of its positions using the transformation string :

 // Initialize position. arm1.transform( "s0.6r-30t-100, 280" ); 


Each letter is a command: “s” for scaling [“scale”], “r” for turning [“rotate”], “t” for the translate command.

Using this notation, I made the arm1 element 40% smaller, I turned it by -30 degrees and positioned it outside the mask so that it was not visible.

I applied similar commands to initialize the arm2 and arm3 elements, but hid them by setting the opacity value to 0.

 // Set opacity to 0 arm2.attr( {opacity: 0} ); 


Combining elements

Having completed these operations, I began to animate images and create transitions between them. This is where the fun begins.

Snap.svg has an animate function. It receives the following attributes:

 Element.animate( attrs, duration, [easing], [callback] ); 


Here is an example of the first animation for the “give five” gesture:

  arm1.animate( {transform:'t-50,60'}, 400, mina.backout, function(){ // callback code here } ); 


Using the transformation attributes and new values ​​as the first of the function parameters, I programmed the movement of the arm1 element from the position -100px to -50px along the X axis and from 280px to 60px along the Y axis.

The second attribute (400) is the total duration of the animation in milliseconds.

The third attribute (mina.blackout) is a timing function like mina.linear, mina.easein, mina.easeout, etc. The mina.blackout function creates a “swing” effect, making movement more natural.

The fourth attribute is a callback function that is executed as soon as the animation ends. This is very important, because in this way you can attach one animation to another and control the creation of a consistent animated series.

For example, when switching between elements arm1 and arm2, I hide arm1 using the callback function of the original transformation. As soon as the process is completed, the arm1 element ceases to be visible (display: none), and the process of animating the arm2 element begins.

This all happens very quickly - the “attenuation” of the first element lasts 30 milliseconds, and the appearance of the second - 10 milliseconds.

Here is the part of the code describing the specified callback functions:

 arm1.animate( {transform: 't-50,60'}, 400, mina.backout, function(){ //400ms arm1.animate( {opacity: 0}, 30, mina.linear, function(){ // hide arm1 arm1.attr( {display: "none"} ); // Chain/Start // animation for arm2 _highFive.animate02(); // fadein 10ms }); }, 100); 


For a more detailed overview of the code that was created to animate the “give five” gesture, you can study the original version yourself.

[ Translation of the 6th part of the book ]

Source: https://habr.com/ru/post/253717/


All Articles