Skip to content

Instantly share code, notes, and snippets.

@MichinobuMaeda
Last active December 22, 2015 14:28
Show Gist options
  • Save MichinobuMaeda/6485888 to your computer and use it in GitHub Desktop.
Save MichinobuMaeda/6485888 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<!--
Copyright 2013 Michinobu Maeda.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="jquery-1.10.2.min.js"></script>
<script>
// Mouse Left Button is on / off.
var mouseLeftButton = false;
// Utilities
function strRgb(rgb) {
if (rgb) {
return "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
} else {
return "rgb(-,-,-)";
}
}
function strFfffff(rgb) {
var toFf = function(x) {
return ("0" + x.toString(16)).slice(-2).toUpperCase();
}
if (rgb) {
return'#' + toFf(rgb.r) + toFf(rgb.g) + toFf(rgb.b);
} else {
return "#------";
}
}
function fontMonospace(sz) {
return "" + sz + "px Monaco, 'Lucida Console', monospace"
}
// RGB cube ( 16 x 16 x 16 ) | cross section ( White - CMY - RGB - Black )
function Figure(base) {
this.left = base.offsetLeft;
this.top = base.offsetTop;
this.width = base.width;
this.height = base.height;
this.backgroundColor = base.style.backgroundColor;
this.ctx = base.getContext("2d");
// 0x00, 0x11, 0x22 ... 0xFF
this.colorDelta = 0x11;
this.colorMax = 0xFF;
this.depth = this.colorMax / this.colorDelta + 1;
// Layer 0 : #FFFFFF
// ...
// Layer 15 : #00FFFF, #FF00FF, #FFFF00
// ...
// Layer 30 : #FF0000, #00FF00, #0000FF
// ...
// Layer 45 : #000000
this.layerCount = 46;
this.lo = this.height / (this.layerCount + 1);
this.ld = (this.height - this.lo) / this.layerCount;
function Coordinate(radius, xo, yo, xd, yd, ld, twist) {
this.radius = radius;
this.xo = xo;
this.yo = yo;
this.xd = xd;
this.yd = yd;
this.ld = ld;
this.twist = twist;
this.xr = this.xd * 0;
this.yr = this.yd * 2;
this.xg = this.xd * Math.sqrt(3);
this.yg = this.yd * (-1);
this.xb = this.xd * (-1 * Math.sqrt(3));
this.yb = this.yd * (-1);
}
var cbUnit = {
x: this.width / 2 / this.depth,
y: this.ld,
};
this.coordinateCube = new Coordinate(
cbUnit.x / 6,
this.width / 4,
cbUnit.y,
cbUnit.x / this.depth / 4,
cbUnit.y / this.depth / 64,
this.ld,
this.width / 8
);
var csUnit = {
x: Math.min(this.width / 2, this.height / 1.5) / this.depth,
y: Math.min(this.width / 2, this.height / 1.5) / this.depth
};
this.coordinateCrossSection = new Coordinate(
csUnit.x / 2.2,
this.width / 4 * 3,
this.height / 2 + this.ld * 4,
csUnit.x / this.depth / 4,
csUnit.y / this.depth / 4,
0,
0
);
// Draw.
this.drawCube();
this.setLayer(0);
}
Figure.prototype.drawLayer = function(layer, c) {
for (var r = 0; r <= this.colorMax; r += this.colorDelta) {
for (var g = 0; g <= this.colorMax; g += this.colorDelta) {
for (var b = 0; b <= this.colorMax; b += this.colorDelta) {
if (layer * this.colorDelta == this.colorMax * 3 - (r + g + b)) {
var x = c.xo + (c.xr * r) + (c.xg * g) + (c.xb * b);
if (c.twist) {
x += r / c.twist - g / c.twist / 2 - b / c.twist / 2;
}
var y = c.yo + c.ld * layer + (c.yr * r) + (c.yg * g) + (c.yb * b);
this.ctx.fillStyle = strRgb({r:r, g:g, b:b});
this.ctx.beginPath();
this.ctx.arc(x, y, c.radius, 0, Math.PI * 2);
this.ctx.fill();
}
}
}
}
};
Figure.prototype.drawCube = function() {
for (var l = this.layerCount - 1; 0 <= l; --l) {
this.drawLayer(l, this.coordinateCube);
}
};
Figure.prototype.drawCrossSection = function() {
this.drawLayer(this.layer, this.coordinateCrossSection);
};
Figure.prototype.drawCursor = function() {
var xo = this.width / 2;
var sz = this.ld * 0.75;
var bar = {
w: sz / 2,
h: this.ld * (this.layerCount - 1),
};
var grd = this.ctx.createLinearGradient(0, 0, 0, bar.h);
grd.addColorStop(0, "white");
grd.addColorStop(1, "black");
this.ctx.fillStyle = grd;
this.ctx.fillRect(xo, this.lo, bar.w, bar.h);
this.ctx.beginPath(0,0);
this.ctx.moveTo(xo - sz, this.lo + (this.ld * this.layer));
this.ctx.lineTo(xo + sz, this.lo + (this.ld * this.layer) - sz);
this.ctx.lineTo(xo + sz, this.lo + (this.ld * this.layer) + sz);
this.ctx.fillStyle = strRgb({r:0xDD, g:0xDD, b:0xDD});
this.ctx.fill();
}
Figure.prototype.setLayer = function(layer) {
var xo = base.width / 2 - this.ld;
var yo = 0;
layer = Math.min(Math.max(0, layer), this.layerCount - 1);
if (this.layer == layer) { return; }
this.layer = layer;
this.ctx.fillStyle = this.backgroundColor;
this.ctx.fillRect(xo, yo, base.width - xo, base.height - yo);
this.drawCrossSection();
this.drawCursor();
this.showRgbValue(null);
}
Figure.prototype.onSelectLayer = function(m) {
if (m.x < this.width / 2 + this.ld) {
this.setLayer(Math.round((m.y - this.lo) / this.ld, 0));
}
};
Figure.prototype.showRgbValue = function(rgb) {
var xt = base.width / 2 + this.ld * 2;
var ft = this.ld * 2;
var yt = ft + this.ld;
this.ctx.fillStyle = this.backgroundColor;
this.ctx.fillRect(xt, 0, base.width, yt * 2 + ft / 2);
this.ctx.fillStyle = strRgb({r:0xFF, g:0xFF, b:0xFF});
this.ctx.font = fontMonospace(ft);
this.ctx.fillText(strFfffff(rgb), xt, yt);
this.ctx.fillText(strRgb(rgb), xt, yt * 2);
};
Figure.prototype.onSelectCrossSectionDot = function(m) {
var c = this.coordinateCrossSection;
if (m.x <= this.width / 2 + this.ld) {
this.showRgbValue(null);
return;
}
for (var r = 0; r <= this.colorMax; r += this.colorDelta) {
for (var g = 0; g <= this.colorMax; g += this.colorDelta) {
for (var b = 0; b <= this.colorMax; b += this.colorDelta) {
if (this.layer * this.colorDelta == this.colorMax * 3 - (r + g + b)) {
var x = c.xo + (c.xr * r) + (c.xg * g) + (c.xb * b) - m.x;
var y = c.yo + (c.yr * r) + (c.yg * g) + (c.yb * b) - m.y;
if (Math.pow(x, 2) + Math.pow(y, 2) <= Math.pow(c.radius, 2)) {
this.showRgbValue({r:r, g:g, b:b});
return;
}
}
}
}
}
this.showRgbValue(null);
};
Figure.prototype.getMousePos = function(e) {
return {
x: e.pageX - this.left,
y: e.pageY - this.top,
};
};
$(document).ready(function (){
// Initialize.
var figure = new Figure($("#base").get(0));
// Register event listeners.
$("#base").on("click", function(e) {
figure.onSelectLayer(figure.getMousePos(e));
});
$(document).on("mousedown", function(e){
if(e.which === 1) { mouseLeftButton = true; };
});
$(document).on("mouseup", function(e){
if(e.which === 1) { mouseLeftButton = false; };
});
$("#base").on("mousemove", function(e) {
if (mouseLeftButton) {
figure.onSelectLayer(figure.getMousePos(e));
} else {
figure.onSelectCrossSectionDot(figure.getMousePos(e));
}
});
// Demo
var cursorDown = function() {
figure.setLayer(figure.layer + 1);
if (figure.layer >= 20) { return; }
setTimeout(cursorDown, 100);
}
setTimeout(cursorDown, 500);
});
</script>
<title>RGB Colors</title>
</head>
<body style="margin: 0; padding: 0; background-color: #999999;">
<h1 style="color: white; padding: 0 0.5em; margin: 0;">RGB Colors</h1>
<canvas id="base" width="720" height="480"
style="background-color: #777777;"></canvas>
</body>
</html>
@MichinobuMaeda
Copy link
Author

@MichinobuMaeda
Copy link
Author

どっちみち古いIEは対応していないので ondrag* イベント使った方が良かったかもしれない。

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