Change marquee to css animations (#5119)

* Update hui-marquee.ts

* Change to css animation

* Comments

* tweaks

* Prevent page repaint on animation start/end
This commit is contained in:
Bram Kragten 2020-03-10 22:39:16 +01:00 committed by GitHub
parent 283e858576
commit 1c75fe3bb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -8,30 +8,22 @@ import {
CSSResult, CSSResult,
property, property,
} from "lit-element"; } from "lit-element";
import { classMap } from "lit-html/directives/class-map";
const marqueeSpeed = 0.2;
@customElement("hui-marquee") @customElement("hui-marquee")
class HuiMarquee extends LitElement { class HuiMarquee extends LitElement {
@property() public text?: string; @property() public text?: string;
@property() public active?: boolean; @property() public active?: boolean;
private _interval?: number; @property() private _animating = false;
private _left: number = 0;
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties); super.updated(changedProperties);
if ( if (
changedProperties.has("active") && changedProperties.has("active") &&
this.active && this.active &&
!this._interval &&
this.offsetWidth < this.scrollWidth this.offsetWidth < this.scrollWidth
) { ) {
this._interval = window.setInterval(() => { this._animating = true;
this._play();
});
this.requestUpdate();
} }
} }
@ -41,31 +33,25 @@ class HuiMarquee extends LitElement {
} }
return html` return html`
<div>${this.text}</div> <div
${this._interval class="marquee-inner ${classMap({
? html` animating: this._animating,
<div>${this.text}</div> })}"
` @animationiteration=${this._onIteration}
: ""} >
<span>${this.text}</span>
${this._animating
? html`
<span>${this.text}</span>
`
: ""}
</div>
`; `;
} }
private get _marqueeElementFirstChild(): HTMLElement { private _onIteration() {
return this.shadowRoot!.firstElementChild as HTMLElement; if (!this.active) {
} this._animating = false;
private _play(): void {
this.style.marginLeft = "-" + this._left + "px";
if (!this.active && !this._left) {
clearInterval(this._interval);
this._interval = undefined;
return;
}
this._left += marqueeSpeed;
if (this._left >= this._marqueeElementFirstChild.offsetWidth + 16) {
this._left = 0;
} }
} }
@ -73,10 +59,31 @@ class HuiMarquee extends LitElement {
return css` return css`
:host { :host {
display: flex; display: flex;
position: relative;
align-items: center;
height: 25px;
} }
:host div { .marquee-inner {
margin-right: 16px; position: absolute;
animation: marquee 10s linear infinite paused;
}
.animating {
animation-play-state: running;
}
span {
padding-right: 16px;
}
@keyframes marquee {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-50%);
}
} }
`; `;
} }