tp-avatar/tp-avatar.js
2024-10-21 23:37:00 +02:00

131 lines
3.2 KiB
JavaScript

/**
@license
Copyright (c) 2024 trading_peter
This program is available under Apache License Version 2.0
*/
import '@tp/tp-icon/tp-icon.js';
import { LitElement, html, css, svg } from 'lit';
import { classMap } from 'lit/directives/class-map.js';
class TpAvatar extends LitElement {
static get styles() {
return [
css`
:host {
display: inline-block;
position: relative;
border-radius: 50%;
width: var(--tp-avatar-size, 32px);
height: var(--tp-avatar-size, 32px);
}
:host [hidden] {
display: none;
}
#avatarImg {
width: var(--era-avatar-size, 32px);
height: var(--era-avatar-size, 32px);
background-size: cover;
background-position: center center;
border-radius: 50%;
opacity: 0;
}
#avatarImg.visible {
transition: opacity 300ms;
opacity: 1;
}
tp-icon {
opacity: 1;
transition: opacity 100ms;
color: #BDBDBD;
position: absolute;
inset: 0;
--tp-icon-height: var(--tp-avatar-size, 32px);
--tp-icon-width: var(--tp-avatar-size, 32px);
}
tp-icon.hidden {
opacity: 0;
transition: opacity 300ms linear 0ms;
}
`
];
}
render() {
const { loaded, hasSrc } = this;
return html`
<div id="avatarImg" class=${classMap({ visible: loaded, hidden: !loaded })}></div>
<tp-icon id="placeHolder" .icon=${TpAvatar.defaultAccountIcon} class=${classMap({ visible: !loaded || !hasSrc, hidden: loaded && hasSrc})}></tp-icon>
`;
}
static get properties() {
return {
loaded: { type: Boolean },
baseUrl: { type: String },
loading: { type: Boolean },
hasSrc: { type: Boolean },
src: { type: String },
};
}
static get defaultAccountIcon() {
return svg`<path fill="var(--tp-icon-color)" d="m 12,20.64 c -3,0 -5.652,-1.536 -7.2,-3.84 0.036,-2.4 4.8,-3.72 7.2,-3.72 2.4,0 7.164,1.32 7.2,3.72 -1.548,2.304 -4.2,3.84 -7.2,3.84 M 12,3.6 A 3.6,3.6 0 0 1 15.6,7.2 3.6,3.6 0 0 1 12,10.8 3.6,3.6 0 0 1 8.4,7.2 3.6,3.6 0 0 1 12,3.6 M 12,0 A 12,12 0 0 0 0,12 12,12 0 0 0 12,24 12,12 0 0 0 24,12 C 24,5.364 18.6,0 12,0 Z"></path>`;
}
updated(changes) {
if (changes.has('src')) {
if (!this.src) {
this.hasSrc = false;
return;
}
if (this.src !== changes.get('src')) {
this.hasSrc = true;
if (newSrc.indexOf(this.baseUrl) !== 0 && !this.hasSchema(newSrc)) {
this.src = this.baseUrl + this.src;
return;
}
this.loaded = false;
if (Boolean(newSrc)) {
this.loadImage();
}
}
}
}
hasSchema(src) {
return src.indexOf('http://') === 0 || src.indexOf('https://') === 0;
}
loadedChanged() {
if (this.loaded) {
this.$.avatarImg.style.backgroundImage = `url("${this.src}")`;
}
}
loadImage() {
var img = new Image();
img.src = this.src;
this.loading = true;
img.onload = function() {
this.loading = false;
this.loaded = true;
this.loadedChanged();
}.bind(this);
}
}
window.customElements.define('tp-avatar', TpAvatar);