Skip to content

Instantly share code, notes, and snippets.

@califat
Forked from anonymous/index.html
Created June 3, 2017 03:34
Show Gist options
  • Save califat/cccc1f5089f982cee072056f385868c8 to your computer and use it in GitHub Desktop.
Save califat/cccc1f5089f982cee072056f385868c8 to your computer and use it in GitHub Desktop.
mouse position color picker (scroll for saturation)
<div class="js-picker picker">
<svg class="cursor js-cursor" width="278" height="278" viewBox="0 0 278 278" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="#000"><g fill-rule="nonzero" fill="#000"><path class="filter" d="M179.023 128.25c2.18-2.186 2.18-5.68 0-7.866L63.425 4.596c-2.618-2.62-6.107-4.04-9.815-4.04H14.46C6.824.555.61 6.78.61 14.425v39.216c0 3.66 1.47 7.21 4.034 9.83l115.6 115.79c2.18 2.184 5.67 2.184 7.85 0l50.93-51.013z"/><path d="M270.74 259.384c11.23-16.658 7.796-39.324-6.38-53.58l-42.805-42.82 15.704-15.674c2.18-2.184 2.18-5.68 0-7.865l-11.78-11.797c-2.126-2.13-5.452-2.13-7.633-.11l-90.46 90.61c-2.02 2.185-1.964 5.57.108 7.647l11.778 11.797c2.18 2.185 5.67 2.185 7.852 0l15.704-15.675 43.893 43.966c18.05 18.024 48.857 15.894 64.016-6.5z"/></g></g></svg>
<header>
<h2 class="js-picker__colorName">Hot Pink</h2>
<h1 class="js-picker__colorValue">#ff69b4</h1>
</header>
</div>
const $context = document.querySelector('.js-picker');
const $title = document.querySelector('.js-picker__colorValue');
const $subtitle = document.querySelector('.js-picker__colorName');
const $cursor = document.querySelector('.js-cursor');
// global X/Y cursor position
let x = 0; let y = 0;
let cursor = {x:0, y:0, z:0};
// mouseCoordinates <-> color system mapping
let axis = {x: 'h', y: 'l', z: 's'};
// global RAF ticking status
let ticking = false;
// initial color
let color = chroma($title.innerHTML);
// color system information
let hsl = {
h: color.get('hsl.h'),
s: color.get('hsl.s'),
l: color.get('hsl.l'),
};
function place (e) {
let h = e.pageX / $context.clientWidth;
let l = e.pageY / $context.clientHeight;
let $el = document.createElement('div');
$el.classList.add('picked');
$el.style.background = color.hex();
$el.style.left = `${h * 100}%`;
$el.style.top = `${l * 100}%`
$context.appendChild($el);
}
function moveCursor (e) {
hsl[axis.x] = x = e.pageX / Math.round($context.clientWidth * 0.99);
hsl[axis.y] = y = e.pageY / Math.round($context.clientHeight * 0.99);
requestTick();
}
function wheelEvent (e) {
const delta = (e.wheelDelta || e.detail || e.originalEvent.wheelDelta || e.originalEvent.detail) > 0 ? 0.01 : -0.01;
hsl[axis.z] = Math.max(0, Math.min(1, hsl[axis.z] - delta));
requestTick();
}
let oldHex;
function tick () {
let hex = color.set('hsl', [hsl.h * 360,hsl.s,hsl.l]).hex();
if(hex !== oldHex) {
$context.style.background = hex;
$context.style.color = color.luminance() < .4 ? '#fff' : '#000';
$title.innerHTML = hex;
$subtitle.innerHTML = getClosestNamedColor(hex).name;
oldHex = hex;
}
$cursor.style.top = `${y * 100}%`;
$cursor.style.left = `${x * 100}%`;
ticking = false;
}
function requestTick() {
if(!ticking) {
requestAnimationFrame(tick);
ticking = true;
}
}
function zigzag (n, max) {
return max - Math.abs(n % (2*max) - max);
}
if ( !('ontouchstart' in document.documentElement )) {
document.documentElement.addEventListener("mousemove", moveCursor);
document.documentElement.addEventListener("click", place);
$context.addEventListener("mousewheel", wheelEvent, false);
$context.addEventListener("DOMMouseScroll", wheelEvent, false);
} else {
let xyTouch = new Hammer($context);
xyTouch.get('pan').set({ direction: Hammer.DIRECTION_ALL });
xyTouch.on("panleft panright panup pandown", (ev) => {
hsl[axis.x] = x = ev.pointers[0].pageX / $context.clientWidth;
hsl[axis.y] = y = ev.pointers[0].pageY / $context.clientHeight;
/*
let deltaY = ev.deltaY > 0 ? 0.00001 : -0.00001;
let deltaX = ev.deltaX > 0 ? 0.01 : -0.01;
*/
requestTick();
});
let zTouch = new Hammer($context);
zTouch.get('pan').set({ direction: Hammer.DIRECTION_ALL, pointers: 2 });
zTouch.on("panup pandown", (ev) => {
let delta = ev.deltaY > 0 ? 0.01 : -0.01;
hsl[axis.z] = Math.max(0, Math.min(1, hsl[axis.z] - delta));
requestTick();
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.2.2/chroma.min.js"></script>
<script src="//cdn.rawgit.com/dtao/nearest-color/master/nearestColor.js"></script>
<script src="//codepen.io/meodai/pen/VLVRYw"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=Roboto:300,500');
html, body {
overflow: hidden;
}
body, .picker {
font-family: 'Roboto', sans-serif;
min-height: 100vh;
cursor: none;
background: hotpink;
}
.picker {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
.cursor {
z-index: 2;
position: fixed;
width: 2rem; height: 2rem;
top: 110vh;
pointer-events: none;
g {
fill: currentColor;
transition: fill 200ms linear;
}
}
header {
position: fixed;
left: 0;
bottom: 0;
right: 0;
padding: 2vw;
transition: color 200ms linear;
}
h1, h2 {
margin: 0;
padding: 0;
font-weight: 500;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
//cursor: text;
}
h1 {
text-transform: uppercase;
font-size: calc(0.4rem + 3vw);
font-weight: 100;
}
h2 {
margin-bottom: 0.025em;
font-size: calc(0.8rem + 5vw);
}
.picked {
pointer-events: none;
position: fixed;
width: 10vw;
height: 10vw;
border-radius: 100%;
transform: translate(-50%,-50%) scale(.2);
//box-shadow: 0 0 1vw currentColor;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment