<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>
@import url('https://fonts.googleapis.com/css?family=Teko:300,500');
html, body {
  overflow: hidden;
}
body, .picker {
  font-family: 'Teko', 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 + 5vw);
  font-weight: 100;
}
h2 {
  margin-bottom: 0.025em;
  margin-top: -80px;
  font-size: calc(0.8rem + 2.1vw);
}

.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;
}
View Compiled
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();
  });
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.2.2/chroma.min.js
  2. https://cdn.rawgit.com/dtao/nearest-color/master/nearestColor.js
  3. https://codepen.io/meodai/pen/VLVRYw.js
  4. https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js