Skip to content

Instantly share code, notes, and snippets.

@mootari
Last active November 5, 2022 15:16
Show Gist options
  • Save mootari/bfbf01320da6c14f9cba186c581d507d to your computer and use it in GitHub Desktop.
Save mootari/bfbf01320da6c14f9cba186c581d507d to your computer and use it in GitHub Desktop.
dat.GUI color scheme selection
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.1/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>(function() {
var config = {
scheme: 'ffffff-000000'
};
var values = d3.range(9).map(function() { return Math.random() * .8 + .1; });
var ui = new dat.GUI();
var c = selectToRadios(ui.add(config, 'scheme', [
'ffffff-000000',
'https://coolors.co/002626-0e4749-95c623-e55812-efe7da',
'https://coolors.co/003049-d62828-f77f00-fcbf49-eae2b7',
'https://coolors.co/20bf55-0b4f6c-01baef-fbfbff-757575',
'https://coolors.co/1a535c-4ecdc4-f7fff7-ff6b6b-ffe66d',
'https://coolors.co/cc211a-234ec3-f6dc28-e8ebf7-acbed8',
'https://coolors.co/5d737e-64b6ac-c0fdfb-daffef-fcfffd',
'https://coolors.co/ff9f1c-ffbf69-ffffff-cbf3f0-2ec4b6',
'https://coolors.co/50514f-f25f5c-ffe066-247ba0-70c1b3'
])).onChange(function() { initColor(); draw(); });
// Only the part after the last slash will be parsed. Slash is optional.
c.__radios.map(colorLabel);
var color;
var ctx = d3.select('body')
.append('canvas')
.attr('width', 600)
.attr('height', 300)
.node().getContext('2d');
initColor();
draw();
function draw() {
var w = ctx.canvas.width / values.length;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
values.map(function(v, i) {
ctx.fillStyle = color(v);
ctx.fillRect(i * w, ctx.canvas.height, w, -ctx.canvas.height * v);
});
}
function initColor() {
color = d3.scaleSequential(
d3.interpolateRgbBasis(
urlToColors(config.scheme)))
.domain([.1, .9]);
}
function urlToColors(url) {
return url.split('/').pop().split('-').map(function(c) {
return '#' + c;
});
}
function colorLabel(label) {
function gradient(colors) {
function stops(color, i, colors) {
return color + ' ' + (i * 100 / colors.length) + '%'
+ ',' + color + ' ' + ((i+1) * 100 / colors.length) + '%';
}
return 'linear-gradient(90deg,' + colors.map(stops) + ')';
}
label.style.display = 'inline-block';
var radio = label.children[0];
radio.nextSibling.remove();
var span = document.createElement('span');
span.style.background = gradient(urlToColors(radio.value));
span.style.paddingRight = '4em';
span.style.marginRight = '.5em';
label.appendChild(span);
}
// Adds and links labeled radios to select controller, hides select.
// Radios are wrapped inside labels and stored in controller.__radios.
function selectToRadios(controller) {
var wrapper = controller.domElement;
var select = wrapper.children[0];
wrapper.parentNode.parentNode.style.height = 'auto';
controller.__radios = Array.prototype.map.call(select.children, function(option, i) {
var radio = document.createElement('input');
radio.type = 'radio';
radio.name = option.name;
radio.value = option.value;
radio.checked = option.selected;
radio.addEventListener('change', function(e) {
option.selected = true;
c.__select.dispatchEvent(new e.constructor(e.type, e));
});
var label = document.createElement('label');
label.appendChild(radio);
label.appendChild(document.createTextNode(option.innerText));
wrapper.appendChild(label);
return label;
});
wrapper.removeChild(select);
return controller;
}
}());
</script>
</body>
@Vamoss
Copy link

Vamoss commented Nov 5, 2022

Super cool!

I removed the D3 dependency and created a function to call it:

function addColorScheme(gui, conf, prop, schemes, callback){
	var c = selectToRadios(gui.add(conf, prop, schemes)).onChange(callback);
	
	// Only the part after the last slash will be parsed. Slash is optional.
	c.__radios.map(colorLabel);

	function colorLabel(label) {
		function gradient(colors) {
			function stops(color, i, colors) {
				 return color + ' ' + (i * 100 / colors.length) + '%'
					 + ',' + color + ' ' + ((i+1) * 100 / colors.length) + '%';
			}
			return 'linear-gradient(90deg,' + colors.map(stops) + ')';
		}

		label.style.display = 'inline-block';
		var radio = label.children[0];
		radio.nextSibling.remove();
		var span = document.createElement('span');
		span.style.background = gradient(urlToColors(radio.value));
		span.style.paddingRight = '4em';
		span.style.marginRight = '.5em';
		label.appendChild(span);
	}

	function urlToColors(url) {
		return url.split('/').pop().split('-').map(function(c) {
			return '#' + c;
		});
	}

	// Adds and links labeled radios to select controller, hides select.
	// Radios are wrapped inside labels and stored in controller.__radios.
	function selectToRadios(controller) {
		var wrapper = controller.domElement;
		var select = wrapper.children[0];

		wrapper.parentNode.parentNode.style.height = 'auto';
		controller.__radios = Array.prototype.map.call(select.children, function(option, i) {
			var radio = document.createElement('input');
			radio.type = 'radio';
			radio.name = option.name;
			radio.value = option.value;
			radio.checked = option.selected;

			radio.addEventListener('change', function(e) {
				option.selected = true;
				c.__select.dispatchEvent(new e.constructor(e.type, e));
			});

			var label = document.createElement('label');
			label.appendChild(radio);
			label.appendChild(document.createTextNode(option.innerText));
			wrapper.appendChild(label);
			return label;
		});
		wrapper.removeChild(select);
		return controller;
	}
}

Usage:

var gui = new dat.GUI();
const schemes = [
	'ffffff-000000',
	'https://coolors.co/002626-0e4749-95c623-e55812-efe7da',
	'https://coolors.co/003049-d62828-f77f00-fcbf49-eae2b7',
	'https://coolors.co/20bf55-0b4f6c-01baef-fbfbff-757575',
	'https://coolors.co/1a535c-4ecdc4-f7fff7-ff6b6b-ffe66d',
	'https://coolors.co/cc211a-234ec3-f6dc28-e8ebf7-acbed8',
	'https://coolors.co/5d737e-64b6ac-c0fdfb-daffef-fcfffd',
	'https://coolors.co/ff9f1c-ffbf69-ffffff-cbf3f0-2ec4b6',
	'https://coolors.co/50514f-f25f5c-ffe066-247ba0-70c1b3'
];
var config = {scheme: 'ffffff-000000'};
function onColorChange(e){
	console.log(e);
}
addColorScheme(gui, config, 'scheme', schemes, onColorChange);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment