Web Designer Blog
The latest news and tips from the Google Web Designer team
Google Web Designer Tips - Part 1
Friday, December 15, 2017
This document compiles the top tips collected from years of helping users on the
forum
, and from the
Google Web Designer blog posts
.
1. Use CSS transform for animation
Issue
: choppy animation when animating Top/Left/Width/Height.
Solution
: use CSS transform (
3D translation
and
scale
) for animation instead of Top/Left/Width/Height.
Google Web Designer defaults to CSS transform when creating CSS-based animation because the CSS transform property provides a higher frame rate and smoother animation. What this means is that when you use the selection tool to move an element or the transform tool to resize it in an animation, it will default to CSS transform (3D translation and scale section in the Properties panel) (see our
help
). However, many users change the Top/Left/Width/Height fields in the Properties panel when animating elements and this will cause choppy animation.
To avoid choppy animation, try using 3D translate X and Y for position, and 3D scale for size in the Properties panel when you animate elements. If you use the selection tool (or arrow tool) to move an element or the transform tool to resize an element, that should take care of it for you by default.
Note: if the animation of an image is choppy on IE when using CSS transform, wrap the image with animation in a div by right clicking on the image and selecting Wrap, then in the Properties panel of the parent div, set Selection 3D Rotation Z to 0.01 to workaround the issue.
2. Pixelation when using 3D scale for animation
Issue
: when using 3D scale for animation, the image becomes pixelated when scaled up.
Solution
: start with a large image that is the same size as the scaled up image. Add your starting and ending keyframes. At the starting keyframe, scale down the image using the Properties panel's 3D scale options. This creates an animation where the image grows in size without being pixelated.
3. Groups for reusable elements
Grouping objects creates a reusable element that can be placed in documents as "instances", which are references to the group's elements. Any change that is made to the group is reflected in all the instances of that group (see our
help
).
One example where groups are useful is a CTA button with an exit event that exists on different pages in the creative. Another benefit is that events for the elements in the group are retained in all instances of the group as long as the group instance has an ID assigned to it.
To create a group, right-click on the element on stage and select
Create Group...
You can then view the group in the Library panel and drag it on to the stage to create additional instances.
Groups are also used in the Swipeable and Carousel Galleries in dynamic creatives to display a custom layout for each product item in a collection. For example, you can create a group to display a product's image, name, description, price, etc., and this layout can be repeated for each product in the feed. This workflow will be described in a future dynamic tips blog post.
4. Make an element appear/disappear at a specific time during the animation
Issue
: how to create an animation with an element that needs to be hidden/shown at certain keyframes.
Solution
: use
opacity
and
step-end/step-start
easing. You can also watch the YouTube video on this topic
here
.
In this example, a div is hidden until the 3s mark. Then it is animated until 5s and disappears at 5s. To do this, let’s switch to the timeline’s Advanced mode then select the first keyframe. In the Properties panel of the element, set the opacity to 0 to hide the element.
Add the second keyframe where you want to show the element, at 3s in this example, and set the opacity of the element to 1.
At this point, if you preview, you will see that the element animates from 0 opacity to 1 because the easing is set to linear by default.
Right-click on the span between the keyframes and change the easing from linear to
step-end
. At this point, the element will not show until the second keyframe.
Add a third keyframe, at 5s in this example, and animate your element (in this example, it travels across the stage).
To hide the element again, add another keyframe at 5.5s, and set opacity to 0 and easing to step-start.
Then drag the keyframe so it’s right next to the keyframe at 5s.
Now you have accomplished turning an element on or off at a certain keyframe! You can view the
source file
or check out our
blog post
to use other ways to achieve the same effect.
5. How to replace an image without losing the events or animation
Issue
: some users build a new creative using an existing creative and want to easily change an image without losing events or animation.
Solution
: use
Swap image
in the context menu (see our
help
).
Select the image on the stage to be changed, right-click on it, and select
Swap image...
In the Swap image dialog, select the new image (if it’s already in the Library), or add a new image and select it. Click
OK
to save.
6. How to update an element’s size and position without affecting animation
Issue
: when building multi-size creatives, many users may start with one size, then build additional sizes using the first completed creative instead of using responsive design. In this workflow, it is necessary to update the element’s size and position in the new creative while keeping the animation the same.
Solution
: use CSS transform for animation (solution #1 in this post) , then update the Top, Left, Width, and Height properties in the
first keyframe in Advanced mode
to update the element’s position and size without affecting the animation.
When using animation, the best practice is to animate using CSS transform to avoid choppy animation. In addition to the performance benefit, you can also quickly update the element’s size and/or position without having to update all keyframes.
For example, let’s say you have a 100x100px element at the first keyframe like this:
In the second keyframe, it moves across the screen and shrinks to half of its size like this:
Now let’s say you’re building a bigger creative and the element has to be 200x200px. You can simply select the first keyframe and update the Width and Height properties. Since Width and Height are not used to animate the element, what you change in the first keyframe will propagate across all subsequent keyframes.
The element will now be 200x200px and travel across the screen by 200px with its size reduced in half:
7. How to loop the Swipeable Gallery infinitely
Issue
: when autoplay is set, the Swipeable Gallery only autoplays until the last frame and then returns to the first frame.
Solution
:
autoplay
the Swipeable Gallery infinitely by rotating once when the autoplay ends, and setting the rotation time and autoplay duration for smooth looping.
In this example, there are 3 images, autoplay is set in the Properties panel, and autoplay rotation is set to 3000 in the Advanced properties for the Swipeable Gallery. This means that the gallery autoplays from the first to the last frame in 3 seconds.
When you preview, you will see that the Swipeable Gallery autoplays once, then goes back to the first frame and stops. To autoplay it infinitely, add an autoplay ended event to rotate once forward.
Right-click on the Swipeable Gallery and select
Add event
.
Select Swipeable Gallery >
Autoplay ended
as the Event.
Select Swipeable Gallery >
Rotate once
as Action.
Select the Swipeable Gallery ID as the Receiver.
In Configuration, set the Rotation time to be the same as the autoplay duration. In this example, this is 3000 with forward direction.
Click OK to save.
You now have a
working file
that loops the Swipeable Gallery infinitely.
We hope you have enjoyed these tips, and don't forget to download the working files and give these solutions a try!
Posted by San K, Google Web Designer Team
Masking in Google Web Designer
Friday, November 4, 2016
Investigating Masking in Google Web Designer
Masking routinely tops the list of requested features in Google Web Designer. We investigated different approaches to implementing masking in HTML5, and we concluded that the limitations of existing browsers make effective masking infeasible at this time. We recognize that this is a disappointing result, so we’re using this space to explain (and show!) what we tried, and why we think masking is not yet ready for production.
What is masking?
A mask defines a region of the plane where content (the
maskee
) is rendered; outside of this region, the content is invisible. For example, a circular mask may be used to create a spotlight effect, by only revealing content within the "light". A complete masking solution would meet the following criteria:
Everything is maskable.
The maskee may include text, images, animation, SVG, canvases, videos, custom elements, and even other masks.
A mask can have any shape.
It may be as simple as a circle, or it may be multiple disconnected regions with complicated geometry.
Masks can be animated.
The mask can be translated, rotated, and scaled; it can be morphed into new shapes; and in the most general case, the mask can be a video.
Masks stack and overlap.
Placing one mask inside another is equivalent to intersecting the two masks. If two independent masks overlap, the output of one is rendered atop the other, with no other interference.
Events are masked.
Events originating outside the mask are blocked, and otherwise they pass through to the maskee without modification.
What did we try?
There is no way to achieve all of the above properties on any particular browser, much less every browser we support (i.e., Chrome, Firefox, Safari, and IE 10+). We don’t require perfection, however; an approximate solution can still be useful in practice. We initially experimented with
CSS3 masking
. Smooth mask animation is only possible if the mask is a CSS basic-shape, but otherwise all masking behaviors, such as those listed in the section above, are supported. However, CSS3 masking is not yet available on all major browsers.
Another way to implement masking, which is already supported by all major browsers, is to represent a mask as an element styled with
overflow: hidden
. This exhibits all masking behaviors, although the mask’s shape is equivalent to the element’s border, which effectively limits masks to rectangles, circles, ellipses, and capsules. Despite this limitation, overflow-based masking would still be useful for basic effects like wipes and reveals. Moreover, on browsers that support CSS3 masking, the mask’s shape could essentially be arbitrary, although animation would still be limited to the element’s transform. Unfortunately, we discovered that even in simple cases, overflow-based masking produced blurring and flickering artifacts on some browsers.
Finally, it’s worth noting that in simple cases, masking-like effects can be achieved simply by overlaying an image with transparent regions, which is already possible in Google Web Designer. This technique, however, is really the opposite of masking -- instead of rendering
only
within the mask region, it paints over everything that is
not
in the mask region.
CSS3 masking
We started by exploring CSS3 masking, which comes in two forms: clipping (clip-path) and masking (image-mask). Clipping crops the rendering of an element and its children to a binary mask defined either through an inlined SVG, or a “basic shape” consisting of a circle, and ellipse, or a polygon. Masking crops the element’s content to an image’s boundary, and then applies an alpha channel determined by the image content. As of this writing, browser support for CSS3 masking is as follows:
Clipping
is supported
on Chrome, Safari, and Firefox, although Firefox’s support for basic shapes is turned off by default.
Masking
is supported
in Chrome, Safari, and Firefox, but Firefox currently does not allow control over the image’s size or position.
IE does not currently support CSS3 masking, but future support
is likely
, at least for Edge.
We tested CSS3 clipping and masking in several different scenarios, and here’s what we found (
demo
):
Clipping.
Clip paths defined as SVG elements offer the most flexible representation of a mask’s shape, but CSS animations applied to SVG clipping elements are ignored at render time. Basic shapes offer less expressive mask geometry, but at least they can be animated: for circles and ellipses, the centers and radii are interpolated, and for polygons, control points locations are linearly interpolated (assuming that each keyframe has the same number of control points). One quirk is that in some browsers,
overflow: hidden
must be set on the mask element, or else the clipping path will be ignored if the maskee contains 3D transforms or has animated transforms (2D or 3D).
Masking.
Masking allows essentially arbitrary mask geometry, but animation of the mask shape is limited to defining CSS keyframes for mask-position and mask-size, allowing the mask to be translated and (non-uniformly) scaled. However, the mask is always rendered with positions and sizes rounded to the nearest integer, resulting in jagginess artifacts when the mask is animated slowly (
demo
).
In summary, smoothly animatable masks are only possible using clip-path with a basic shape — and even then, currently only in Chrome and Safari.
Overflow-based masking
An alternative to CSS3 masking is to set an element's overflow to “hidden”, and then add the maskee as a child element:
<div id=”mask”>
<div id=”maskee”></div>
</div>
This crops the maskee to the bounds of the parent element. Because the maskee is a child of the mask, however, moving the mask will also move the maskee. To allow them to move independently, we can insert an intermediate element that cancels changes to the mask.
<div id=”mask”>
<div id=”maskCancel”>
<div id=”maskee”></div>
</div>
</div>
For example, if mask is moved ten pixels to the left,
maskCancel
is moved ten pixels to the right, giving the appearance that maskee remains stationary while the mask reveals a different portion of it. More generally, changes to the mask configuration can be canceled as follows:
The intermediate element is forced to the same size as the mask, by setting its width and height to 100%.
If the mask’s left and top are (x, y), the intermediate element’s left and top are (-x, -y).
The intermediate element’s transform origin is identical to that of the mask, and its transform is the inverse of the mask’s transform.
Similarly, if the mask is animated using CSS3 keyframes, additional keyframes rules must be added to the intermediate layer to cancel this animation. Assuming that animation is limited to transform (per existing
best practices
), this means:
Animation of the mask’s transform-origin is copied to the intermediate element.
The inverse of the mask’s transform animation is applied to the intermediate element.
(2) is by far the most complicated part of the process, and as it need not be understood to evaluate the practical effectiveness of overflow-based masking, we discuss it in the Appendix at the end of this post.
We built a
proof-of-concept implementation
of overflow-based masking, and discovered that even in simple of cases, animating the mask transform produces blurring and flickering artifacts on some browsers. For example, here is a screenshot of Chrome’s output, using a circular mask that translates back and forth (
demo
):
It appears as if the maskee is first being rendered with the intermediate layer’s transform applied, and then re-rendered with the mask’s transform, resulting in blurring and flickering artifacts. This behavior is not consistent across browsers: as of this writing, the artifacts appear in Chrome in all cases, they appear in Firefox if the animation includes scale or rotation (
demo
), and they do not appear in IE or Safari. However, on all browsers, no artifacts are present if overflow is set to visible, but the mask/intermediate layer/maskee construct is otherwise left unmodified.
Animation of an element’s left, top, width, and height (LTWH) is generally discouraged, and by default GWD uses LTWH for static layout and translation/scale for animation. Still, in light of these rendering artifacts, it’s worth considering whether LTWH makes more sense for masking. One problem with LTWH animation is that it has
worse performance
than transform animation: dozens of objects can easily be animated at 60Hz using transforms, but will slow down to 10Hz or worse if LTWH is used. If a document only has one or two masks and isn’t too complicated, however, perhaps the performance penalty is acceptable. A second problem is that LTWH values are rounded to the nearest integer at render time, which avoids the rendering artifacts discussed above, but at the expense of creating clunky, stair-step-like animations when objects animate slowly (
demo
).
Stay tuned
We would love to add masking to Google Web Designer, but as an HTML5 authoring tool, we're limited by what browsers are able to support. Still, the web is constantly evolving, and browsers are continually improving, so we still hope and expect to ultimately be able to add masking to our suite of tools.
Posted by Lucas, Software Engineer
Appendix: Inverting animation for overflow-based masking
If a mask is rotated or translated, then an inverse animation can easily be created by reversing the order of each key’s transforms and negating the values of each transform channel. For example, if the mask’s transform is
translate(tx, ty) rotate(rz) scale(sx, sy),
then the intermediate element’s transform is
scale(1/sx, 1/sy) rotate(-rz) translate(-tx, -ty).
If a mask is also scaled, then the inverse scale animation is defined in terms of a reciprocal. For example, a simple linear scaling from s1 to s2 over a time interval T can be written as
and the inverse scaling animation is then
Functions like this cannot be exactly represented in CSS3, which
defines animation curves
as 2D cubic Bezier segments where the first dimension is time and the second dimension is normalized value. While we could simply disallow scaling, this would make it impossible to achieve wipe and reveal effects. Instead, we generate samples of the ideal inverse scale animation
and fit an approximating animation curve. For simplicity, in our experiments we constructed inverse animations as piecewise linear functions, although more compact results can be obtained by fitting general cubic Bezier curves. To determine an acceptable error tolerance for the approximation, consider an absolute error e resulting in a net scale at the maskee of
At a distance
d
from the transform origin, this yields a positional error of
sed
, and so given a maximum mask size of
M
, the maximum error
E
is
Positional discrepancies can therefore be kept below half a pixel by requiring
Intuitively, the smaller the scale value, the larger the error we can tolerate, because only a narrow slice of content will be visible through the mask. (It is also possible to invert animation of uniform scale by animating z translation, but this technique does not generalize to animations that include non-uniform scaling, and it alters the meaning of existing z translations authored in the maskee.)
Interactive Design with CSS and Events
Monday, April 4, 2016
Introduction
One of Google Web Designer’s strengths is that it allows for content creation without requiring users to be seasoned coders. With a few clicks, drags and keypresses you can create an animated and event-driven HTML5 experience without any hand-coding at all.
While the usefulness of visual authoring is obvious, the web platform is powerful and ever growing; so knowing a bit of CSS and JavaScript can give you a valuable toolset in creating engaging online experiences.
In this article, we’ll observe some of the CSS created when authoring a transition effect and combine it with a small amount of JavaScript to have tighter control of the visual state of elements. Some basic understanding of HTML and CSS is assumed.
The Design
For the design, our goal is to create an HTML “ferris wheel” effect by using Web Designer’s three-dimensional transformation tools, the Timeline and the CSS Panels, among other key features. For now, we’ll be rotating simple text elements.We’ll also want to control the animation playback using triggering element.
Let’s start by creating the text elements, adjusting their font styles and position, and adding rotational animation.
Create Text Elements
Using the Text Tool, click near the top of the stage to create a paragraph element and type some text. Our design involves presenting a list of 4 destinations, so let’s type “San Francisco” as our first destination.
In the CSS Panel, you’ll notice a rule was created to apply styles to your text element -- it should have a selector reading something like “.
gwd-p-1234
”. This selector might seem like gibberish to you, and well, you’d be right. This is because Web Designer doesn’t know what you plan to use the CSS rule for, so it assigns a generic selector. Updating these selectors to be more meaningful will make your code easier to read and understand.
With the CSS Panel open, click on the selector to activate it for edits. Change the selector to ‘
.label
’. Next, use the Text Tool’s toolbar to set the font family, font size and color to your preference. I’ve chosen large, light text using the Google Font “Luckiest Guy”.
Now, switch over to the Selection Tool, copy/paste the current selection and drag downward (or hold Shift+Down Arrow) to move the copy directly below the original. Switch back to the Text Tool and change the label’s text to something new (e.g. “Mountain View”).
Hit Ctrl+A (or Command+A on OS X) to select both paragraphs, right-click either one and select “Wrap” from the context menu. This will create a DIV to surround our two paragraphs. Feel free to update the generated CSS rule selector to something meaningful for added maintainability (keeping with the wheel analogy, I’ve chosen “
.spoke
” for my selector). While we’re at it, right-click and again select “Wrap” from the menu, this time changing the generated CSS selector to “
.wheel
”. Our “wheel” will eventually contain multiple “spokes”, but we’ll get to that later.
Animate the container
Now that we have a bit of content, let’s work on our animation. We’ve already wrapped our text elements in a DIV, so rotating that DIV should spin the inner text elements on the correct path. With the outer element selected (the one using the selector “
.wheel
”), use the Timeline to set a keyframe at 1 second. You can apply rotation at that keyframe by either using the 3D Object Rotate Tool or the Properties Panel. Since we know the exact values to enter (
360 degrees
of rotation along the X-axis), using the Properties Panel here is a more efficient workflow.
We’ll want this animation to loop indefinitely, so use the animation repeat control on the appropriate Timeline track to set animation looping to “Infinite”.
An unexpected twist
A handy feature of Web Designer’s Timeline is animation scrubbing. Click and drag the Timeline’s tick marker back and forth to get a preview of our newly created animation. You’ll notice our “ferris wheel” is behaving a bit unexpectedly. While the path of rotation is what we want, the text labels do not remain upright -- a desired quality in both textual labels and ferris wheel cars.
To ensure the text remains legible, we’ll add a counter-rotation animation to our labels.
Apply counter-rotation animation
With the Selection Tool activated, double-click the “spoke” element. This changes the drawing container and allows us to access our label elements once again for editing. For each label, add a keyframe at 1s in its Timeline, and set the X-axis rotation at that keyframe to
-360 degrees
using the Properties Panel.
The animations should also have looping set to “Infinite.” Another pass at scrubbing the Timeline animation should yield much better results.
Adding another “spoke”
The design calls for 4 destinations to be listed, so naturally, we’ll add another “spoke” to the wheel. We can do this quickly by copying and pasting the existing spoke element (containing two labels). The second spoke is now laying on top of the first, but it should really intersect it at the center. We can achieve this by rotating it about its X-axis by
90 degrees
.
You’ll notice the pasted element will already have animations listed in the Timeline. These are the copies of the original counter-rotation animation we used for the first set of labels, but now we must update them to make up for the fact that they are rotated an additional 90 degrees. For each of these two labels, set X-axis rotation in the first keyframe to
270 degrees
and
-90 degrees
in the last. Next, use the Text Tool to update the strings within the new labels. I’m sticking to California cities, and so let’s add “Monterey” and “Santa Barbara”.
NOTE! You may find it easier to edit your text by temporarily rotating the stage to get a better view. To do this, select the 3D Stage Rotate Tool and click and drag a point on stage around to get a different perspective.
The Text Tool allows for editing in 3D. Use the 3D Stage Rotate Tool to get a better angle for your edits.
Adding an animation control
To control the animation, we’ll add another text element (using the Text Tool) to serve as a button. Since this control will toggle playback, type “Toggle” as the content of your text element. In the Properties Panel, assign an ID attribute; ID’s are needed on target elements before using Web Designer’s event listening feature.
After assigning the ID, right-click the new element and select “
Add event…
” to launch the Events Dialog. Select
Mouse > Click, Timeline > Toggle Play
, select your current page and click
Save
. You should now notice this new event configuration listed in the Events Panel.
Final steps
So far, we’ve create an HTML structure that allows us to apply a rotation to invoke a spinning wheel effect. We’ve also wired an event listener a toggle button using the Events Dialog to pause and resume animation playback on the user’s demand. Let’s see if it works!
To see your design working in a browser, click the
Preview
button and select your preferred browser. Test out the toggle button. What do you see?
You should notice that pausing the animation using the button only affects the top-level animation -- the labels continue to rotate along their X-axis:
To fix this, let’s jump into Code View and take a closer look at our CSS.
In Code View, find a block of CSS resembling the following:
#page1.gwd-pause-animation .gwd-gen-1cvqgwdanimation {
animation-play-state: paused !important;
}
This CSS rule relies on the class “
gwd-pause-animation
” to be applied to the page’s root element in order to pause playback,
but only
for the top-level element. Change the code to the following to also target the animations on labels:
#page1.gwd-pause-animation .gwd-gen-1cvqgwdanimation,
#page1.gwd-pause-animation .label
{
animation-play-state: paused !important;
}
With the animation pausing rule modified, let’s give our toggle button another test run. Hit Preview one more time. The toggle button should now work!
Keep it rolling
In this exercise, you have successfully built a pausable, three-dimensional animation using JavaScript events and some custom CSS; techniques you can utilize to further enhance your animation projects! We’ve covered a lot of ground in this exercise, but this only scratches the surface of what is possible with Google Web Designer! Continue to follow along with us and let us know what you think in the blog comments!
Posted by Eric, UX Engineer
Labels
3D
animation
animations
BYOC
carousel
clips
css
CTA
custom code
Display
DoubleClick Bid Manager
DoubleClick Studio
dynamic
engagement ads
English
events
exit
fluid layout
gallery
google cultural institute
google web designer
Google Web Designer Blog
groups
HTML5
javascript
lightbox
looping
masking
new release
new version
pages
publish
responsive
sales animation
swatches
swipeable
text
timeline
UI
Archive
2018
January
Google Web Designer Tips - Part 2
2017
December
April
March
2016
November
June
May
April
March
February
Feed
Follow @googlewdesigner