Media Card: Add Marquee to Title (#5095)

* Marquee Addition

* Review Comments

* instance var name change

* fix merge

* Comments plus merge fix
This commit is contained in:
Zack Arnett 2020-03-09 12:43:53 -04:00 committed by GitHub
parent 9da32880ec
commit 0e1eca8a3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 2 deletions

View File

@ -44,6 +44,7 @@ import {
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../components/hui-marquee";
function getContrastRatio(
rgb1: [number, number, number],
@ -88,6 +89,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
@property() private _narrow: boolean = false;
@property() private _veryNarrow: boolean = false;
@property() private _cardHeight: number = 0;
@property() private _marqueeActive: boolean = false;
private _progressInterval?: number;
private _resizeObserver?: ResizeObserver;
@ -240,8 +242,13 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
: html`
<div class="media-info">
<div class="title">
${stateObj.attributes.media_title ||
computeMediaDescription(stateObj)}
<hui-marquee
.text=${stateObj.attributes.media_title ||
computeMediaDescription(stateObj)}
.active=${this._marqueeActive}
@mouseover=${this._marqueeMouseOver}
@mouseleave=${this._marqueeMouseLeave}
></hui-marquee>
</div>
${!stateObj.attributes.media_title
? ""
@ -564,6 +571,18 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
});
}
private _marqueeMouseOver(): void {
if (!this._marqueeActive) {
this._marqueeActive = true;
}
}
private _marqueeMouseLeave(): void {
if (this._marqueeActive) {
this._marqueeActive = false;
}
}
static get styles(): CSSResult {
return css`
ha-card {

View File

@ -0,0 +1,89 @@
import {
html,
LitElement,
PropertyValues,
TemplateResult,
customElement,
css,
CSSResult,
property,
} from "lit-element";
const marqueeSpeed = 0.2;
@customElement("hui-marquee")
class HuiMarquee extends LitElement {
@property() public text?: string;
@property() public active?: boolean;
private _interval?: number;
private _left: number = 0;
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (
changedProperties.has("active") &&
this.active &&
!this._interval &&
this.offsetWidth < this.scrollWidth
) {
this._interval = window.setInterval(() => {
this._play();
});
this.requestUpdate();
}
}
protected render(): TemplateResult {
if (!this.text) {
return html``;
}
return html`
<div>${this.text}</div>
${this._interval
? html`
<div>${this.text}</div>
`
: ""}
`;
}
private get _marqueeElementFirstChild(): HTMLElement {
return this.shadowRoot!.firstElementChild as HTMLElement;
}
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;
}
}
static get styles(): CSSResult {
return css`
:host {
display: flex;
}
:host div {
margin-right: 16px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-marquee": HuiMarquee;
}
}