PDFlib - how can I clear attribute that was set by set_graphics_option() - pdflib

The code:
$p->set_graphics_option('fillcolor={rgb 0 1 0} strokecolor={rgb 1 0 0} linewidth=2');
$p->rect(100, 300, 300, 200);
$p->fill_stroke();
$p->set_graphics_option('linewidth=1 strokecolor={rgb 1 0 0} linewidth=2');
$p->rect(100, 600, 100, 100);
$p->fill_stroke();
This will render two rectangles, both with red outline (stroke) and filled with green color.
The problem is that second rectangle still "remembers" fill color set by previous set_graphics_option() call - although most recent call does not define fillcolor.
Questions:
Is there something similar to set_graphics_option('fillcolor=none') to draw second rectangle as outline only?
Is there a command that works as opposite of setcolor() - that would unset current color?
Important:
I would like to use fill_stroke() to render both rectangles. I am aware that I can use either fill() or stroke().

you should encapsulate it with save restore:
$p->save();
$p->set_graphics_option('fillcolor={rgb 0 1 0} strokecolor={rgb 1 0 0} linewidth=2');
$p->rect(100, 300, 300, 200);
$p->fill_stroke();
$p->restore();
$p->save();
$p->set_graphics_option('linewidth=1 strokecolor={rgb 1 0 0} linewidth=2');
$p->rect(100, 600, 100, 100);
$p->fill_stroke();
$p->restore();
when you set the same option multiple times within a single option list, the last one wins. In this sample, you set first linewidth=1 and then linewidth=2, so the current line width is 2.
A option is always valid until you reset it, or the related scope stops.
Is there something similar to set_graphics_option('fillcolor=none') to draw second rectangle as outline only?
When you don't want a fill the rectangle, please use stroke() instead. When you fill it, you get always the current color. And none is not a valid color.

Related

Phaser HTML5 Background change with specific score

Im trying to change the background in a phaser game once the player reaches a score of 50 or any number really, the back is a png. Is this possible?
this is my code:
this.backgroundGame = this.game.add.tileSprite(0, 0, 800, 600, 'background');
if (this.score == 3)
this.backgroundGame = this.game.add.tileSprite(0, 0, 800, 600, 'background1');
But this is surely not working at all, it kind of brings background1 and covers the whole game if I include the if in the update function, and if I include it on the create function it is just ignored. Any advise? Sorry I'm a newbie and still learning. Also English is not my first language so if my question is not clear let me know thanks.
You can load in preload() method all background do you need.
this.game.load.image('background', 'images/bg1.png');
this.game.load.image('background2', 'images/bg2.png');
Later add to game one sprite like background:
this.backgroundSprite = this.game.add.tileSprite(0, 0, 800, 600, 'background');
this.backgroundSprite = this.game.add.sprite(0, 0,'background');
And when will be right time:
if (this.score == 3)
this.backgroundSprite.loadTexture('background1');
You will have better performance when you not allways add new object to game word.
In create method you have to set both (or many as you want) backgrounds. As in Phaser layers are like in CSS, the original background (the first of them) has to be the last in create:
--- Create:
this.background2 = this.game.add.tileSprite(0, 0, 800, 600, 'background1');
this.backgroundOriginal = this.game.add.tileSprite(0, 0, 800, 600, 'background');
Then in update, when your condition is true, you have to set alpha = 0 (invisible) to the original background and the layer behind will be visible.
--- Update:
if(this.score == 3) {
this.backgroundOriginal.alpha = 0;
}
PD.: My english is not enough good too... pero supongo que el inglés españolizado si lo entiendes bien, ¿no Rafa? ;)

Html5 Canvas - Shading an outside area

I need to shade an OUTSIDE area, ie the shapes I draw in the shader are drawn normally, and their inverse is then shaded. Its easiest to explain with an example, and noting the bit that is not working:
// canvasBackground is the actual background
// canvasBackgroundContext is its context
// To make it simple, I will fill it with green
canvasBackgroundContext.fillStyle = "#00FF00";
canvasBackgroundContext.clearRect(0, 0, canvasBackground.width, canvasBackground.height);
// I also have a the shader
// canvasShader and canvasShaderContext with same width and height as canvasBackground
canvasShaderContext.fillStyle = "rgba(0, 0, 0, 0.25)"; // Black but slightly transparent
canvasShaderContext.clearRect(0, 0, canvasShader.width, canvasShader.height);
// Everything so far is great - now the problem
// This is wrong, because when I create the area I want to create clear, it does not work
// because when you draw a shape it does not work like clearRect, as it does not set each pixel to a clear pixel
canvasShaderContext.fillStyle = "rgba(0, 0, 0, 0.0)";
// Create the only non shaded bits in the shader, overlapping rects
canvasShaderContext.fillRect(10, 10, 50, 50);
canvasShaderContext.fillRect(40, 40, 50, 50);
// So when I do this, it should shade the entire background except for the two 50x50 overlapping rects at 10,10 and 40,40
canvasBackgroundContext.drawImage(canvasShaderContext, 0, 0);
I don't want to go to a pixel by pixel basis using getImageData, as that is slow. There must be some way of doing this.
I am not sure I fully understand what you try to achieve, but how about adding a composite mode to this:
canvasShaderContext.fillRect(10, 10, 50, 50);
canvasShaderContext.fillRect(40, 40, 50, 50);
which results in:
/// store old mode whatever that is
var oldMode = canvasShaderContext.globalCompositeOperation;
/// this uses any shape that is drawn next to punch a hole
/// in destination (current context).
canvasShaderContext.globalCompositeOperation = 'destination-out';
/// now draw the holes
canvasShaderContext.fillRect(10, 10, 50, 50);
canvasShaderContext.fillRect(40, 40, 50, 50);
/// set back to old mode
canvasShaderContext.globalCompositeOperation = oldMode;
That will also clear the alpha bits.

How do a cut out one shape from another (XOR) in Canvas when shape is partially transparent?

Normally to cut one shape out from another using Canvas, I've used the globalCompositeOperation option "xor":
var c2 = document.getElementById('canvas').getContext('2d');
c2.globalCompositeOperation = "xor";
c2.fillRect(0, 0, 200, 200);
c2.fillRect(170, 0, 30, 30); // shape 2 is cut out from shape 1
However, when either the fillStyle has a alpha value < 1, or the globalAlpha of the context is < 1, the "cut-out" shape is no longer completely invisible.
Specifically, if the alpha is >0.5 and <1, you see a lighter version of the shape. If the alpha is 0.5, there is no cut-out visible at all. And if alpha is <0.5, we get the inverse: the shape that's supposed to be cut out is in fact darker than the first shape.
This can be seen at http://jsfiddle.net/N7aXY/2/.
You can try changing the alpha value to see the different effects.
Is there any way to completely cut out a shape when the background shape has an alpha < 1?
Ok, this is a bit "hackish", but here we go anyway:
Set compositing to XOR.
Draw to "cut" shape2 from shape1 normally.
Save the canvas.
Set compositing to normal (source-over).
Set globalAlpha to your desired level.
Clear the canvas and redraw the saved image.
Results: globalAlpha and globalCompositing work in harmony!
Here is code and a Fiddle: http://jsfiddle.net/utttk/1/
ctx.fillStyle="red";
ctx.globalCompositeOperation="xor";
ctx.fillRect(0,0,200,200);
ctx.fillRect(170,0,30,30);
var png=canvas.toDataURL();
ctx.globalCompositeOperation="source-over"; // "normal" compositing
ctx.globalAlpha=.2;
var image=new Image();
image.onload=function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(image,0,0);
}
image.src=png;

html5 canvas: clipping by color

is there any way to choose an area on the canvas by color and clip it?
I want to be able to clip an undefined aread that the only thing in common between all the pixels is that they all have the same color.
thanks
Live Demo
Below is a way to select a color.. and do whatever you want with it. I pass a color I want to find iterate over every pixel and remove the color that matches, since Im not sure what you meant by clipping I assumed you mean remove. However please note on large images this method will be slow.
// Takes an array with 3 color components, rgb
function removeColor(color){
var canvasData = ctx.getImageData(0, 0, 256, 256),
pix = canvasData.data;
for (var i = 0, n = pix.length; i <n; i += 4) {
if(pix[i] === color[0] && pix[i+1] === color[1] && pix[i+2] === color[2]){
pix[i+3] = 0;
}
}
ctx.putImageData(canvasData, 0, 0);
}
removeColor([0,0,255]); // Removes blue.
And like Simon pointed out the code above will get the exact color. Below will grab the approximate color, which is good if you have colors overlapping or very close to each other.
Demo 2 with approximation

html canvas shadow being applied to everything

If you define a shadow ONCE, then it applies to all "graphics" on the canvas from thereon after (which is what it's supposed to do).
Sample:
http://flanvas.com/development/flanvas/test.html
Does anyone know best practice to turn the shadow off after you've used it? I'm setting shadowColor to "rgba(0,0,0,0)" which is a no-alpha black. I'm sure there is a better way.
case sample: The text is also getting a shadow. I'm using the no-alpha black to combat this for now.
http://flanvas.com/development/flanvas/examples/filters-dropShadowFilter.html
By using save, translate and restore you can perform your tasks without worrying about the style changes, for eg.
ctx.save();
ctx.translate(X,Y);
ctx.shadowColor = 'rgba(255, 0, 0, 0.5)';
// do some stuff
ctx.restore();
here X & Y are the co-ordinates where you intended to draw and you do your stuff relative to the co-ordinates 0,0.
This method solves the problem of caching and restoring the previous styles/values and is also very helpful when you work with gradients as they are always plotted relative to the origin (0,0)
(EDIT: Oops! I see that's what you were already doing with a 0 alpha black.)
This is what you were looking for:
context.shadowColor = "transparent";
It's usually a good idea to store the old value of these kind of "global" attributes before you change it and use this stored value to restore it later on. Example:
var origShadowColor = ctx.shadowColor;
ctx.shadowColor = 'rgba(255, 0, 0, 0.5)';
// ... do some stuff
ctx.shadowColor = origShadowColor;
I created a function i can call to reset the shadow if needed.
resetShadow() {
this.ctx.shadowOffsetX = 0;
this.ctx.shadowOffsetY = 0;
this.ctx.shadowColor = "transparent";
}