我正在使用ocanvas设计游戏,我想知道是否有某种方法可以改变精灵的色调。如果没有,有没有办法整合html5画布的方式来改变精灵的色调到ocanvas?
答案 0 :(得分:1)
我没有关于ocanvas的信息,但这里是如何更改绘制到html5画布上的精灵的色调。
此方法使用context.getImageData
来获取画布上每个像素的颜色数据。然后任何具有蓝色色调的像素都会变为绿色色调。
注意:如果你的精灵有更多离散的颜色(f.ex:精灵有一个特定的蓝色,你希望改变为特定的绿色),那么你不需要转换为和来自HSL颜色格式。
如有必要,您可以将此重新塑造的html5画布转换为精灵图像,以使用.toDataURL
包含在ocanvas中。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.crossOrigin="anonymous";
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/marioStanding.png";
function start(){
ctx.drawImage(img,0,0);
ctx.drawImage(img,150,0);
// shift blueish colors to greenish colors
recolorPants(-.33);
}
function recolorPants(colorshift){
var imgData=ctx.getImageData(150,0,canvas.width,canvas.height);
var data=imgData.data;
for(var i=0;i<data.length;i+=4){
red=data[i+0];
green=data[i+1];
blue=data[i+2];
alpha=data[i+3];
// skip transparent/semiTransparent pixels
if(alpha<230){continue;}
var hsl=rgbToHsl(red,green,blue);
var hue=hsl.h*360;
// change blueish pixels to the new color
if(hue>200 && hue<300){
var newRgb=hslToRgb(hsl.h+colorshift,hsl.s,hsl.l);
data[i+0]=newRgb.r;
data[i+1]=newRgb.g;
data[i+2]=newRgb.b;
data[i+3]=255;
}
}
ctx.putImageData(imgData,150,0);
}
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return({
h:h,
s:s,
l:l,
});
}
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return({
r:Math.round(r * 255),
g:Math.round(g * 255),
b:Math.round(b * 255),
});
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<p>Example shifting color Hue with .getImageData</p>
<p>(Original: left, Recolored: right)</p>
<canvas id="canvas" width=300 height=300></canvas>
答案 1 :(得分:1)
另一种流行的解决方案是使用灰度图像并通过canvas中的globalCompositeOperation在JS中对它们进行着色。这里详细描述:http://buildnewgames.com/global-composit-operations/#colored-sprite-masks-with-codesource-atopcode
我汇总了一个如何与oCanvas一起完成的例子:http://jsfiddle.net/g0tj7vrv/
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/ocanvas/2.7.4/ocanvas.min.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
JS:
var canvas = oCanvas.create({
canvas: '#canvas',
background: '#000'
});
canvas.display.register('colorizedImage', {
hue: '',
path: '',
width: 0,
heigth: 0,
_renderNewColor: function(tempImage) {
if (!this._tempCanvas) {
this._tempCanvas = document.createElement('canvas');
}
this._createColorizedImage(this._tempCanvas, tempImage, this.hue);
var self = this;
setTimeout(function() {
self.core.redraw();
}, 0);
},
_createColorizedImage: function(tempCanvas, imageElement, hue) {
var tempContext = tempCanvas.getContext('2d');
tempCanvas.width = imageElement.width;
tempCanvas.height = imageElement.height;
tempContext.drawImage(imageElement, 0, 0);
tempContext.fillStyle = 'hsla(' + hue + ', 50%, 50%, 0.5)';
tempContext.globalCompositeOperation = 'source-atop';
tempContext.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
}
}, function(context) {
if (this._tempCanvas) {
var origin = this.getOrigin();
var x = this.abs_x - origin.x;
var y = this.abs_y - origin.y;
var w = this.width || this._tempCanvas.width;
var h = this.height || this._tempCanvas.height;
context.drawImage(this._tempCanvas, x, y, w, h);
}
if (this.path !== this._lastPathBeingLoaded) {
this._lastPathBeingLoaded = this.path;
var tempImage = new Image();
tempImage.src = this.path;
var self = this;
tempImage.onload = function() {
if (self.path === this.src) {
self._renderNewColor(tempImage);
}
};
this._lastImageElement = tempImage;
}
if (this.hue !== this._lastHueBeingLoaded) {
this._lastHueBeingLoaded = this.hue;
this._renderNewColor(this._lastImageElement);
}
});
var colorizedImage = canvas.display.colorizedImage({
hue: 0,
path: 'https://dl.dropboxusercontent.com/u/2645586/gco/cobra-primary.png',
origin: {x: -60, y: 0},
width: 120,
height: 120,
x: canvas.width / 2,
y: canvas.height / 2
});
canvas.addChild(colorizedImage);
canvas.setLoop(function() {
colorizedImage.hue = (colorizedImage.hue + 10) % 360;
colorizedImage.rotation -= 2;
}).start();