| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import {assert} from '//resources/js/assert.js'; |
| |
| export const STANDARD_EASING = 'cubic-bezier(0.2, 0.0, 0, 1.0)'; |
| |
| export const EMPHASIZED_DECELERATE = 'cubic-bezier(0.05, 0.7, 0.1, 1.0)'; |
| |
| /** |
| * Generic animator class that has common animations and util methods. |
| */ |
| export class Animator { |
| private root_: HTMLElement; |
| private animationsEnabled_: boolean; |
| |
| constructor(root: HTMLElement, animationsEnabled: boolean) { |
| this.root_ = root; |
| this.animationsEnabled_ = animationsEnabled; |
| } |
| |
| getElement(selector: string): HTMLElement { |
| const element = this.root_.shadowRoot!.querySelector(selector); |
| assert(element); |
| return element as HTMLElement; |
| } |
| |
| animate( |
| selector: string, keyframes: Keyframe[], |
| options: KeyframeAnimationOptions, |
| meetsCondition: boolean = true): Animation[] { |
| if (!this.animationsEnabled_ || !meetsCondition) { |
| return []; |
| } |
| |
| const elements = Array.from( |
| this.root_.shadowRoot!.querySelectorAll<HTMLElement>(selector)); |
| assert(elements.length > 0); |
| return elements.map(element => { |
| return element.animate( |
| keyframes, Object.assign({fill: 'backwards'}, options)); |
| }); |
| } |
| |
| fadeIn(selector: string, options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {opacity: 0}, |
| {opacity: 1}, |
| ], |
| Object.assign({easing: 'linear'}, options)); |
| } |
| |
| fadeOut(selector: string, options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {opacity: 1}, |
| {opacity: 0}, |
| ], |
| Object.assign({easing: 'linear'}, options)); |
| } |
| |
| /* Fades out an element and then sets the 'display' of the element to 'none'. |
| * This is useful for animations that result in an element and its children |
| * becoming [hidden]. */ |
| fadeOutAndHide( |
| selector: string, beforeDisplay: string, |
| options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {display: beforeDisplay, opacity: 1}, |
| {display: 'none', opacity: 0}, |
| ], |
| Object.assign({easing: 'linear'}, options)); |
| } |
| |
| /* Maintains a style for a duration on an element. This is useful for |
| * animations that require a fixed state (such as fixed heights). */ |
| maintainStyles( |
| selector: string, styles: Keyframe, options: KeyframeAnimationOptions) { |
| return this.animate(selector, [styles, styles], options); |
| } |
| |
| scaleIn(selector: string, options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {transform: 'scale(0)'}, |
| {transform: 'scale(1)'}, |
| ], |
| Object.assign({easing: STANDARD_EASING}, options)); |
| } |
| |
| slideIn( |
| selector: string, startDistance: number, |
| options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {transform: `translateY(${startDistance}px)`}, |
| {transform: `translateY(0)`}, |
| ], |
| Object.assign({easing: STANDARD_EASING}, options)); |
| } |
| |
| slideOut( |
| selector: string, endDistance: number, |
| options: KeyframeAnimationOptions): Animation[] { |
| return this.animate( |
| selector, |
| [ |
| {transform: `translateY(0)`}, |
| {transform: `translateY(${endDistance}px)`}, |
| ], |
| Object.assign({easing: STANDARD_EASING}, options)); |
| } |
| } |