Reputation: 146
First of all, I have images with different shapes and i have to recolour them, and set the hit region (for onclick event) only when the mouse is on the shape. So after investigate the problem separately, i have found both solutions, but i dont know how to use both together.
-to use only shape hit region, i use .cache(), to store the image on cache and redraw it without transparent pixels.
-to change the color, i iterate on imageData pixels, to change them one by one inside a for loop.
For testing, i'm using original blue image (.png format) and i want red image with hit regions set properly, also i'm using kinetic-v5.0.2.
this is my code.
function makeKineticImage(imageObj){
var dImage = new Kinetic.Shape({
sceneFunc: function (context) {
context.beginPath();
console.log("sceneFunc");
var x = 100;
var y = 100;
context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
var data = imageData.data;
//Here i'm changing the color
for (var i = 0; i < data.length; i += 4) {
//var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
data[i] = 255;
data[i + 1] = 25;
data[i + 2] = 25;
}
context.putImageData(imageData, x, y);
context.rect(x, y, imageObj.width, imageObj.height);
context.closePath();
context.fillStrokeShape(this);
}
});
dImage.on("click", function() {
console.log("Click dImage");
});
layer.add(dImage);
/*dImage.cache({
width: 79,
height: 73,
x: 100,
y: 100
});
dImage.drawHitFromCache();*/
layer.draw();
layer.drawHit();
}
Now I get my shape filled in other color (red) but hit region dont fit the shape (get all image square), but If I uncomment .cache() and .drawHitFromCache() i get my original image (blue) with hit region only on the shape.
Could you help me? Thank you very much.
Upvotes: 4
Views: 400
Reputation: 36
try this!!!
The relavant part of code is:
dataURL = context.getCanvas().toDataURL("image/png");
var imageObj = new Image(); imageObj.src = dataURL;
function makeKineticImage(imageObj){
var dataURL;
var dImage = new Kinetic.Shape({
sceneFunc: function (context) {
context.beginPath();
console.log("sceneFunc");
var x = 100;
var y = 100;
context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
//var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
data[i] = 255;
data[i + 1] = 25;
data[i + 2] = 25;
}
context.putImageData(imageData, x, y);
context.rect(x, y, imageObj.width, imageObj.height);
context.closePath();
context.fillStrokeShape(this);
dataURL = context.getCanvas().toDataURL("image/png");
console.log(dataURL);
},
hitFunc: function(context) {
console.log("hitFunc");
context.beginPath();
var x = 100;
var y = 100;
context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
//var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
data[i] = 255;
data[i + 1] = 25;
data[i + 2] = 25;
}
context.putImageData(imageData, x, y);
context.rect(x, y, imageObj.width, imageObj.height);
context.closePath();
context.fillStrokeShape(this);
}
});
layer.add(dImage);
layer.draw();
layer.removeChildren();
var imageObj = new Image();
imageObj.src = dataURL;
var kImage = new Kinetic.Image({
image: imageObj,
//x: 100,
//y: 100,
});
kImage.on("click", function() {
console.log("Click dImage");
});
layer.add(kImage);
kImage.cache();
kImage.drawHitFromCache();
layer.draw();
layer.drawHit();
}
Upvotes: 2
Reputation: 105025
I offer an alternative:
recolor your image using an offscreen canvas
create a Kinetic.Image instead of a Kinetic.Shape
set the Image's image property to reference the offscreen canvas
do dImage.cache
, dImage.drawHitFromCach
& drawHit
to create the custom hit region
Here's example code and a Demo: http://jsfiddle.net/m1erickson/kv5Lg/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var canvas=document.createElement("canvas");
var imageObj=new Image();
imageObj.crossOrigin="anonymous";
imageObj.onload=start;
imageObj.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house100x100.png";
function start(){
canvas.width=imageObj.width;
canvas.height=imageObj.height;
var ctx=canvas.getContext("2d");
ctx.drawImage(imageObj,0,0);
var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
data[i] = 255;
data[i + 1] = 25;
data[i + 2] = 25;
}
ctx.putImageData(imageData,0,0);
var dImage=new Kinetic.Image({
x:100,
y:100,
image:canvas,
});
dImage.on("click", function() {
console.log("Click dImage");
});
layer.add(dImage);
layer.draw();
dImage.cache();
dImage.drawHitFromCache();
layer.drawHit();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Upvotes: 1