Circle colors pick
by PhilQ
HTML
<div class="back">
<!-- <div class="overlay"></div> -->
</div>
<input type="color" id="picker" value="#ff0000" />
<button class="add" type="button">Add</button>
<button class="delete" type="button">Delete</button>
SCSS
:root {
--size: 200;
--t: 1;
}
*, ::before, ::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
min-height: 100%;
}
body {
height: auto;
display: flex;
justify-content: center;
align-items: center;
background: #000;
}
.add, .delete, #picker {
position: fixed;
font-size: 1.5rem;
}
.add {
top: 1rem;
left: 1rem;
}
.delete {
top: 4rem;
left: 1rem;
}
#picker {
top: 1rem;
right: 1rem;
}
.back {
position: relative;
display: flex;
width: calc(var(--size) * 2px);
height: calc(var(--size) * 2px);
background-blend-mode: normal;
background-color: #0D1021;
border-radius: 100%;
overflow: hidden;
.color {
--r: 0;
--g: 0;
--b: 0;
--n: 0;
display: flex;
position: absolute;
left: 50%;
top: 50%;
width: calc(var(--size) * 1px);
height: calc(var(--size) * 1px);
border-radius: 100%;
transform-origin: center center;
transform:
translate(-50%, -50%)
rotate(calc((var(--n) / var(--t)) * 360deg))
translate(100%, 0%)
;
mix-blend-mode: normal;
background: radial-gradient(
closest-side,
rgba(
var(--r),
var(--g),
var(--b),
1.0
) 0%,
rgba(
var(--r),
var(--g),
var(--b),
0.0
) 80%,
rgba(
var(--r),
var(--g),
var(--b),
0.0
)
);
}
.overlay {
--c1: 255, 0, 0;
--c2: 0, 255, 0;
--c3: 0, 0, 255;
display: flex;
width: 100%;
height: 100%;
mask-size: 100% 100%;
mask-position: 0 0;
mask-repeat: no-repeat;
mask-image: radial-gradient(
closest-side,
rgba(255, 255, 255, 0.0),
rgba(255, 255, 255, 0.0),
rgba(255, 255, 255, 1.0)
);
mask-mode: alpha;
mix-blend-mode: normal;
background-image:
conic-gradient(
from 0turn at 50% 50%,
rgba(var(--c1), 1.0),
rgba(var(--c1), 0.0),
rgba(var(--c2), 0.0),
rgba(var(--c2), 1.0),
rgba(var(--c2), 0.0),
rgba(var(--c3), 0.0),
rgba(var(--c3), 1.0),
rgba(var(--c3), 0.0),
rgba(var(--c1),...
JavaScript
const root = document.querySelector(':root');
const back = document.querySelector('.back');
const picker = document.querySelector('#picker');
let currentItem = null;
const colors = [
[
28,
196,
87
],
[
255,
213,
0
],
[
224,
93,
6
],
[
209,
51,
51
],
[
223,
58,
129
],
[
87,
60,
226
],
[
18,
119,
253
]
];
colors.forEach(addItem);
picker.addEventListener('change', (e) => {
if (!currentItem || !picker.value) {
return;
}
[
"--r",
"--g",
"--b",
].forEach((c, i) => {
currentItem.style.setProperty(
c,
parseInt(
picker.value.slice(1 + 2*i, 3 + 2*i),
16
)
);
});
});
document.querySelector('button.add')
.addEventListener('click', () => {
addItem([0,0,0], colors.length);
});
document.querySelector('button.delete')
.addEventListener('click', () => {
if (!currentItem) {
return;
}
back.removeChild(currentItem);
root.style.setProperty("--t", back.childElementCount);
selectItem(back.lastElementChild);
});
function addItem(c) {
let i = back.childElementCount;
let o = document.createElement('div');
o.classList.add('color');
o.style.setProperty("--r", c[0]);
o.style.setProperty("--g", c[1]);
o.style.setProperty("--b", c[2]);
o.style.setProperty("--n", i);
root.style.setProperty("--t", i+1);
o.addEventListener('click', (e) => {
selectItem(o);
});
back.appendChild(o);
selectItem(o);
}
function selectItem(o) {
if (!o) {
return;
}
currentItem = o;
const s = getComputedStyle(currentItem);
picker.value = `#${
[
"--r",
"--g",
"--b",
]
.map((v) => String(
parseInt(
s.getPropertyValue(v)
)
.toString(16)
)
.padStart(2, '0')
)
.join('')
}`;
}
function logColors() {
console.log(
[...document.querySelectorAll('.color').values()]
.map(o =>...