我有静态大小的调色板我需要它变得更小或更大,anybode可以帮助我,我试图找到我可以改变值,坏结果是坏的。这是较短版本,完整版本为:https://github.com/nilium/harmony
/* PALETTE.JS */
function Palette()
{
var canvas, context, offsetx, offsety, radius = 90,
count = 1080, oneDivCount = 1 / count, countDiv360 = count / 360, degreesToRadians = Math.PI / 180,
i, angle, angle_cos, angle_sin, gradient;
canvas = document.createElement("canvas");
canvas.width = 250;
canvas.height = 250;
offsetx = canvas.width / 2;
offsety = canvas.height / 2;
context = canvas.getContext("2d");
context.lineWidth = 1;
// http://www.boostworthy.com/blog/?p=226
for(i = 0; i < count; i++)
{
angle = i / countDiv360 * degreesToRadians;
angle_cos = Math.cos(angle);
angle_sin = Math.sin(angle);
context.strokeStyle = "hsl(" + Math.floor( (i * oneDivCount) * 360 ) + ", 100%, 50%)";
context.beginPath();
context.moveTo(angle_cos + offsetx, angle_sin + offsety);
context.lineTo(angle_cos * radius + offsetx, angle_sin * radius + offsety);
context.stroke();
}
gradient = context.createRadialGradient(offsetx, offsetx, 0, offsetx, offsetx, radius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
return canvas;
}
/* COLORSELECTOR.JS */
function ColorSelector( gradient )
{
this.init( gradient );
}
ColorSelector.prototype =
{
container: null,
gradientContainer: null,
color: [0, 0, 0],
hueInput: null,
saturationInput: null,
luminosityInput: null,
hue: null,
hueSelector: null,
luminosity: null,
luminositySelector: null,
luminosityData: null,
luminosityPosition: null,
dispatcher: null,
changeEvent: null,
areaDelta: 0,
init: function(gradient)
{
/* DEFINES */
var scope = this, context, hue, hueData;
this.container = document.getElementById('container');
this.gradientContainer = document.getElementById('gradient-container');
this.luminosity = document.getElementById('luminosity');
this.hue = document.getElementById('hue');
this.hueSelector = document.getElementById('hue-selector');
this.luminositySelector = document.getElementById('luminosity-selector');
/* OTHER ASSIGNS */
this.hue.width = gradient.width;
this.hue.height = gradient.height;
this.hueSelector.style.left = ((this.hue.width - 15) / 2 ) + 'px';
this.hueSelector.style.top = ((this.hue.height - 15) / 2 ) + 'px';
this.luminosityPosition = [ (gradient.width - 15), (gradient.height - 15) / 2 ];
this.luminositySelector.style.left = (this.luminosityPosition[0] - 7) + 'px';
this.luminositySelector.style.top = (this.luminosityPosition[1] - 7) + 'px';
/* INITS */
drawSelectorCircles(this.hueSelector.getContext("2d"));
contextHue = this.hue.getContext("2d");
contextHue.drawImage(gradient, 0, 0, this.hue.width, this.hue.height);
hueData = contextHue.getImageData(0, 0, this.hue.width, this.hue.height).data;
contextLum = this.luminositySelector.getContext("2d");
contextLum.drawImage(this.hueSelector, 0, 0, this.luminositySelector.width, this.luminositySelector.height);
/* OTHER */
this.dispatcher = document.createElement('div'); // this could be better handled...
this.changeEvent = document.createEvent('Events');
this.changeEvent.initEvent('change', true, true);
this.gradientContainer.addEventListener('mousedown', onMouseDown, false);
function drawSelectorCircles(ctx) {
ctx.lineWidth = 2;
ctx.strokeStyle = "rgba(0, 0, 0, 0.5)";
ctx.beginPath();
ctx.arc(8, 8, 6, 0, Math.PI * 2, true);
ctx.stroke();
ctx.strokeStyle = "rgba(256, 256, 256, 0.8)";
ctx.beginPath();
ctx.arc(7, 7, 6, 0, Math.PI * 2, true);
ctx.stroke();
}
function onMouseDown( event )
{
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mouseup', onMouseUp, false);
update( event.clientX - scope.container.offsetLeft, event.clientY - scope.container.offsetTop, true );
}
function onMouseMove( event )
{
update( event.clientX - scope.container.offsetLeft, event.clientY - scope.container.offsetTop, false );
}
function onMouseUp( event )
{
window.removeEventListener('mousemove', onMouseMove, false);
window.removeEventListener('mouseup', onMouseUp, false);
update( event.clientX - scope.container.offsetLeft, event.clientY - scope.container.offsetTop, false );
}
//
function updateColorInputs()
{
var hsv = [0,0,0];
var r=scope.color[0], g=scope.color[1], b=scope.color[2];
var mn, mx, dif, ad, dv, md;
mn = Math.min(r, g, b);
mx = Math.max(r, g, b);
if (r > g && r > b) {
dif = g - b;
ad = 0;
} else if (g > b) {
dif = b - r;
ad = 120;
} else {
dif = r - g;
ad = 240;
}
md = mx - mn;
var mdt = 0;
if (md != 0) {
mdt = 1.0 / md;
}
var mxt = 0;
if (mx != 0) {
mxt = 1.0 / mx;
}
hsv[0] = 60 * (dif * mdt) + ad;
if (hsv[0] < 0) {
hsv[0] = 360 + hsv[0];
}
hsv[1] = md * mxt;
hsv[2] = mx;
scope.hueInput = Math.floor(hsv[0]);
scope.saturationInput = Math.floor(hsv[1] * 100);
scope.luminosityInput = Math.floor(hsv[2] / 2.56);
}
function update(x, y, began)
{
var dx, dy, d, nx, ny;
dx = x - 125;
dy = y - 125;
d = Math.sqrt( dx * dx + dy * dy );
if (began) {
scope.areaDelta = d;
}
var pickHue = 0;
if (scope.areaDelta < 90) {
pickHue = 1;
} else if (scope.areaDelta > 100) {
pickHue = 2;
}
if (pickHue == 1)
{
if (d > 89.5) {
var scale = d / 89.5;
dx = Math.floor(dx / scale);
dy = Math.floor(dy / scale);
x = dx + 125;
y = dy + 125;
d = 89.5;
}
scope.hueSelector.style.left = (x - 7) + 'px';
scope.hueSelector.style.top = (y - 7) + 'px';
var index = (x + (y * 250)) * 4;
scope.updateLuminosity( [ hueData[index], hueData[index + 1], hueData[index + 2] ] );
}
else if (pickHue == 2)
{
nx = dx / d;
ny = dy / d;
scope.luminosityPosition[0] = (nx * 110) + 125;
scope.luminosityPosition[1] = (ny * 110) + 125;
scope.luminositySelector.style.left = ( scope.luminosityPosition[0] - 7) + 'px';
scope.luminositySelector.style.top = ( scope.luminosityPosition[1] - 7) + 'px';
}
x = Math.floor(scope.luminosityPosition[0]);
y = Math.floor(scope.luminosityPosition[1]);
scope.color[0] = scope.luminosityData[(x + (y * 250)) * 4];
scope.color[1] = scope.luminosityData[(x + (y * 250)) * 4 + 1];
scope.color[2] = scope.luminosityData[(x + (y * 250)) * 4 + 2];
updateColorInputs();
scope.dispatchEvent( scope.changeEvent );
}
},
//
show: function()
{
this.container.style.visibility = 'visible';
},
getColor: function()
{
return this.color;
},
setColor: function( color )
{
// Ok, this is super dirty. The whole class needs some refactoring, again! :/
var hsb, angle, distance, rgb, degreesToRadians = Math.PI / 180
this.color = color;
hsb = RGB2HSB(color[0] / 255, color[1] / 255, color[2] / 255);
angle = hsb[0] * degreesToRadians;
distance = (hsb[1] / 100) * 90;
this.hueSelector.style.left = ( ( Math.cos(angle) * distance + 125 ) - 7 ) + 'px';
this.hueSelector.style.top = ( ( Math.sin(angle) * distance + 125 ) - 7 ) + 'px';
rgb = HSB2RGB(hsb[0], hsb[1], 100);
rgb[0] *= 255; rgb[1] *= 255; rgb[2] *= 255;
this.updateLuminosity( rgb );
angle = (hsb[2] / 100) * 360 * degreesToRadians;
this.luminosityPosition[0] = ( Math.cos(angle) * 110 ) + 125;
this.luminosityPosition[1] = ( Math.sin(angle) * 110 ) + 125;
this.luminositySelector.style.left = ( this.luminosityPosition[0] - 7 ) + 'px';
this.luminositySelector.style.top = ( this.luminosityPosition[1] - 7 ) + 'px';
this.dispatchEvent( this.changeEvent );
},
//
updateLuminosity: function( color )
{
var context, angle, angle_cos, angle_sin, shade, offsetx, offsety,
inner_radius = 100, outter_radius = 120, i, count = 1080 / 2, oneDivCount = 1 / count, degreesToRadians = Math.PI / 180,
countDiv360 = (count / 360);
offsetx = this.luminosity.width / 2;
offsety = this.luminosity.height / 2;
context = this.luminosity.getContext("2d");
context.lineWidth = 3;
context.clearRect(0, 0, this.luminosity.width, this.luminosity.height);
for(i = 0; i < count; i++)
{
angle = i / countDiv360 * degreesToRadians;
angle_cos = Math.cos(angle);
angle_sin = Math.sin(angle);
shade = 255 - (i * oneDivCount /* / count */) * 255;
context.strokeStyle = "rgb(" + Math.floor( color[0] - shade ) + "," + Math.floor( color[1] - shade ) + "," + Math.floor( color[2] - shade ) + ")";
context.beginPath();
context.moveTo(angle_cos * inner_radius + offsetx, angle_sin * inner_radius + offsety);
context.lineTo(angle_cos * outter_radius + offsetx, angle_sin * outter_radius + offsety);
context.stroke();
}
this.luminosityData = context.getImageData(0, 0, this.luminosity.width, this.luminosity.height).data;
},
//
addEventListener: function( type, listener, useCapture )
{
this.dispatcher.addEventListener(type, listener, useCapture);
},
dispatchEvent: function( event )
{
this.dispatcher.dispatchEvent(event);
},
removeEventListener: function( type, listener, useCapture )
{
this.dispatcher.removeEventListener(type, listener, useCapture);
}
}
/* MAIN.JS */
var BACKGROUND_COLOR = [250, 250, 250];
var container = document.createElement('div');
document.body.appendChild(container);
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
container.appendChild(canvas);
palette = new Palette();
backgroundColorSelector = new ColorSelector(palette);
container.appendChild(backgroundColorSelector.container);
backgroundColorSelector.setColor( BACKGROUND_COLOR );
backgroundColorSelector.addEventListener('change', onBackgroundColorSelectorChange, false);
function onBackgroundColorSelectorChange( event )
{
BACKGROUND_COLOR = backgroundColorSelector.getColor();
document.body.style.backgroundColor = 'rgb(' + BACKGROUND_COLOR[0] + ', ' + BACKGROUND_COLOR[1] + ', ' + BACKGROUND_COLOR[2] + ')';
}
/* COLORUTILS.JS */
function HSB2RGB(hue, sat, val)
{
var red, green, blue,
i, f, p, q, t;
if (val == 0)
return [ 0, 0, 0 ];
hue *= 0.016666667; // /= 60;
sat *= 0.01; // /= 100;
val *= 0.01; // /= 100;
i = Math.floor(hue);
f = hue - i;
p = val * (1 - sat);
q = val * (1 - (sat * f));
t = val * (1 - (sat * (1 - f)));
switch(i)
{
case 0: red = val; green = t; blue = p; break;
case 1: red = q; green = val; blue = p; break;
case 2: red = p; green = val; blue = t; break;
case 3: red = p; green = q; blue = val; break;
case 4: red = t; green = p; blue = val; break;
case 5: red = val; green = p; blue = q; break;
}
return [red, green, blue];
}
function RGB2HSB(red, green, blue)
{
var x, f, i, hue, sat, val;
x = Math.min( Math.min( red, green ), blue );
val = Math.max( Math.max( red, green ), blue );
if (x==val)
return [0, 0, val*100];
f = (red == x) ? green - blue : ((green == x) ? blue - red : red - green);
i = (red == x) ? 3 : ((green == x) ? 5 : 1);
hue = Math.floor((i - f / (val - x)) * 60) % 360;
sat = Math.floor(((val - x) / val) * 100);
val = Math.floor(val * 100);
return [hue, sat, val];
}
&#13;
#container {
position: absolute;
left: 0px;
top: 0px;
width: 400px;
height: 250px;
}
#gradient-container {
position: absolute;
left: 0px;
top: 0px;
width: 250px;
height: 250px;
cursor: pointer;
}
#luminosity {
position: absolute;
left: 0px;
top: 0px;
}
#luminosity-selector {
position: absolute;
}
#hue-selector {
position: absolute;
}
#canvas {
cursror: crosshair;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='container'>
<div id='gradient-container'>
<canvas id='hue' width='' height=''></canvas>
<canvas id='luminosity' width='250' height='250'></canvas>
<canvas id='luminosity-selector' width='15' height='15'></canvas>
<canvas id='hue-selector' width='15' height='15'></canvas>
</div>
</div>
<canvas id='canvas'></canvas>
&#13;