admin管理员组文章数量:1122796
I have a custom HTML element I made that creates a repeating background pattern which I animate in. I need the ability to dynamically set the color of this pattern with a CSS variable that lives in the parent/main document scope.
I know this is possible, but I think the complication is that I am setting the BG pattern as a CSS background image string.
customElements.define(
'svg-background',
class extends HTMLElement {
connectedCallback() {
setTimeout(() => {
// wait till <template> is parsed as DOM
let svg = this.querySelector('template')
.innerHTML.replaceAll(/(\n\s*)|(\<!-- .*? --\>)/g, '') //remove linebreaks & indentations after linebreaks, and comments
.replaceAll('"', "'") //replace double quotes
.replaceAll('#', '%23'); //escape #
Object.assign(this.style, {
backgroundImage: `url("data:image/svg+xml;utf8,${svg}")`,
});
});
}
},
);
function toggleColor(){
document.documentElement.classList.toggle('theme-blue')
}
:root{
--hex-color: red;
}
:root.theme-blue{
--hex-color: blue;
}
svg-background {
position: fixed;
bottom: 0;
left:0;
width: 100vw;
height: 800px;
transform: translateZ(0);
pointer-events: none;
z-index: -1;
}
<button type="button" onclick="toggleColor()">Toggle Color</button>
<svg-background>
<template>
<svg xmlns="" viewBox="0 0 90 800">
<defs>
<style>
use {
animation: 0.4s fade-in-hex;
animation-fill-mode: both;
fill: var(--app-theme-hex);
}
@keyframes fade-in-hex {
from {opacity: 0;}
to {opacity: 1;}
}
#hex-col use:nth-child(1) {animation-delay: 0.9s;}
#hex-col use:nth-child(2) {animation-delay: 0.8s;}
#hex-col use:nth-child(3) {animation-delay: 0.7s;}
#hex-col use:nth-child(4) {animation-delay: 0.6s;}
#hex-col use:nth-child(5) {animation-delay: 0.5s;}
#hex-col use:nth-child(6) {animation-delay: 0.4s;}
#hex-col use:nth-child(7) {animation-delay: 0.3s;}
#hex-col use:nth-child(8) {animation-delay: 0.2s;}
#hex-col use:nth-child(9) {animation-delay: 0.1s;}
</style>
<path id="hex" d="M0 25.980762113533157L15 0L45 0L60 25.980762113533157L45 51.96152422706631L15 51.96152422706631Z" />
</defs>
<!-- We repeat a pattern of 3 columns. One in the middle, and then two on either side that are cut in half so they line up when they meet -->
<g id="hex-col">
<use href="#hex" transform="translate(25 25) scale(.2)" />
<use href="#hex" transform="translate(21 115) scale(.3)" />
<use href="#hex" transform="translate(18 205) scale(.4)" />
<use href="#hex" transform="translate(15 295) scale(.5)" />
<use href="#hex" transform="translate(12 385) scale(.6)" />
<use href="#hex" transform="translate(10 475) scale(.7)" />
<use href="#hex" transform="translate(8 565) scale(.8)" />
<use href="#hex" transform="translate(4 655) scale(.9)" />
<use href="#hex" transform="translate(0 750)" />
</g>
<use href="#hex-col" transform="translate(45 -51)" />
<use href="#hex-col" transform="translate(-45 -51)" />
</svg>
</template>
</svg-background>
I have a custom HTML element I made that creates a repeating background pattern which I animate in. I need the ability to dynamically set the color of this pattern with a CSS variable that lives in the parent/main document scope.
I know this is possible, but I think the complication is that I am setting the BG pattern as a CSS background image string.
customElements.define(
'svg-background',
class extends HTMLElement {
connectedCallback() {
setTimeout(() => {
// wait till <template> is parsed as DOM
let svg = this.querySelector('template')
.innerHTML.replaceAll(/(\n\s*)|(\<!-- .*? --\>)/g, '') //remove linebreaks & indentations after linebreaks, and comments
.replaceAll('"', "'") //replace double quotes
.replaceAll('#', '%23'); //escape #
Object.assign(this.style, {
backgroundImage: `url("data:image/svg+xml;utf8,${svg}")`,
});
});
}
},
);
function toggleColor(){
document.documentElement.classList.toggle('theme-blue')
}
:root{
--hex-color: red;
}
:root.theme-blue{
--hex-color: blue;
}
svg-background {
position: fixed;
bottom: 0;
left:0;
width: 100vw;
height: 800px;
transform: translateZ(0);
pointer-events: none;
z-index: -1;
}
<button type="button" onclick="toggleColor()">Toggle Color</button>
<svg-background>
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 800">
<defs>
<style>
use {
animation: 0.4s fade-in-hex;
animation-fill-mode: both;
fill: var(--app-theme-hex);
}
@keyframes fade-in-hex {
from {opacity: 0;}
to {opacity: 1;}
}
#hex-col use:nth-child(1) {animation-delay: 0.9s;}
#hex-col use:nth-child(2) {animation-delay: 0.8s;}
#hex-col use:nth-child(3) {animation-delay: 0.7s;}
#hex-col use:nth-child(4) {animation-delay: 0.6s;}
#hex-col use:nth-child(5) {animation-delay: 0.5s;}
#hex-col use:nth-child(6) {animation-delay: 0.4s;}
#hex-col use:nth-child(7) {animation-delay: 0.3s;}
#hex-col use:nth-child(8) {animation-delay: 0.2s;}
#hex-col use:nth-child(9) {animation-delay: 0.1s;}
</style>
<path id="hex" d="M0 25.980762113533157L15 0L45 0L60 25.980762113533157L45 51.96152422706631L15 51.96152422706631Z" />
</defs>
<!-- We repeat a pattern of 3 columns. One in the middle, and then two on either side that are cut in half so they line up when they meet -->
<g id="hex-col">
<use href="#hex" transform="translate(25 25) scale(.2)" />
<use href="#hex" transform="translate(21 115) scale(.3)" />
<use href="#hex" transform="translate(18 205) scale(.4)" />
<use href="#hex" transform="translate(15 295) scale(.5)" />
<use href="#hex" transform="translate(12 385) scale(.6)" />
<use href="#hex" transform="translate(10 475) scale(.7)" />
<use href="#hex" transform="translate(8 565) scale(.8)" />
<use href="#hex" transform="translate(4 655) scale(.9)" />
<use href="#hex" transform="translate(0 750)" />
</g>
<use href="#hex-col" transform="translate(45 -51)" />
<use href="#hex-col" transform="translate(-45 -51)" />
</svg>
</template>
</svg-background>
Share
Improve this question
asked Nov 21, 2024 at 22:17
Chris BarrChris Barr
33.9k28 gold badges102 silver badges150 bronze badges
2
|
1 Answer
Reset to default 2I would use it as a mask instead and control the color using the background
customElements.define(
'svg-background',
class extends HTMLElement {
connectedCallback() {
setTimeout(() => {
// wait till <template> is parsed as DOM
let svg = this.querySelector('template')
.innerHTML.replaceAll(/(\n\s*)|(\<!-- .*? --\>)/g, '') //remove linebreaks & indentations after linebreaks, and comments
.replaceAll('"', "'") //replace double quotes
.replaceAll('#', '%23'); //escape #
Object.assign(this.style, {
mask: `url("data:image/svg+xml;utf8,${svg}")`,
});
});
}
},
);
function toggleColor(){
document.documentElement.classList.toggle('theme-blue')
}
:root{
--hex-color: red;
}
:root.theme-blue{
--hex-color: blue;
}
svg-background {
position: fixed;
bottom: 0;
left:0;
width: 100vw;
height: 800px;
transform: translateZ(0);
pointer-events: none;
z-index: -1;
background: var(--hex-color)
}
<button type="button" onclick="toggleColor()">Toggle Color</button>
<svg-background>
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 800">
<defs>
<style>
use {
animation: 0.4s fade-in-hex;
animation-fill-mode: both;
fill: #000;
}
@keyframes fade-in-hex {
from {opacity: 0;}
to {opacity: 1;}
}
#hex-col use:nth-child(1) {animation-delay: 0.9s;}
#hex-col use:nth-child(2) {animation-delay: 0.8s;}
#hex-col use:nth-child(3) {animation-delay: 0.7s;}
#hex-col use:nth-child(4) {animation-delay: 0.6s;}
#hex-col use:nth-child(5) {animation-delay: 0.5s;}
#hex-col use:nth-child(6) {animation-delay: 0.4s;}
#hex-col use:nth-child(7) {animation-delay: 0.3s;}
#hex-col use:nth-child(8) {animation-delay: 0.2s;}
#hex-col use:nth-child(9) {animation-delay: 0.1s;}
</style>
<path id="hex" d="M0 25.980762113533157L15 0L45 0L60 25.980762113533157L45 51.96152422706631L15 51.96152422706631Z" />
</defs>
<!-- We repeat a pattern of 3 columns. One in the middle, and then two on either side that are cut in half so they line up when they meet -->
<g id="hex-col">
<use href="#hex" transform="translate(25 25) scale(.2)" />
<use href="#hex" transform="translate(21 115) scale(.3)" />
<use href="#hex" transform="translate(18 205) scale(.4)" />
<use href="#hex" transform="translate(15 295) scale(.5)" />
<use href="#hex" transform="translate(12 385) scale(.6)" />
<use href="#hex" transform="translate(10 475) scale(.7)" />
<use href="#hex" transform="translate(8 565) scale(.8)" />
<use href="#hex" transform="translate(4 655) scale(.9)" />
<use href="#hex" transform="translate(0 750)" />
</g>
<use href="#hex-col" transform="translate(45 -51)" />
<use href="#hex-col" transform="translate(-45 -51)" />
</svg>
</template>
</svg-background>
本文标签: javascriptHow to use a CSS variable inside a custom HTML elementStack Overflow
版权声明:本文标题:javascript - How to use a CSS variable inside a custom HTML element? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736306900a1933122.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
<template>
,setTimeout
and allreplace
stuff; and you can usecurrentColor
. Maybe even generate the SVG (columns) client-side instead of a static SVG, that will make it easier to adjust spacing, scale etc. as well. – Danny '365CSI' Engelman Commented Nov 22, 2024 at 9:32