@radial-color-picker/vue-color-picker
Version:
Radial Color Picker - Vue
187 lines (180 loc) • 4.66 kB
CSS
/**
* The ColorPicker has 2 tab stops - one for the visual object that the user moves
* and one for the second type of interaction, i.e. selecting a color via the well
*
* @see https://www.w3.org/WAI/ARIA/apg/patterns/slider/
*/
.rcp,
.rcp *,
.rcp *:before {
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
box-sizing: border-box;
border-radius: 50%;
}
.rcp,
.rcp__knob,
.rcp__ripple,
.rcp__well {
aspect-ratio: 1;
}
.rcp {
display: flex;
align-items: center;
justify-content: center;
width: 280px;
position: relative;
transform: scale(1.001);
transition: transform 0.15s cubic-bezier(0.68, 0, 0.47, 2);
}
.rcp:focus {
outline: 0;
}
.rcp:hover .rcp__knob {
box-shadow:
0 0 20px rgba(0, 0, 0, 0.19),
0 0 10px rgba(0, 0, 0, 0.24);
}
/* Allow tapping through the transparent area surrounding the well when collapsed */
.rcp[aria-expanded='false'] {
pointer-events: none;
}
.rcp[aria-expanded='false'] .rcp__well {
pointer-events: auto;
}
/* Slightly scale up the color picker when rotating, but not when tapping the well */
.rcp:active:focus {
transform: scale(1.04);
}
.rcp[aria-disabled='true'] {
cursor: not-allowed;
transform: scale(0.96);
}
.rcp__palette {
position: absolute;
inset: 0;
background-size: 100% 100%;
background-image: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
-webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 53.5%, black 54%);
mask-image: radial-gradient(circle at 50% 50%, transparent 53.5%, black 54%);
will-change: transform, opacity;
transition:
transform 0.5s cubic-bezier(0.35, 0, 0.25, 1),
opacity 0.5s cubic-bezier(0.35, 0, 0.25, 1);
transform: scale(1);
opacity: 1;
}
.rcp[aria-expanded='false'] .rcp__palette {
transform: scale(0);
opacity: 0;
}
.rcp[aria-disabled='true'] .rcp__palette {
filter: contrast(0.25);
}
.rcp__rotator {
position: absolute;
inset: 0;
transform: rotate(var(--rcp-initial-angle));
}
.rcp__knob {
box-shadow:
0 0 10px rgba(0, 0, 0, 0.12),
0 0 5px rgba(0, 0, 0, 0.16);
width: 7%;
/*
* "2.5%" adds distance from the top edge of the rotator to center the knob inside the gradient ring
* "auto" centers the knob horizontally inside the rotator plane
*/
margin-top: 2.5%;
margin-inline: auto;
background-color: #fff;
transition: transform 0.4s cubic-bezier(0.35, 0, 0.25, 1);
outline: 0;
border-style: none;
}
.rcp__knob.in {
transform: scale(1);
}
.rcp__knob.out {
transform: scale(0);
}
.rcp[aria-disabled='true'] .rcp__knob {
box-shadow: none;
pointer-events: none;
}
.rcp__well {
width: 25%;
padding: 0;
margin: 0;
background-color: #ff0000;
outline: 0;
cursor: pointer;
border: 1px solid #b2b2b2;
z-index: 1;
position: relative;
}
.rcp__well:before {
content: '';
position: absolute;
display: block;
inset: 0;
border: 6px solid #fff;
}
.rcp__well::-moz-focus-inner {
border: 0;
}
.rcp:focus-visible .rcp__knob,
.rcp__well:focus-visible {
box-shadow: 0 0 0 2px rgba(160, 174, 192, 0.6);
}
.rcp__well:hover {
border-color: #6b7280;
}
.rcp__well.pressed {
animation: rcp-beat 0.4s cubic-bezier(0.35, 0, 0.25, 1) forwards;
}
.rcp[aria-disabled='true'] .rcp__well {
background-color: #bfbfbf ;
pointer-events: none;
}
.rcp__ripple {
width: 20%;
opacity: 1;
position: absolute;
/* red is just a default initial value which matches the red hue at 0º */
border: 8px solid #ff0000;
}
.rcp__ripple.rippling {
animation: rcp-ripple 0.5s cubic-bezier(0.35, 0, 0.25, 1) forwards;
}
@keyframes rcp-ripple {
0% {
transform: scale(1);
opacity: 0.3;
}
50% {
opacity: 0.1;
}
100% {
opacity: 0;
border-width: 0;
transform: scale(3.8);
}
}
@keyframes rcp-beat {
0% {
transform: scale(1);
}
25% {
transform: scale(0.8);
}
50% {
transform: scale(1);
}
100% {
transform: scale(1);
}
}