JSFiddle - React, Tailwind, and code Playground
by Raphael Quintao
HTML
<div class="mode1 wheel">1</div>
<div class="mode2 wheel"></div>
<div class="mode3 wheel"></div>
<div class="mode4 wheel"></div>
<svg xmlns="http://www.w3.org/2000/svg" class="gradient-svg"
width="150"
viewBox="0 0 100 100">
<circle cx="50" cy="50" r="49" stroke="blue" stroke-width="2"/>
</svg>
<div class="square">
<div class="l"></div>
<div class="r"></div>
</div>
CSS
html {
display: flex;
justify-content: center;
background-color: #333333;
--qp-alpha: 1;
}
body {
display: flex;
flex-wrap: wrap;
background-color: #4f4f4f;
margin: 0;
gap: 10px;
padding: 10px;
}
.wheel {
display: block;
width: 150px;
height: 150px;
border-radius: 50%;
border: 0px solid black;
background-clip: content-box;
}
.mode1 {
background-image: conic-gradient(from 0deg in oklch longer hue, hsl(0, 100%, 50%), hsl(0, 100%, 50%));
/* background-image: conic-gradient(from 0deg in okhsl, red, red); */
/* Optional: Add a shadow for better visual separation */
}
.mode2 {
background-image:
radial-gradient(circle closest-side, white, transparent),
conic-gradient(from 0deg in hsl longer hue, red, red);
}
.mode3 {
background-image:
radial-gradient(
circle closest-side,
hsl(0, 0%, 100%),
hsl(0 0% 0% / 0.0)
),
conic-gradient(from 0deg in hsl longer hue, red, red);
background-size: 100% 100%;
background-repeat: no-repeat no-repeat;
background-blend-mode: hard-light;
}
.gradient-svg {
/* fill: red; */
color: red;
mask-image: conic-gradient(from 0deg in hsl longer hue, red, red);
mask-size: 100%;
}
.square {
width: 150px;
height: 150px;
display: grid;
grid-template-columns: 1fr 1fr;
background-color: black;
--q-base: oklch(0.26 0.07944379 25.84675803);
.l {
background-color: oklch(from var(--q-base) 0.46 c h / 1);
}
.r {
background-color: oklch(from var(--q-base) calc(l + 0.2) c h / 1);
}
}
JavaScript
/**
* Use canvas to generate a color wheel image and set it as the background of the color area.
*/
function gen_color_wheel(size = 150) {
const get_angle = (x, y, center_x, center_y) => {
const angle_rad = Math.atan2(y - center_x, x - center_y);
let angle_deg = (angle_rad * 180) / Math.PI;
if (angle_deg < 0) angle_deg += 360;
return angle_deg;
};
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
// document.body.append(canvas);
// const canvas = new OffscreenCanvas(size + 10, size + 10);
const ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = true;
const width = canvas.width;
const height = canvas.height;
const center_x = width / 2;
const center_y = height / 2;
const max_radius = Math.min(width, height) / 2;
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
const dx = x - center_x;
const dy = y - center_y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= max_radius) {
const hue = get_angle(x, y, center_x, center_y) + 90;
const saturation = (distance / max_radius) * 100;
const lightness = 50;
const alpha = 1;
ctx.fillStyle = `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;
ctx.fillRect(x, y, 1, 1);
}
}
}
return canvas.toDataURL('image/png');
}
const data_url = gen_color_wheel(200);
let el = document.querySelector(".mode4");
el.style.backgroundImage = 'url(' + data_url + ')';
el.style.backgroundPosition = 'center';
el.style.backgroundSize = 'auto';