HTML5 canvas challenge!
q1: is it possible to have an invisible rectangle?
q2: is it possible to call method upon method? See below.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "";
ctx.strokeStyle = "";
// as far FF 3.67 goes, no way
// the goal is to fill the rectangle with some text
ctx.fillRect(50,50,50,20).fillText("you rock",250,250);
Tha开发者_开发技巧nks.
q1: is it possible to have an invisible rectangle?
Indeed it is!
ctx.fillStyle = 'rgba(255,255,255,0)';
ctx.fillRect(50,50,50,20);
Though this also works, and is a bit more concise:
;
q2: is it possible to call method upon method?
Conceivably you could do something like this:
//Naive generic chainer function
//returns this even if the default
//value is significant!
function chain(obj) {
function F() {}
F.prototype = obj;
var cobj = new F();
for (var i in obj) {
if (typeof obj[i] == 'function') {
//Function Bind-ish
cobj[i] = (function() {
var method = i;
return function() {
this.constructor.prototype[method].apply(this, arguments);
return this;
};
}());
}
}
return cobj;
}
var chained = chain(ctx);
chained.fillRect(0,0,200,200)
.fillRect(100,100,200,200)
.fillRect(400,400,100,100)
.fillText("I CAN HAS INVISDIBLE??", 250, 250);
But why bother when you can do this:
with (ctx) {
fillRect(100,100,200,200);
fillRect(300,300,100,100);
fillStyle = 'green'; //I CAN SEE
fillText("SCREW BEST PRACTICES");
}
You seem to be trying to use the canvas element as SVG. Try using Raphaël instead. Your 'text objects' will then actually be objects and you can move them around by adjusting their attributes, you can also define a group and move them all in a single operation. You will also be able to attach onclick
events to them.
Why would you want an invisible rectangle? I assume to use as the bounds for your fillText()
call. The answer is no: once you call fillRect()
the canvas doesn't have conception of a rectangle existing at a certain location. Think of the canvas a dumb collection of pixels, nothing more, with just some helper methods so you don't have to set pixels one at a time.
you need some kind of data structure to keep track of your text objects inside your canvas. Once you write on a canvas there is no way you can know what object you drew. You can get the pixel information but no object. So keep track of objects in an array as you draw on the canvas. And then write a mouse handler to detect clicks on the canvas and then map it back using the data structure.
You should check out Canvas.js, it's a small library by Rob Larsen that enables ctx.chaining, https://github.com/roblarsen/CanvasJS
Invisible rectangles, are possible, sure. I don't see any reason why not.
You could make the strokeStyle = whatever the background color is of the rectangle, 1px.
It does require being filled or stroked though, I'm pretty sure. If you don't do that, then the methods you use to make it, rect() or whatever, will be within the context state, so whenever you do fill or stroke, it will be applied to the rectangle then.
Use .save() and .restore() - helps separate the stack state, and indent your code too. Easier to read and follow within state stacks.
精彩评论