Reputation: 472
I have a Kinetic.Group
and added to its properties the variable actualstatus
. actualstatus
gets changed dynamically by some other JavaScript wether to "1" or "0" (1 = ON 0 = OFF
).
Now, the thing I'm trying to do, is to display the actual status (on or off) with KineticJS. When I used a custom Kinetic.Shape
I could simply do it that way:
var shape = new Kinetic.Shape({
actualstatus: "",
drawFunc: function(canvas){
var ctx = canvas.getContext();
ctx.beginPath();
if(this.actualstatus == "1") ctx.fillStyle = "yellow";
else if(this.actualstatus == "0") ctx.fillStyle = "lightgrey";
ctx.fillRect(0,0,50,50);
ctx.closePath();
}
});
It worked flawlessly, but it wasn't possible to listen for events on it and use more than one ctx.beginPath()
ctx.closePath()
to draw complex widgets.
Because of that, I'm rebuilding it with non-custom Kinetic-Shapes only, which resolves my event and complex drawing problems, but now, it doesn't change its color or text anymore according to the actualstatus
-property of the group, containing all shapes.
So to my question: Is there a way to redraw the shape with new colors etc. every time the actualstatus
-property changes? Or is there a way to listen for actualstatus
- changes?
I hope you can get somehow a image of what I said a little bit complicatedly above :) any help is, of course, greatly appreciated ;)
Upvotes: 3
Views: 2098
Reputation: 472
@markE Thanks for your help and the awesome code-snippet. I wanted to use the KineticJS functions and it now works by setting activestate
with the .setAttrs()
method:
rect.setAttrs({
activestate: "0" //or "1"
});
If you change attributes with .setAttrs()
you can use the attrs-listener provided by KineticJS:
rect.on('activestateChange', function(){
if(activestate == "1")
rect.setFill('yellow');
else if(activestate == "0")
rect.setFill('grey');
});
Upvotes: 1
Reputation: 105035
You can “listen” for when the value of “actualstatus” changes and change colors accordingly
You can do this using javascript getters and setters.
These are 2 functions that become associated with a property (actualstatus) and are fired whenever the property value is requested (the getter) and whenever the property value is assigned (the setter).
// this will trigger the getter function
var test = actualstatus;
// this will trigger the setter function
actualstatus=”1”;
The importance of this is that you can use the setter function to change the actualstatus value…AND…you can also trigger a change to your shape color.
Here’s what the setter function looks like:
function (newValue) {
// change the current value to the new value
this.currentValue = newValue;
// and also change the rectangle’s color based on the newValue
switch(value){
case "0":
myKineticRect.setFill('lightgrey');
break;
case "1":
myKineticRect.setFill('yellow');
break;
default:
myKineticRect.setFill('red');
break;
}
layer.draw();
}
Putting getters/setters to work:
First, declare an object that will contain all the variables we want to “listen” to.
// create a container object for all the Vars we want to "listen" to
var WatchedVars=function(){};
Next tell WatchedVars to add a variable called “actualstatus” that will have a getter and a setter:
// "listen" for gets and sets on "actualstatus"
Object.defineProperty(WatchedVars.prototype,"actualstatus",{
// this is a "private" property that holds the current value of actualstatus
privateValue: "X",
// on get: just return the current value (privateValue)
get: function(){ return(this.privateValue); },
// on set: set the current value
// ...AND(!)... execute the callback handler (actualstatusSetHandler)
set: function(newValue){
this.privateValue=newValue;
actualstatusSetHandler(this.privateValue);
}
});
So whenever you change the value of actualstatus, the setter is called.
// assigning w.actualstatus a value of "1" triggers its setter function
w.actualstatus=”1”;
The setter changes the current value of actualstatus to “1”
The setter also calls actualstatusSetHandler() which fills the rect with yellow color.
And this is the callback that will be executed every time the value of actualstatus changes:
// this handler will get called every time the value of actualstatus changes
// in this case, we change the fill color of a kinetic shape (rect)
function actualstatusSetHandler(value,isTrue){
switch(value){
case "0":
rect.setFill('lightgrey');
break;
case "1":
rect.setFill('yellow');
break;
default:
rect.setFill('red');
break;
}
layer.draw();
}
That’s how to “listen” to variable changes in javascript !
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/Uw4Ht/
<!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-v4.5.1.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:200px;
}
</style>
<script>
$(function(){
// create a container object for all the Vars we want to "listen" to
var WatchedVars=function(){};
// "listen" for gets and sets on "actualstatus"
Object.defineProperty(WatchedVars.prototype,"actualstatus",{
// this is a "private" property that holds the current value of actualstatus
privateValue: "X",
// on get: just return the current value (privateValue)
get: function(){ return(this.privateValue); },
// on set: set the current value
// ...AND(!)... execute the callback handler (actualstatusSetHandler)
set: function(newValue){
this.privateValue=newValue;
actualstatusSetHandler(this.privateValue);
}
});
// this handler will get called every time the value of actualstatus changes
// in this case, we change the fill color of a kinetic shape (rect)
function actualstatusSetHandler(value,isTrue){
switch(value){
case "0":
rect.setFill('lightgrey');
break;
case "1":
rect.setFill('yellow');
break;
default:
rect.setFill('red');
break;
}
layer.draw();
}
// just normal Kinetic stuff
// create stage & layer, add a rectangle
var stage = new Kinetic.Stage({
container: 'container',
width: 200,
height: 200
});
var layer = new Kinetic.Layer();
stage.add(layer);
var rect = new Kinetic.Rect({
x: 30,
y: 30,
width: 100,
height: 30,
fill: "green",
stroke: "gray",
strokeWidth: 3
});
layer.add(rect);
layer.draw();
// create an instance of WatchedVars
var w=new WatchedVars();
// testing...just change the value of actualstatus
$("#set0").click(function(){ w.actualstatus="0"; });
$("#set1").click(function(){ w.actualstatus="1"; });
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
<button id="set0">actualstatus==0</button>
<button id="set1">actualstatus==1</button>
</body>
</html>
Upvotes: 3