I am trying to draw 2 black lines in HTML5 canvas:
JSFiddle: http://jsfiddle.net/KFNt5/
Javascript:
var canvas = document.createElement('canvas');
canvas.height = 150;
canvas.width = 150;
var canvasContext = canvas.getContext('2d');
canvasContext.beginPath();
// Draw the red line.
canvasContext.strokeStyle = '#000';
canvasContext.moveTo(10, 0);
canvasContext.lineTo(10, 100);
canvasContext.stroke();
// Draw the green line.
canvasContext.moveTo(50, 0);
canvasContext.lineTo(50, 100);
canvasContext.stroke();
document.body.appendChild(canvas);
However, the line to the right is gray, implying that it is semitransparent. How do I ensure that the default opacity is 100 (not transparent at all)?
The second line is lighter due to anti-aliasing. You can include the following line to ensure that you render each line once and avoid the anti-aliasing effect.
canvasContext.translate(0.5, 0.5);
http://jsfiddle.net/bagWQ/
Your first line is darker because you drew it twice, once for each call to stroke(). The second call to stroke() draws both lines because you didn't start a new path.
Related
I am creating one geometry at location (0,0,0) but projecting at some other location (for ex. #50,50,50). If the point (0,0,0) is going out of canvas, then geometry is hiding.
Is there any way to always render it on canvas?
How far off the edge does the origin need to be?
You could make the canvas larger than you need, than mask the areas on the edge such that only the center area shows. That way when the origin goes off the side, it will still technically be on the canvas, and the projected geometry will be in the visible area. I expect you will only need a buffer space equal to projection offset.
See here for an example of applying a mask: https://jsfiddle.net/shawnoakley/n1368qr0/2/
Example code:
var context = document.getElementById('canvas').getContext('2d');
// Mask color
context.fillStyle = '#000';
// Image proportions
context.fillRect(0,0,600,400);
var unmaskedImage = function(x, y, radius){
context.save();
context.globalCompositeOperation = 'destination-out';
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
context.restore();
};
unmaskedImage(300, 300, 300);
Briefly, I am having a problem performing a simple stroke operation on arabic text in an html5 2D canvas.
Arabic text has this property of characters changing forms and merging together when they're next to each other. Apparently, how js handles text stroke is by taking every character by itself and operating on them separately. When the characters are then rendered to the screen, the boundaries of characters becomes visible resulting in leaking stroke colors at the joints.
On the left is the result produced by Javascript's stroke function. On the right is a correct result created with Photoshop (different font).
Is there a way around this?
Your problem is probably that you draw the stroked version on top of the filled one.
Do the inverse and everything will look as you wanted :
var ctx = c.getContext('2d');
ctx.font = "200px Al Tharikh, Arial"
var txt = 'مثال';
ctx.textBaseline = 'top';
// change the stroke style
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
// first draw the stroke
ctx.strokeText(txt , 100, 0);
// then draw the fill
ctx.fillText(txt , 100, 0);
<canvas id="c" height="200" width="500"></canvas>
Ps : if you want to get only the external stroke, then you can use globalCompositeOperations :
var ctx = c.getContext('2d');
ctx.font = "200px Al Tharikh, Arial"
var txt = 'مثال';
ctx.textBaseline = 'top';
// change the stroke style
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
// first draw a larger stroke
ctx.strokeText(txt , 100, 0);
// then set the gCO
ctx.globalCompositeOperation = 'destination-out';
// then draw the filled version which will act as an "eraser"
ctx.fillText(txt , 100, 0);
// reset the gCO
ctx.globalCompositeOperation = 'source-over';
canvas{background: ivory;}
<canvas id="c" height="200" width="500"></canvas>
I had a quick question regarding the ctx function stroke along with the usage of rect. In my code, I draw a rect and fill it with red. I want to also add a green border around the rect, but when I use stroke it seems to create a transparent border, rather than a fully solid line. Why does it do this by default?
Img of result:
My code:
var ctx = Canvas.ctx;
ctx.beginPath();
ctx.rect(this.x, this.y, this.width, this.height);
/*
* CONTAINER
*/
ctx.fillStyle = this.primaryColor;
ctx.fill();
/*
* CONTAINER BAR
*/
if(this.borderColor){
ctx.strokeStyle = this.borderColor;
ctx.stroke();
}
/*
* INNER BAR
*/
var per = this.percent;
if(per > 0){
//the width of the actual loading bar that appears
//inside the entire box
var innerWidth = Math.floor(this.width*(per/100));
ctx.fillStyle = this.secondaryColor;
ctx.fillRect(this.x+1, this.y+1, innerWidth-2, this.height-2);
}
/*
* TEXT
*/
if(this.text){
ctx.textAlign = this.textAlign;
ctx.font = this.font;
ctx.fillStyle = this.textColor;
ctx.fillText(this.text, this.textX, this.textY);
}
Canvas draws its lines straddling your pixel coordinate. So a lineWidth=1 vertical line at x=20 will be drawn from 19.5 to 20.5.
To help clarify your rectangle follow these 2 hints:
Assign the rect's x,y,width,height as integers
Set translate(0.50,0.50) before drawing the rect(s) and unset translate(-0.50,-0.50) afterwards
You can read more about the "why?" here:
http://diveintohtml5.info/canvas.html
Note that these hints help with vertical & horizontal lines, but don't help angled lines & curves.
In my canvas adds 2 images. 1 images is "background canvas". 2 image is cut from 1 image and add to background.
Add background (1 images):
img.onload = function() {
img2= new Image();
img2.src=e.target.result;
canvas.width = this.width;
canvas.height = this.height;
context.drawImage(img2,0,0);
}
Add 2 images:
var c=document.getElementById('obrazek');
var ctx = c.getContext("2d");
var img1 = new Image();
img1.src =$('#blur').getCanvasImage();
img1.onload = function(){
ctx.translate(xStart,yStart);
ctx.beginPath();
context.arc(0, 0, d, 0, 2 * Math.PI, false);
ctx.clip();
ctx.drawImage(img1,-xStart,-yStart);
}
I need clean background. I want delete 2 image and load again background.
My clean:
context.drawImage(img2,0,0);
After cleaning background, I see:
2 image is wrong removed, why?
You need to clear your clipping region or else all further draws will be restricted to your circle.
save the unclipped context
do your clipped drawing
restore the context to its unclipped state
Like this:
function drawAll(backgroundImage,topImage,xStart,yStart,d){
// clear the whole canvas of all images
ctx.clearRect(0,0,c.width,c.height);
// save the unclipped context
ctx.save()
// draw the background image (not clipped)
ctx.drawImage(backgroundImage,0,0);
// create a clipping circle
ctx.arc(xStart,yStart,d,0,Math.PI*2);
ctx.clip();
// draw the top image restricted to the clipping circle
ctx.drawImage(topImage,xStart-topImage.width/2,yStart-topImage.height/2);
// restore the context (clears the clipping circle)
ctx.restore();
}
The issue is that you need to clear your context before you redraw
See related issue:
How to clear the canvas for redrawing
This too work:
ctx.clearRect(0,0, c.width, c.height);
var w = c.width;
c.width = 1;
c.width = w;
context.clearRect ( 0 , 0 , canvas.width , canvas.height );
context.drawImage(img2,0,0);
I want to draw a closed shape(Using paths) & my stroke width is 10.
Now,i want to fill that shape,i can fill it using fill() function of context.
But,when i want to change alpha of my shape,then stroke & fill area overlap at border of shape.
I want only fill the area of shape that remains black after my stroke.
I have attached image of explaining my problem.
Click here to show shape with stork & fill bug.
As you can see in jsfiddle,
-- Color of overlapping area are composite color. That i don't want.
I want it to be exactly same as in border(or stroke color with alpha).
-- i am not enable to specify fill area of closed path.(there is no method of contexx.)
-- I can't use "glabalCompositeOperation",because i am drawing more than 1 shapes in 1 canvas in my application.
The effect you are getting seems to be a property of how canvas draws lines round a shape. Half the thickness of the line is drawn inside the shape and half outside the shape. One way round it is to draw the filled shape and the border as seperate paths. The changes to do this for your example are shown below. This will be more difficult with irregular shapes.
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var topLeftCornerX = 188;
var topLeftCornerY = 50;
var width = 200;
var height = 100;
var linewidth = 10;
context.globalAlpha = 0.5;
context.beginPath();
context.moveTo(topLeftCornerX, topLeftCornerY);
context.lineTo(topLeftCornerX+width,topLeftCornerY);
context.lineTo(topLeftCornerX+width,topLeftCornerY+height);
context.lineTo(topLeftCornerX,topLeftCornerY+height);
context.closePath();
context.fillStyle = "#FF0000";
context.fill();
context.beginPath();
context.moveTo(topLeftCornerX-linewidth/2, topLeftCornerY-linewidth/2);
context.lineTo(topLeftCornerX+width+linewidth/2,topLeftCornerY-linewidth/2);
context.lineTo(topLeftCornerX+width+linewidth/2,topLeftCornerY+height+linewidth/2);
context.lineTo(topLeftCornerX-linewidth/2,topLeftCornerY+height+linewidth/2);
context.closePath();
context.lineWidth = linewidth;
context.strokeStyle = "#00FF00";
context.stroke();