NSBezierPath Stroke color is wrong - cocoa

I want to draw a 1px wide border around my custom NSView in DrawRect with NSBezierPath:
BorderColor.Set();
var path = NSBezierPath.FromRect(theRect);
path.LineWidth = 1;
path.Stroke();
Now BorderColor is set to NSColor.Gray, which I can see while debugging has an RGBA color code: (127,127,127,255)
But the 1px wide border which appears on the screen gets this color: (194,194,194,255)
When I set the path.LineWidth to 3, than I can see the 3 lines, the middle with wrong color (194..), the 2 wings with color (135,135,135,255) - which is close enough to the wanted (127..) color to be ok.
When I use four piece of 1px wide rectangles for border instead, and Fill these 4 rects, I also get the (135..) color, which is ok again.
I can use this rectangle based solution, I'm only wondering:
Is there a way to achieve the correct color for a 1px wide border with NSBezierPath.Stroke?

Assuming you're setting the stroke color correctly (we don't see how BorderColor is set up) it might be the case that you're measuring the color value on screen, which - in particular for a thin line - might have been anti-aliased so you're not seeing the original color but the output of the anti-aliasing algorithm.
Set the width to something bigger like 10 and measure the color in the middle of the 'blob' to make sure you're not chasing anti-aliasing artefacts..

Related

How do I change an image (icon's) color in css

I have some images representing icons that consists of blue signs and transparent background. I display them using css:
.icon {
background: rgba(0, 0, 0, 0) url("images/icons/my-icon.png") no-repeat scroll 5px center;
}
My icon looks like this one: https://cdn2.iconfinder.com/data/icons/large-svg-icons-part-3/512/zoom_search_find_magnifying_glass-256.png
I want to be able to change the color of the blue using css. I tried to use CSS3's filter function.
The idea is that I have the hex code and I transform it to RGB and later HSL (hue, saturation and luminance). In the end I'll have for each color a value between 0 and 360 (a degree). See for example this image: http://lodev.org/cgtutor/images/hslhuecircle.jpg .
I'm using this filter function:
filter: hue-rotate(220deg) saturate(100);
Where 220deg is the int value of the hue. So the hue (initially a float value) aproximated up is 220.
Take example red: #ff0000
The hue details are:
array(4) {
["hue"]=>
int(0)
["saturation"]=>
int(100)
["luminance"]=>
float(50)
["degrees"]=>
int(0)
}
So the css becomes:
.icon {
background: rgba(0, 0, 0, 0) url("images/icons/my-icon.png") no-repeat scroll 5px center;
filter: hue-rotate(0deg) saturate(100);
}
But in this case, the blue becomes #9AF8FF (which is not red).
In order to obtain red, I should use:
filter: hue-rotate(195deg) saturate(100);
The hue-rotate values can be between 0 and 360, just like degrees. In my case the results are inversed, instead of obtaining red for 0degrees, I obtain the value that can be find on the following image at 195 degrees: http://lodev.org/cgtutor/images/hslhuecircle.jpg .
Is there any css filter or other solution that can help me to change the image color using css? I played with other CSS3 filters but I couldn't change the color to the desired one.
I have an application where users can select the desired color, the only problem is with existing image icons.
Any help will be great, anticipate thanks!
When I wrote the question I found a possible solution. In my case, the results were reversed.
For red, #ff0000 I obtained 0 degrees. I realized that with css3's filter hue-rotate, the red is not at 0, but it starts at 180. So for each hue/degree value that I obtain, I add 180. In this way, I can obtain the desired color.
After this change, the hsl:
array(4) {
["hue"]=>
int(0)
["saturation"]=>
int(100)
["luminance"]=>
float(50)
["degrees"]=>
int(0)
}
become:
array(4) {
["hue"]=>
int(180)
["saturation"]=>
int(100)
["luminance"]=>
float(50)
["degrees"]=>
int(180)
}
I tried it for green and other colors and it works well. If you have a better idea to change the image color with CSS, one that doesn't use the filter function "hue-rotate", I'll be glad to hear about it.
EDIT
I found the solution.
1) I'm using the solution explained above (I add 180 to my degrees).
2) I'm using brightness filter also
So My filter looks like:
filter: hue-rotate(350deg) saturate(100) brightness(1);
This filter changes the icon's color to this color: #00FFFF .
So the solution work 100%. I'm sending color code and brightness and I dynamically calculate the filter values. For darker colors use a lower value for brightness (under 0.5) and for brighter colors use values above 0.5.

How to set no border when drawing background colored rectange?

Is there a way to set no border when drawing background-color filled rectangle? Or make border color match background-color filled rectange?
PrimitiveComposer primitiveComposer = new PrimitiveComposer(page);
{
BlockComposer blockComposer = new BlockComposer(primitiveComposer);
primitiveComposer.SetLineWidth(0.0f);
primitiveComposer.SetFillColor(DeviceRGBColor.Get(System.Drawing.Color.DarkGray));
primitiveComposer.DrawRectangle(new RectangleF(_boxMarginX, _boxMarginY, (page.Size.Width - (_boxMarginX * 2)), 205f), 0f);
primitiveComposer.FillStroke();
}
You use
primitiveComposer.FillStroke();
which is the command to fill and stroke a path. As you don't want the borders, i.e. you don't want to stroke, use
primitiveComposer.Fill();
instead.
By the way,
primitiveComposer.SetLineWidth(0.0f);
The PDF specification defines a line width of 0 to mean the smallest line the target device can render.

OpenGL: How to darken a sprite in Cocos2d

I've tried shooting the dark with all the GL functions, to no avail on what I'm sure has to be pretty simple. I'm new to it.
I want to take a sprite and simply darken it. My thoughts on this were to load the sprite, add a grey layer overtop of it (using CCLayerColor with a grey color), apply some kind of GL function, and then grab the output and display it onscreen. However, in every variant I tried where my source image was correctly darkened, the transparency around it was also affected, showing the grey. I need the darkening effect to be masked to the shape of the source sprite.
Here's the code I have so far. How can I correctly mask the darkening effect?
CCSprite* sprite = [CCSprite spriteWithSpriteFrameName: mod.backgroundImagePath];
CCLayerColor* tint = [CCLayerColor node];
[tint setColor:ccc3(205, 205, 205)];
//[tint setBlendFunc: (ccBlendFunc){GL_SRC_COLOR, GL_ONE_MINUS_DST_ALPHA}]; Need help here?
[sprite addChild:tint];
CCRenderTexture* rt = [CCRenderTexture renderTextureWithWidth:sprite.boundingBox.size.width height:sprite.boundingBox.size.height];
[rt begin];
[sprite visit];
[rt end];
You can just set the color property of CCSprite (which is inherited from CCNode):
CCSprite* sprite = [CCSprite spriteWithSpriteFrameName:#"foobar"];
sprite.color = [CCColor colorWithRed:r green:g blue:b alpha:a];
Where the r,g,b,a variables are the color you want to use, normalized between 0 and 1.
I.e.:
Setting to 0,0,0,1 will make the object completely black.

EaselJS spritesheet animation makes background disappear

I am working on a game using EaselJS, and I am still trying the functions provided by this great library.
What I may need is Alphamaskfilter class & Spritesheet class.
Currently, I have a canvas like this:
<canvas id = 'container3' width = 320px; height = 480px;
style = 'outline: 2px solid; margin-right: 10px;float:left;'></canvas>
and in my script, I have draw a rect with blue color:
var ctx3 = document.getElementById('container3').getContext('2d');
ctx3.beginPath();
ctx3.rect(0,0,320,480);
ctx3.fillStyle = 'blue';
ctx3.fill();
So now I have a blue color 320*480 canvas. And now I have a sprite sheet to animate on it,
here is the sprite and code I wrote:
http://i.imgur.com/XumDvic.png
PS: the sprite frame is 200*200 FYI.
stage = new createjs.Stage(document.getElementById('container3'));
var test = new Image();
test.src = 'trans_blackball.png';
test.onload = function(){
var sprite = new createjs.SpriteSheet({
images: [test],
frames: {width: 200, height: 200},
animations: {
born: [0,3,0]
}
});
var animation = new createjs.BitmapAnimation(sprite);
animation.gotoAndPlay("born");
animation.x = 10;
animation.y = 10;
animation.currentFrame = 0;
stage.addChild(animation);
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(10);
}
function tick(){
stage.update();
}
Okay, my question is: I expect an animation of an enlarging black circle on a blue background(rect), but what I got is firstly the canvas is blue, but for a certain mini-second after, the whole canvas became white, and the animation is running on the white background, what is the reason of this and how can I solve it?
Here is two points that may help:
I am working with chrome, and I check with F12 & console, the fillStyle of the canvas is still blue even it appears white after the sprite animation start
If I set the canvas background property to blue instead of drawing a blue rect on it, everything's fine!!
<canvas id = 'container3' width = 320px; height = 480px;
style = 'background: blue; outline: 2px solid; margin-right:
10px;float:left;'></canvas>
but clearly this is not what I want...
The problem can be solved as well by not using native canvas rect but use EaselJS's Shape to draw the rect:
var shape = new createjs.Shape();
shape.graphics.beginFill("#ff0000").drawRect(0, 0, 320, 480);
stage.addChild(shape);
But I still wanna know why the native rect drawing code is not working...
Please bare my bad english and thanks for reading and any attempt to help...I can elaborate more if there is anything unclear in the situation..thanks!
createjs.Stage.update() will clear the canvas-contents by default before rendering the new frame.
The reason for this is one the one hand the technical behaviour of canvas, the canvas is basically just an image of pixels, you cannot have real 'layers' and say "I just want to remove/update this one object" - you just can modify the flattened pixels of the frame or remove everything and redraw it(which is safer, easier to achieve, and actually fast enough performance-whise. And on the other hand, it makes sense to make consistent use of a framework like EaselJS, and not do some parts with the framework and some parts without it, this would result in a big mess at the end.
So, the right solution is to go with 3.
You can set myStage.autoClear = false; to prevent the Stage from autoClearing the canvas on every update() but I don't think this will suit your needs in this case.
I would recommend instead using the EaselJS Shape class to make your blue box. If it part of the EaselJS display list, it will be drawn with the other content.
javascript
var shape = new createjs.Shape();
shape.graphics.beginFill("blue").drawRect(0,0,320,480);
stage.addChild(shape);

How to fill color in nsbox on nsslider movement?

I want to fill color in an NSBox on slider movement.
I am using the following code.
-(IBAction)slider1move:(id)sender {
[self.box setFillColor:[NSColor colorWithCalibratedRed: ([self.slider1 floatValue])/255.0 green:0.0 blue:0.0 alpha:0.0]];
}
Please correct me. I have three sliders in my application with each correspond to red , green and blue color.
How do I fill the color in the box on slider movement based on the current value of slider.
Like if my slider showing value of 50 the box should be half filled with red color if it is for red color.
First, make sure you've met the requirements listed in NSBox's setFillColor: documentation:
Functional only when the receiver’s box type (boxType) is NSBoxCustom
and its border type (borderType) is NSLineBorder.
Assuming that's not the problem, a quick guess would be that you may need to call setNeedsDisplay: on the box to get it redrawn with the new color.
Look at Your color, You set fully transparent color - alpha to 0.0 that's why Your color it's not changing.
Change Your color to alpha 1.0 like this:
[NSColor colorWithCalibratedRed: ([self.slider1 floatValue])/255.0 green:0.0 blue:0.0 alpha:1.0]

Resources