Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit d66d4e3e4747cece583080b812ba4c169886a5e1 Lea Verou committed Sep 14, 2011
Showing with 325 additions and 0 deletions.
  1. +23 −0 README.md
  2. +136 −0 colors.js
  3. +38 −0 index.html
  4. +128 −0 style.css
@@ -0,0 +1,23 @@
+# [CSS.coloratum](http://css.coloratum.com)
+
+## Purpose
+CSS.coloratum is a nifty little tool that helps you:
+
+* Share colors with friends and colleagues (never have to go through describing a shade again, just give them the link!)
+* Check out what RGB & HSL values correspond to that color keyword you keep using
+* Covert HSL to RGB, because you're done with your prototype and now it has to work in IE8 too
+* ...and much more!
+
+## Technical details (cause we're geeks after all!)
+CSS.coloratum is built with cutting edge open web technologies, so it only works with modern browsers. In its 3KB, it makes use of cool new technologies like:
+
+* HTML5: canvas, autofocus, output, oninput event, hashchange event
+* CSS3: gradients, media queries, box-sizing, background-clip, border-radius, shadows, RGBA
+* ES5: Array#map()
+* Selectors API
+
+## Links
+
+* CSS.coloratum is one of my 2 entries to the 10K contest. If you like it, [vote for it](http://10k.aneventapart.com/Entry/Details/538)!
+* [My blog post about it](http://leaverou.me/2011/09/css-coloratum-convert-and-share-css-colors/)
+* It's released under an MIT-like License, like most of my stuff. In short, do whatever the eff you want with it, as long as you give me credit in some decent way.
136 colors.js
@@ -0,0 +1,136 @@
+function $(expr) { return document.querySelector(expr); }
+function $$(expr) { return document.querySelectorAll(expr); }
+
+var body = document.body,
+ canvas = document.createElement('canvas'),
+ ctx = canvas.getContext('2d'),
+ input = $('#color'),
+ form = $('form'),
+ out = $$('output > input');
+
+canvas.width = canvas.height = 16;
+body.appendChild(canvas);
+
+form.onsubmit = function(e) {
+ e && e.preventDefault();
+
+ var color = input.value.trim(),
+ previous = body.style.backgroundColor;
+
+ body.style.backgroundColor = '';
+ body.style.backgroundColor = color;
+
+ if(!body.style.backgroundColor) {
+ body.style.backgroundColor = previous;
+ input.className = 'invalid';
+ return;
+ }
+
+ input.removeAttribute('class');
+
+ ctx.fillStyle = color;
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fillRect(0, 0, 16, 16);
+
+ // Get RGB
+ var rgb = [].slice.apply(ctx.getImageData(0, 0, 1, 1).data);
+
+ if(rgb[3] === 255) {
+ rgb.length = 3;
+ }
+
+ var hex = rgb.map(function(a) {
+ return (a < 16? '0' : '') + a.toString(16);
+ }).join('');
+
+ if(rgb.length === 3) {
+ if(/(([\da-z])\2){3}/i.test(hex)) {
+ hex = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
+ }
+ }
+
+ out[1].value = '#' + hex;
+
+ if(rgb.length > 3) {
+ rgb[3] = ('' + Math.round(rgb[3] / 2.55) / 100).replace('0.', '.');
+ }
+
+ out[0].value = 'rgb' + (rgb.length > 3? 'a' : '') + '(' + rgb.join(', ') + ')';
+
+
+ // Now it's HSL's turn
+ if(color.indexOf('hsl') === 0) {
+ out[2].value = color.replace('0.', '.');
+ }
+ else {
+ rgb[0] /= 2.55; rgb[1] /= 2.55; rgb[2] /= 2.55;
+
+ var hsl = [],
+ max = Math.max.apply(Math, rgb),
+ min = Math.min.apply(Math, rgb);
+
+ hsl[2] = Math.round((min + max)/2);
+
+ var d = max - min;
+
+ if(d !== 0) {
+ hsl[1] = Math.round(d*100 / (100 - Math.abs(2*hsl[2] - 100))) + '%';
+
+ switch(max){
+ case rgb[0]: hsl[0] = (rgb[1] - rgb[2]) / d + (rgb[1] < rgb[2] ? 6 : 0); break;
+ case rgb[1]: hsl[0] = (rgb[2] - rgb[0]) / d + 2; break;
+ case rgb[2]: hsl[0] = (rgb[0] - rgb[1]) / d + 4;
+ }
+
+ hsl[0] = Math.round(hsl[0]*60);
+ hsl[2] += '%';
+ }
+ else {
+ hsl[0] = 0;
+ hsl[1] = '0%';
+ }
+
+ if(rgb.length > 3) {
+ hsl[3] = rgb[3];
+ }
+
+ out[2].value = 'hsl' + (hsl.length > 3? 'a' : '') + '(' + hsl.join(', ') + ')';
+ }
+
+ $('link[rel="shortcut icon"]').setAttribute('href', canvas.toDataURL());
+ document.title = color + ' ✿ CSS.coloratum';
+
+ if(history.pushState) {
+ history.pushState(null, null, '#' + encodeURIComponent(input.value));
+ }
+
+ return false;
+};
+
+input.onblur = function() {
+ if(input.className) {
+ return;
+ }
+
+ var hashchange = onhashchange;
+ window.onhashchange = null;
+ location.hash = '#' + encodeURIComponent(input.value);
+ window.onhashchange = hashchange;
+}
+
+input.oninput = function() { form.onsubmit() };
+
+(onhashchange = function() {
+ var color = location.hash.slice(1) || 'slategray';
+
+ try {
+ input.value = decodeURIComponent(color);
+ }
+ catch(e) { input.value = color };
+
+ form.onsubmit();
+})();
+
+for(var i=0; i<out.length; i++) {
+ out[i].onclick = function () { this.select(); }
+}
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<meta charset="utf-8" />
+<title>CSS.coloratum: Convert and share CSS colors</title>
+<link rel="stylesheet" href="style.css" />
+<link rel="shortcut icon" type="image/png" href="about:blank" />
+<meta name="keywords" content="RGB, HSL, RGBA, HSLA, hex, color keywords, convert, conversion" />
+</head>
+<body>
+
+<h1><a href="#">CSS.coloratum</a></h1>
+<form>
+ <label>
+ Type a CSS color <span>keyword, #hex, hsl(), rgba(), whatever</span>:
+ <input type="text" name="color" id="color" value="slategray" autofocus />
+ </label>
+ <output for="color"><input id="rgb" readonly /></output>
+ <output for="color"><input id="hex" readonly /></output>
+ <output for="color"><input id="hsl" readonly /></output>
+</form>
+<footer>
+ By <a href="http://leaverou.me">Lea Verou</a>
+ ✿ <a href="http://www.w3.org/TR/css3-color/">Specification</a>
+ ✿ <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=me%40leaverou%2eme&lc=GR&item_name=Lea%20Verou&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted" rel="nofollow">Donate</a>
+</footer>
+
+<script src="colors.js"></script>
+
+<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://css.coloratum.com" data-count="vertical" data-via="LeaVerou">Tweet</a>
+<script src="http://platform.twitter.com/widgets.js"></script>
+
+<script>_gaq = [['_setAccount', 'UA-25106441-2'], ['_trackPageview']];</script>
+<script src="http://www.google-analytics.com/ga.js" async></script>
+
+</body>
+</html>
128 style.css
@@ -0,0 +1,128 @@
+* {
+ margin: 0;
+}
+
+html {
+ background: white;
+ background: -moz-repeating-linear-gradient(-45deg, white, white 50px, black 50px, black 100px);
+ background: -ms-repeating-linear-gradient(-45deg, white, white 50px, black 50px, black 100px);
+ background: -o-repeating-linear-gradient(-45deg, white, white 50px, black 50px, black 100px);
+ background: -webkit-repeating-linear-gradient(-45deg, white, white 50px, black 50px, black 100px);
+ background: repeating-linear-gradient(-45deg, white, white 50px, black 50px, black 100px);
+ height: 100%;
+}
+
+body {
+ min-height: 100%;
+ background: slategray;
+ color: rgba(0,0,0,.6);
+ font-family: 'Palatino Linotype', Palatino, Georgia, serif;
+ font-size: 110%;
+ text-align: center;
+}
+
+form {
+ width: 30em;
+ margin: auto;
+ padding: 1em 1.2em 1.2em;
+ background: rgba(0,0,0,.6);
+ background-image: -moz-linear-gradient(transparent, rgba(0,0,0,.5));
+ background-image: -ms-linear-gradient(transparent, rgba(0,0,0,.5));
+ background-image: -o-linear-gradient(transparent, rgba(0,0,0,.5));
+ background-image: -webkit-linear-gradient(transparent, rgba(0,0,0,.5));
+ background-image: linear-gradient(transparent, rgba(0,0,0,.5));
+ color: white;
+ font-size: 90%;
+ text-shadow: 1px 1px .3em rgba(0,0,0,.6);
+ border-radius: 1.5em;
+}
+
+input {
+ display: block;
+ width: 100%;
+ padding: .4em 0 .2em;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ font-family: Consolas, 'Andale Mono', 'Lucida Console', monospace;
+ font-weight: bold;
+ text-align: inherit;
+ outline: none;
+}
+
+input:focus {
+ box-shadow: 2px 2px 8px rgba(0,0,0,.7) inset;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+h1 {
+ overflow: hidden;
+ padding-top: .8em;
+ font-size: 340%;
+ line-height: .37;
+}
+
+span {
+ color: rgba(255,255,255,.5);
+ font-weight: normal;
+}
+
+label {
+ display: block;
+}
+
+ label span {
+ font-style: italic;
+ }
+
+ label input {
+ border: 8px solid rgba(0,0,0,.3);
+ background-clip: padding-box;
+ font-size: 210%;
+ border-radius: 15px;
+ }
+
+ input.invalid {
+ border-color: rgba(200,0,0,.4);
+ }
+
+label + output {
+ display: block;
+ margin-top: .5em;
+}
+
+ output > input {
+ background: transparent;
+ border: 0;
+ color: inherit;
+ font-size: 180%;
+ text-shadow: inherit;
+ border-radius: 10px;
+ }
+
+canvas {
+ display: none;
+}
+
+footer {
+ margin-top: .3em;
+ font-weight: bold;
+ color: rgba(0,0,0,.8);
+}
+
+.twitter-share-button {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+}
+
+@media (max-width: 500px) {
+ body { font-size: 90%; }
+}
+
+@media (max-width: 400px) {
+ body { font-size: 80%; }
+}

0 comments on commit d66d4e3

Please sign in to comment.