gpt4 book ai didi

javascript - 如何排除特定类不受设置为整个页面的色调旋转过滤器的影响

转载 作者:行者123 更新时间:2023-12-04 14:53:42 27 4
gpt4 key购买 nike

我正在开发一项功能,让用户可以选择深色或浅色主题以及应用的主题颜色。我是通过 css 过滤器来实现的,特别是 invert(1) 以获得深色主题和 hue-rotate 以获得主题颜色。暗光部分工作得很好,因为我排除了一些类不受 invert() 过滤器的影响,主要是图像和一些 svgs,只需将 invert(0) 设置为他们。但是,由于主题颜色选择器与范围选择器一起使用以带来许多配色方案,我不能使用相同的方法来排除这些类,因为 hue-rotate() 的度数值随用户选择。如果我能够以编程方式计算相反的色调并将其重新应用到那些类,它仍然可以完成,但由于我的 javascript 知识非常有限,我只是在这个过程中搞砸了。因此,对于实现这一目标的任何可能的帮助,我将不胜感激。

所以我想到了这段代码:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="css/light.css" rel="stylesheet" id="theme-link">
</head>
<body id="usrhue">

<h3><label><b>Theme</b></label></h3>
<input type="checkbox" onchange="toggleTheme()"/>
<h3>Theme Color</h1>
<pre><h3><code id="value">hue-rotate(0deg)</code></h3></pre>
<input id="hue-rotate" step="45" type="range" min="0" max="315" value="0">
<div>
<div class="tile">navbar</div>
<svg class="icon" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" x="0" y="0" width="50" height="33" viewbox="0 0 50 33"><path style="fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 50,16.111089 c -0.0023,-0.52719 -0.269301,-1.175411 -0.836045,-1.837787 L 33.538651,0 l 0,4.099986 10.560199,12.011103 -10.560199,12.011102 0,4.099986 15.625304,-14.273302 C 49.730699,17.286499 49.997802,16.638278 50,16.111089 Z m -50,0 c 0.0022,-0.52719 0.2693022,-1.175411 0.8360452,-1.837787 L 16.46135,0 l 0,4.099986 -10.5601995,12.011103 10.5601995,12.011102 0,4.099986 L 0.8360452,17.948875 C 0.2693022,17.286499 0.0021979,16.638278 0,16.111089 Z"/></svg>
</div>

<img src="https://campstoregear.com/wp-content/uploads/2017/09/summer-camp-2018-apparel-design-CD1816-Primary.png">

</body>
</html>

JS

// Theme Chooser
const theme = document.querySelector('#theme-link');
const currentTheme = localStorage.getItem('theme');

if( currentTheme == 'dark' && theme.getAttribute('href')=='css/light.css' ){
theme.href='css/dark.css';
}

function toggleTheme(){
if( theme.getAttribute('href') == 'css/light.css' ) {
theme.href = 'css/dark.css';
themeName = 'dark';
} else {
theme.href = 'css/light.css';
themeName = 'light';
}
localStorage.setItem( 'theme', themeName );
};

// Theme Color Chooser

const currentThemec = localStorage.getItem('themeColor');
const value = document.getElementById('value');
const body = document.getElementById('usrhue');

if (currentThemec) {
const themeColor = currentThemec;
body.style.filter = currentThemec;
value.textContent = currentThemec;
}

document.getElementById('hue-rotate').oninput = function() {
const filter = 'hue-rotate(xdeg)'.replace('x', this.value);
value.textContent = filter;
body.style.filter = filter;

localStorage.setItem( 'themeColor', body.style.filter );
}

LIGHT.CSS

html {
height:100%;
overflow:hidden;
}

body {
display: flex;
height:100%;
justify-content: center;
align-items:center;
flex-direction:column;
background:#999;
}

input {
margin-bottom:5px;
}

.tile {
width:50px;
height:50px;
display:inline-block;
}

.tile:nth-child(1) {
background: #006648;
}

.tile:nth-child(2) {
background: #007aff;
}

pre {
color:#ff0000;
}

img {
width:5%;
}

h3 {
color:#0000ff;
}

svg {
fill:#007aff;
width:45px;
display: flex;
justify-content: center;
align-items:center;
flex-direction:column;
}

DARK.CSS

深色 css 与浅色相同,但将其添加在底部

html, img, svg, pre, code { filter: invert(1) contrast(1) saturate(1);}

.webp, .png, .jpg { filter: invert(0) contrast(1) saturate(1);}

如您所见,如果您在明暗之间切换,此操作不会影响 svg 图标或图像。

但是当您更改主题颜色时,它们都会受到影响。

所以问题是通过这种方式(也许您可以考虑第二种、第三种、第四种或更多方式)以编程方式为色调范围选择器的每个阶段计算相反的色调并动态地将其应用于这些类来解决这个问题。

我在 inspect dev 工具的帮助下做了一些计算,例如,假设你选择了选择器的第一阶段,45deg,那么如果你应用到 img invert(1) hue-rotate(-45deg) on the dark.css and invert(0) hue-rotate(-45deg) on the light.css,然后针对特定的色调值,图像保持正常。按照同样的思路,很容易计算出所有 7 个值。但是以动态方式应用它们的问题仍然是我有限的 JavaScript 技能的一个大问题。

我也在这里找到了这段代码 How to transform black into any given color using only CSS filters

色调旋转计算

function hueRotate(angle = 0) {
angle = angle / 180 * Math.PI;
let sin = Math.sin(angle);
let cos = Math.cos(angle);

this.multiply([
0.213 + cos * 0.787 - sin * 0.213, 0.715 - cos * 0.715 - sin * 0.715, 0.072 - cos * 0.072 + sin * 0.928,
0.213 - cos * 0.213 + sin * 0.143, 0.715 + cos * 0.285 + sin * 0.140, 0.072 - cos * 0.072 - sin * 0.283,
0.213 - cos * 0.213 - sin * 0.787, 0.715 - cos * 0.715 + sin * 0.715, 0.072 + cos * 0.928 + sin * 0.072
]);}

也许比我有更多js经验和能力的人可以用它来完成我需要的东西。

最佳答案

如果我是对的,您希望将深色主题切换为浅色主题,并在用户选择某种颜色时为 ui 元素着色。我重新设计了一个更像样的 View 。我确实使用了 previrous solution并加以改进。

const value = document.getElementById('value');
const body = document.getElementById('usrhue');
const switcher = document.getElementById('switcher');
const hueRotate = document.getElementById('hue-rotate');

const LIGHT_THEME = 'light';
const DARK_THEME = 'dark';

value.textContent = `Color: Tomato`;
body.classList.add(DARK_THEME);
body.classList.add('tomato');

const toggleTheme = ev => {
if (ev.target.checked) {
body.classList.add(LIGHT_THEME);
body.classList.remove(DARK_THEME);
return;
}
body.classList.add(DARK_THEME);
body.classList.remove(LIGHT_THEME);
};

const setClassName = (name, color, num, el) => {
const colorArr = [
'tomato',
'wood',
'green-gross',
'green-house',
'fun-green',
'sky-blue',
'vivid-violet',
'rose-guns',
];

const className = name.toLowerCase().split(' ').join('-');
colorArr.forEach(col => {
if (col === className) {
return el.classList.add(className);
}
el.classList.remove(col);
});
};

switcher.addEventListener('change', toggleTheme);

hueRotate.oninput = function() {
const filter = 'hue-rotate(xdeg)'.replace('x', this.value);
let name;

switch (this.value) {
case '45':
name = `Wood`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color:${name}`);
case '90':
name = `Green House`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '135':
name = `Green Gross`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '180':
name = `Fun Green`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '225':
name = `Sky Blue`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '270':
name = `Vivid Violet`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '315':
name = `Rose Guns`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
default:
name = `Tomato`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
}
};
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: serif;
}

:root {
--background-color: hsl(240 14% 15% / 1);
--context-color: hsl(217 8% 68% / 1);
--buttons-color: var(--context-color);

--tomato: hsl(0 50% 64% / 1);
--wood: hsl(45 50% 50% / 1);
--green-house: hsl(90 50% 50% / 1);
--green-gross: hsl(135 50% 50% / 1);
--fun-green: hsl(180 50% 50% / 1);
--sky-blue: hsl(225 50% 50% / 1);
--vivid-violet: hsl(270 50% 50% / 1);
--rose-guns: hsl(315 50% 50% / 1);
}
.dark {
--background-color: hsl(240 14% 15% / 1);
--context-color: hsl(217 8% 68% / 1);
--buttons-color: var(--context-color);
}
.light {
--background-color: hsl(217 8% 68% / 1);
--context-color: hsl(240 14% 15% / 1);
--buttons-color: var(--context-color);
}
.tomato {
--buttons-color: var(--tomato);
}
.wood {
--buttons-color: var(--wood);
}
.green-house {
--buttons-color: var(--green-house);
}
.green-gross {
--buttons-color: var(--green-gross);
}
.fun-green {
--buttons-color: var(--fun-green);
}
.sky-blue {
--buttons-color: var(--sky-blue);
}
.vivid-violet {
--buttons-color: var(--vivid-violet);
}
.rose-guns {
--buttons-color: var(--rose-guns);
}

html {
height: 100%;
}

body {
display: grid;
grid-template-columns: 200px minmax(min-content, 500px);
grid-template-rows: 70px max-content;
height: 100%;
align-items: center;
justify-content: center;
padding: 0px 10px 20px 10px;
background-color: var(--background-color);
color: var(--context-color);
}

button {
border-radius: 3px;
background-color: var(--buttons-color);
color: black;
transition: all 0.3s ease-in-out;
}
button:hover {
filter: brightness(0.8);
}

#control {
display: flex;
gap: 50px;
}
#theme-switcher,
#theme-colors {
grid-row: 1;
padding: 10px;
color: var(--context-color);
}
#theme-switcher {
grid-column: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
#theme-colors {
grid-column: 2;
}

#theme-colors p {
color: var(--buttons-color);
}

#example {
padding: 10px;
grid-row: 2;
grid-column: 2;
}
#example h1 {
color: var(--buttons-color);
}
#example p {
padding: 10px 0;
}
#example button {
padding: 5px 15px;
border: none;
cursor: pointer;
}

#images {
grid-column: 1;
grid-row: 2;
}
#images img {
width: 100%;
}
#images svg {
margin: auto;
}

svg {
fill: var(--buttons-color);
width: 45px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
<body id="usrhue">
<div id="theme-switcher">
<h3>Theme Switcher</h3>
<input type="checkbox" id="switcher" />
</div>
<div id="theme-colors">
<h3>Theme Color</h1>
<p id="value"></p>
<input id="hue-rotate" step="45" type="range" min="0" max="315" value="0">
</div>
<section id=example>
<h1>Some title</h1>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Esse dolorem corporis praesentium natus soluta distinctio iure eos facere tenetur, assumenda sequi ducimus architecto provident nobis ad, quia nostrum. Voluptas, expedita.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Adipisci hic alias facilis autem!</p>
<button>Cancel</button>
<button>Submit</button>
</section>
<section id='images'>
<img src="https://campstoregear.com/wp-content/uploads/2017/09/summer-camp-2018-apparel-design-CD1816-Primary.png">
<svg class="icon" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" x="0" y="0" width="50" height="33" viewbox="0 0 50 33"><path style="fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 50,16.111089 c -0.0023,-0.52719 -0.269301,-1.175411 -0.836045,-1.837787 L 33.538651,0 l 0,4.099986 10.560199,12.011103 -10.560199,12.011102 0,4.099986 15.625304,-14.273302 C 49.730699,17.286499 49.997802,16.638278 50,16.111089 Z m -50,0 c 0.0022,-0.52719 0.2693022,-1.175411 0.8360452,-1.837787 L 16.46135,0 l 0,4.099986 -10.5601995,12.011103 10.5601995,12.011102 0,4.099986 L 0.8360452,17.948875 C 0.2693022,17.286499 0.0021979,16.638278 0,16.111089 Z"/></svg>
</section>
</body>

使用本地存储

  const theme = localStorage.getItem('theme');
const swithTheme = localStorage.getItem('switcher');

const value = document.getElementById('value');
const body = document.getElementById('usrhue');
const switcher = document.getElementById('switcher');
const hueRotate = document.getElementById('hue-rotate');

const LIGHT_THEME = 'light';
const DARK_THEME = 'dark';

value.textContent = `Color: Tomato`;

if (!swithTheme) {
localStorage.setItem('switcher', DARK_THEME);
body.classList.add(DARK_THEME);
}

if (swithTheme) {
if (swithTheme === LIGHT_THEME) {
switcher.setAttribute('checked', true);
}
body.classList.add(swithTheme);
}

if (!theme) {
localStorage.setItem(
'theme',
JSON.stringify({
color: 'hue-rotate(0deg)',
num: 0,
name: `Tomato`,
})
);
body.classList.add('tomato');
}

if (theme) {
const LS = JSON.parse(theme);
const className = LS.name.toLowerCase().split(' ').join('-');

body.classList.add(className);
hueRotate.value = LS.num;
value.textContent = `Color: ${LS.name}`;
}

const toggleTheme = ev => {
if (ev.target.checked) {
body.classList.add(LIGHT_THEME);
body.classList.remove(DARK_THEME);
localStorage.setItem('switcher', LIGHT_THEME);
return;
}
body.classList.add(DARK_THEME);
body.classList.remove(LIGHT_THEME);
localStorage.setItem('switcher', DARK_THEME);
};

const setClassName = (name, color, num, el) => {
const colorArr = [
'tomato',
'wood',
'green-gross',
'green-house',
'fun-green',
'sky-blue',
'vivid-violet',
'rose-guns',
];

localStorage.setItem(
'theme',
JSON.stringify({
color,
num,
name,
})
);

const className = name.toLowerCase().split(' ').join('-');
colorArr.forEach(col => {
if (col === className) {
return el.classList.add(className);
}
el.classList.remove(col);
});
};

switcher.addEventListener('change', toggleTheme);

hueRotate.oninput = function () {
const filter = 'hue-rotate(xdeg)'.replace('x', this.value);
let name;

switch (this.value) {
case '45':
name = `Wood`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color:${name}`);
case '90':
name = `Green House`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '135':
name = `Green Gross`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '180':
name = `Fun Green`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '225':
name = `Sky Blue`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '270':
name = `Vivid Violet`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
case '315':
name = `Rose Guns`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
default:
name = `Tomato`;
setClassName(name, filter, this.value, body);
return (value.textContent = `Color: ${name}`);
}
};

关于javascript - 如何排除特定类不受设置为整个页面的色调旋转过滤器的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68579939/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com