Dear GSAPers,
My sincere apologies for the very poor display of code and the lack of codepen example. This is my first post and I was not sure how to provide a more succinct example. Please also note that I am new to TypeScript and am feeling like I am a long way out of my depth so I am not sure how to strip down to the minimal information, or how to make LitElement and its components work in such an environment.
All in all, as far as the code goes, the below class DOES work with the exception of GSAP not being able to find the "active" class element, which is a based on a conditional statement in the code below. I can confirm that the HTML inspector tool does indicate that there is at least one element with a class of "active" present on the page, so as far as I understand it, GSAP SHOULD be able to detect it and apply the relevant animation via the animateStatus() function. It is probably also worth mentioning that the console log inside the animateStatus() function prints 'null'.
Again, I apologise for the poor display of code. If there is a way to make it clearer please let me know.
I would appreciate any help with this.
Kind thanks in advance.
import {
LitElement,
html,
customElement,
property,
} from "@polymer/lit-element";
import gsap from 'gsap';
@customElement("aa-item-button")
export default class ItemButton extends LitElement {
inputIcon!: string;
inputText!: string;
inputLocation!: string;
inputState!: number;
inputStatus!: number;
inputLevel!: number;
constructor() {
super()
// this.animateStatus();
}
// element attributes
static get properties() {
return {
inputIcon: {
type: String,
},
inputText: {
type: String,
},
inputLocation: {
type: String,
},
inputState: {
type: Number,
},
inputStatus: {
type: Number,
},
inputLevel: {
type: Number,
}
}
}
// // blinking light for active status
animateStatus() {
console.log(`Active element is: ${JSON.stringify(this.shadowRoot?.querySelector('.active'))}`)
gsap.to(".active", {
backgroundColor: "#3B90FF",
delay: 0.5,
duration: 0.5,
repeat: -1,
yoyo: true,
})
}
render() {
return html`
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<style>
.active {
background: #003a85;
width: 22px;
height: 12px;
margin-right: 10px;
/* box-shadow: #000 0 -1px 7px 1px, inset #460 0 -1px 9px, #7D0 0 2px 12px; */
}
.inactive {
background-color: red;
width: 22px;
height: 12px;
margin-right: 10px;
}
.online {
width: 22px;
height: 12px;
background-color: #00ff33;
margin-right: 10px;
/* box-shadow: #000 0 -1px 7px 1px, inset #460 0 -1px 9px, #7D0 0 2px 12px; */
}
.offline {
width: 22px;
height: 12px;
background-color: lightgray;
margin-right: 10px;
}
.button-container {
position: relative;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 1rem;
/* padding: 1rem;
width: 302.901px;
height: 363px; */
}
#Button-blank {
position: relative;
}
.contents-container {
position: absolute;
height: 91%;
width: 90%;
}
.input-icon {
display: flex;
align-items: center;
justify-content: center;
color: rgb(130, 130, 130);
max-width: 100%;
line-height: 1.1;
font-size: 200px;
height: 57%;
}
.icon-style {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.icon-container {
position: absolute;
}
.embossed {
color: #f0f0f0;
background-color: #666666;
text-shadow: 1px 4px 4px #555;
text-align: center;
background-clip: text;
-webkit-background-clip: text;
-moz-background-clip: text;
}
.input-text {
display: flex;
align-items: center;
justify-content: center;
font-family: "Segoe UI";
font-size: 2rem;
overflow-wrap: break-word;
font-weight: 600;
color: rgb(130, 130, 130);
max-width: 100%;
line-height: 1.1;
height: 20%;
}
.text-style {
height: 100%;
display: flex;
align-items: flex-start;
justify-content: center;
width: -moz-fit-content;
width: fit-content;
width: 85%;
}
.location-name {
color: rgb(130, 130, 130);
font-weight: 500;
margin: 0.1rem;
height: 6%;
}
.button-statuses {
display: flex;
height: 15%;
width: 100%;
color: rgb(130, 130, 130);
font-weight: 500;
}
.left-cell {
margin-left: 18%;
width: 45%;
}
.status-container {
display: flex;
justify-content: flex-start;
}
.status-light-container {
display: flex;
align-items: center;
justify-content: center;
}
.status-light {
}
.status-text {
}
.state-container {
display: flex;
justify-content: flex-start;
}
.state-light-container {
display: flex;
align-items: center;
justify-content: center;
}
.state-light {
}
.state-text {
}
.right-cell {
width: 45%;
}
.level-container {
display: flex;
justify-content: flex-start;
}
.level-text {
}
</style>
<div class="button-container">
<!-- Button background -->
<svg
id="Button-blank"
data-name="Lights Button"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="302.901"
height="363"
>
<defs>
<linearGradient
id="linear-gradient"
x1="0.5"
y1="1"
x2="0.5"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#b1b1b1" />
<stop offset="0.099" stop-color="#999898" />
<stop offset="0.211" stop-color="#a0a0a0" />
<stop offset="0.32" stop-color="#aca6a6" />
<stop offset="0.411" stop-color="#bebebe" />
<stop offset="0.415" stop-color="#c5c5c5" />
<stop offset="0.515" stop-color="#9f9f9f" />
<stop offset="0.604" stop-color="#908c8c" />
<stop offset="0.703" stop-color="silver" />
<stop offset="0.793" stop-color="#a3a3a3" />
<stop offset="0.905" stop-color="#aeaeae" />
<stop offset="1" stop-color="#898989" />
</linearGradient>
<linearGradient
id="linear-gradient-3"
x1="0.5"
y1="1"
x2="0.5"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#a5a5a5" />
<stop offset="0.099" stop-color="#d3d3d3" />
<stop offset="0.211" stop-color="#a0a0a0" />
<stop offset="0.32" stop-color="#aaa" />
<stop offset="0.411" stop-color="#bebebe" />
<stop offset="0.415" stop-color="#c5c5c5" />
<stop offset="0.515" stop-color="#9f9f9f" />
<stop offset="0.604" stop-color="#8e8e8e" />
<stop offset="0.703" stop-color="silver" />
<stop offset="0.793" stop-color="#a3a3a3" />
<stop offset="0.905" stop-color="#bcbcbc" />
<stop offset="1" stop-color="#898989" />
</linearGradient>
<linearGradient
id="linear-gradient-4"
x1="0.5"
y1="1"
x2="0.5"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#adadad" />
<stop offset="0.099" stop-color="#b3b3b3" />
<stop offset="0.226" stop-color="#f9f9f9" />
<stop offset="0.328" stop-color="#bebebe" />
<stop offset="0.428" stop-color="#adadad" />
<stop offset="0.534" stop-color="#c3c3c3" />
<stop offset="0.646" stop-color="#f3f3f3" />
<stop offset="0.74" stop-color="#c6c6c6" />
<stop offset="0.833" stop-color="#d2d2d2" />
<stop offset="0.924" stop-color="#c4c4c4" />
<stop offset="1" stop-color="#bcbcbc" />
</linearGradient>
</defs>
<g id="BG-shadow">
<g id="Group_3834" data-name="Group 3834">
<path
id="Path_8296"
data-name="Path 8296"
d="M291.6,363H11.4A11.4,11.4,0,0,1,0,351.6V11.4A11.4,11.4,0,0,1,11.4,0H291.5a11.4,11.4,0,0,1,11.4,11.4V351.5A11.27,11.27,0,0,1,291.6,363Z"
fill="#878787"
/>
</g>
</g>
<g id="Background">
<g id="Group_3836" data-name="Group 3836">
<g id="Group_3835" data-name="Group 3835">
<path
id="Path_8297"
data-name="Path 8297"
d="M301.5,351.5a10.029,10.029,0,0,1-10,10H11.5a10.029,10.029,0,0,1-10-10V11.5a10.029,10.029,0,0,1,10-10h280a10.029,10.029,0,0,1,10,10Z"
fill="url(#linear-gradient)"
/>
<path
id="Path_8298"
data-name="Path 8298"
d="M301.5,351.5a10.029,10.029,0,0,1-10,10H11.5a10.029,10.029,0,0,1-10-10V11.5a10.029,10.029,0,0,1,10-10h280a10.029,10.029,0,0,1,10,10Z"
fill="url(#linear-gradient)"
/>
</g>
</g>
<g id="Group_3838" data-name="Group 3838">
<g id="Group_3837" data-name="Group 3837">
<path
id="Path_8299"
data-name="Path 8299"
d="M301.5,351.5a10.029,10.029,0,0,1-10,10H11.5a10.029,10.029,0,0,1-10-10V11.5a10.029,10.029,0,0,1,10-10h280a10.029,10.029,0,0,1,10,10Z"
fill="url(#linear-gradient-3)"
/>
</g>
</g>
</g>
<g id="FG-shadow">
<g id="Group_3839" data-name="Group 3839">
<path
id="Path_8300"
data-name="Path 8300"
d="M11.5,341.5a10.029,10.029,0,0,0,10,10h260a10.029,10.029,0,0,0,10-10V21.5a10.029,10.029,0,0,0-10-10H21.5a10.029,10.029,0,0,0-10,10Z"
fill="#7c7c7c"
/>
</g>
</g>
<g id="Foreground">
<g id="Group_3840" data-name="Group 3840">
<path
id="Path_8301"
data-name="Path 8301"
d="M21,347.5H282a5.549,5.549,0,0,0,5.5-5.5V21a5.549,5.549,0,0,0-5.5-5.5H21A5.549,5.549,0,0,0,15.5,21V342A5.549,5.549,0,0,0,21,347.5Z"
fill="url(#linear-gradient-4)"
/>
</g>
</g>
</svg>
<!-- Button icon -->
<div class="contents-container embossed">
<div class="input-icon material-icons">
<span class="icon-style">${this.inputIcon}</span>
</div>
<!-- Button text -->
<div class="input-text">
<div class="text-style">${this.inputText}</div>
</div>
<!-- Button statuses -->
<div class="location-name">(${this.inputLocation.toUpperCase()})</div>
<div class="button-statuses">
<div class="left-cell">
<div class="status-container">
<div class="status-light-container">
<div class="${this.inputStatus ? "online" : "offline"}"></div>
</div>
<div class="status-text">
${this.inputStatus == 0 ? "Offline" : "Online"}
</div>
</div>
<div class="state-container">
<div class="state-light-container">
<div class="${this.inputState ? "active" : "inactive"}"></div>${this.inputState ? this.animateStatus() : ``}
</div>
<div class="state-text">
${this.inputState == 0 ? "Inactive" : "Active"}
</div>
</div>
</div>
<div class="right-cell">
<div class="level-container">
<div class="level-text">Level: ${this.inputLevel}%</div>
</div>
</div>
</div>
</div>
</div>
`;
}
}