context.font = '20pt Calibri';
context.fillStyle = 'rgba(225,225,225,0.5)';
var width = context.measureText(message2).width;
context.fillRect(xIndent, yIndent+100, width, 60);
context.fillStyle = 'rgba(255,85,0,1.0)';
context.fillText(message3, xIndent, yIndent+100);
I want the context.fillText to have no transparency and the context.fillRect to have some transparency
For some reason, I can make both transparent or both opague
The result is both TEXT and Background color are of the same transparency
You need to reset everything after the first text is written. Because you can set fillStyle after you have drawn or written something, it will still fill it. So, if you want to have to things drawn or written after each other you need to reset everything, so that the next fillStyle doesn't change it's fillStyle too. You need to use context.beginPath() after you have wriite the first text. Here is your code corrected :
context.font = '20pt Calibri';
context.fillStyle = 'rgba(225,225,225,0.5)';
var width = context.measureText(message2).width;
context.fillRect(xIndent, yIndent+100, width, 60);
context.beginPath();
context.fillStyle = 'rgba(255,85,0,1.0)';
context.fillText(message3, xIndent, yIndent+100);
It is best to use context.beginPath() each time you want to draw or write something else.... I hope this helped.....
Related
I'm trying to place text over a background color. I think the issue is that the "fillStyle" is being applied to both the text and the background. I want the text to be black. What am I doing wrong here?
Below is my code:
var canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext("2d");
ctx.fillText("hello", 0, 0);
ctx.fillStyle = "#E7E0CA";
ctx.fillRect(0, 0, 200, 200);
var img = document.createElement("img");
img.src = canvas.toDataURL("image/png");
document.body.appendChild(img);
Here's a link to the fiddle: https://jsfiddle.net/jessecookedesign/9rsy9gjn/36/
Unlike HTML where you define a list of what you want to appear, when working with a canvas it's like you're painting. So each "drawing" operation you do (like fillRect or fillText) will go on top of any existing content and cover it up.
Similarly since you're actually painting, rather than defining objects, you need to set the fill style before drawing. Using the analogy, you need to select the color of paint you'll use before you put paint to canvas.
Finally, the fillText method takes a position as the start of the baseline of the text. Since (0, 0) is the top left of the canvas, your text will get drawn above the bounds of the canvas an not be visible, so you need to move it down e.g. fillText("Hello World", 10, 100);
Correcting for those issues you get something like the following (and skipping the steps involved in converting to an img tag):
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// Draw a black background
context.fillStyle = "black";
context.fillRect(0, 0, 200, 200);
// Draw the text
context.fillStyle = "#E7E0CA";
context.fillText("Hello world", 10, 100);
<canvas id="canvas" width="200" height="200"></canvas>
Wrong order - You're drawing the rectangle over the text.
The text has the same color as the rectangle
There's no font specified
The position (0,0) is out of bounds
Try it like this:
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#E7E0CA";
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = "black";
ctx.font="20px Georgia";
ctx.fillText("hello",10,30);
There are several issues:
You need to first fill the background, then fill the text.
Your text is above the canvas area — try a lower position.
This code has the correct order, and a position for the text that isn’t outside the canvas bounds.
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#E7E0CA";
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = "#000000";
ctx.fillText("hello", 10, 10);
With the changed order, of course you need to choose a new color for the text, in this case "#000000".
Alternatively, you could save and restore your canvas state:
var ctx = canvas.getContext("2d");
ctx.save();
ctx.fillStyle = "#E7E0CA";
ctx.fillRect(0, 0, 200, 200);
ctx.restore();
ctx.fillText("hello", 10, 10);
Whenever you access canvas of html page,
whatever you draw first, will display first.
so if you want to display your colored box first fill it first, then write your text by providing color ,font and position of text. for example,
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#E7E0CA";//your rect color
ctx.fillRect(0, 0, 200, 200);//your rect size
ctx.fillStyle = "#000000";//color for your text
ctx.font="30px Arial";//font style and size
ctx.fillText("hello world",25,50);//text and location
</script>
How do I create a transparent gradient stroke that using html5 canvas? I need it to go from one point to another and look like the below image.
At the moment I have got this:
const gradient = ctx.createLinearGradient(1, 0, 100, 0);
gradient.addColorStop(0, '#fff');
gradient.addColorStop(1, '#d29baf');
ctx.lineWidth = 30;
ctx.strokeStyle = gradient;
ctx.beginPath();
ctx.moveTo(fromXPos, fromYPos);
ctx.lineTo(toXPos, toYPos);
ctx.stroke();
This makes it look like a solid block though like:
Thanks.
Fill a shape
Use a shape and fill it with the gradient.
You can use CSS colour type rgba(red,green,blue,alpha) where red,green,blue are values from 0-255 and alpha is 0 transparent to 1 opaque.
To create a shape you start with ctx.beginPath() to create a new shape then use lineTo(x,y) to mark out each corner. If you want to add another shape using the same fill or stroke you use ctx.moveTo(x,y) to move to the first point.
Note many people use ctx.beginPath(); ctx.moveTo(x,y); but that works just the same as ctx.beginPath(); ctx.lineTo(x,y); As the first point after beginPath is always converted to a moveTo for any type of path object.
const ctx = canvas.getContext("2d");
// draw first box (left of canvas)
ctx.fillStyle = "#ab7383";
ctx.fillRect(20,100,50,50);
// draw second box (to right of first)
ctx.fillStyle = "#904860";
ctx.fillRect(100,20,50,130);
// gradient from top of second box to bottom of both boxes
const g = ctx.createLinearGradient(0, 20, 0, 150);
g.addColorStop(0, `rgba(${0xd2},${0xba},${0xaf},1`); // opaque
g.addColorStop(1, `rgba(${0xd2},${0xba},${0xaf},0`); // transparent
ctx.fillStyle = g;
ctx.beginPath();
ctx.lineTo(70, 100); // top right of first box
ctx.lineTo(100, 20); // top left of second box
ctx.lineTo(100, 150); // bottom left of second box
ctx.lineTo(70, 150); // bottom right of first box
ctx.fill(); // fill the shape
<canvas id="canvas" style="border:2px solid black"></canvas>
If I draw a rectangle to the canvas, and I enable the shadows, then there will be created inner, and outer shadows too, but I only want outer shadow.
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.shadowColor = 'black';
ctx.shadowBlur = 5;
ctx.strokeRect(20,30,150,75);
The only way I've found is ctx.clearRect(20,30,150,75);. But it's not really what I want, because there may be something under my rect, and I don't want to delete it.
Thanks in advance,
You could fetch the pixels inside the rectangle, do the painting and put those pixels back. That way, pixels inside the rectangle won't change: http://jsfiddle.net/dkAKE/.
var imgdata = ctx.getImageData(20, 30, 150, 75);
ctx.strokeRect(20, 30, 150, 75);
ctx.putImageData(imgdata, 20, 30);
To retain the border, use (21, 31, 148, 73) as the area (assuming a stroke width of 1px).
You can also use .fillRect() instead of .strokeRect(). This will create a solid rectangle that has an inner color you define as .fillStyle()
ctx.shadowColor = 'black';
ctx.fillStyle = 'white';
ctx.shadowBlur = 5;
ctx.fillRect(20,30,150,75);
You will still have the problem of it overwriting whatever was underneath the rectangle, so you would still need pimvdb's solution to solve that problem.
I'm drawing simple text in HTML5 canvas using this:
context.fillStyle = "#FF0000"
context.font = "italic 20pt Arial";
context.fillText("sfddsfs", 50, 50);
Now I want to animate fade out of this text. How can that be done?
Edit: I'm aware there's currently no ready to use way to do this (at least I can't find anything). I'm a noob in graphic programming but want to learn, so any hint about where to start is appreciated.
Maybe something like putting the text in an own canvas and changing globalAlpha of the canvas...? But the background of the canvas would have to be transparent. And don't know about performance, have a lot of small labels appearing and dissapearing everywhere which need to be faded out.
It's easier if you use rgba() notation to set the fillStyle rather than the hexadecimal notation. Here's a working example (demo):
// Create a canvas element and append it to <body>
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d');
document.body.appendChild(canvas);
function fadeOut(text) {
var alpha = 1.0, // full opacity
interval = setInterval(function () {
canvas.width = canvas.width; // Clears the canvas
context.fillStyle = "rgba(255, 0, 0, " + alpha + ")";
context.font = "italic 20pt Arial";
context.fillText(text, 50, 50);
alpha = alpha - 0.05; // decrease opacity (fade out)
if (alpha < 0) {
canvas.width = canvas.width;
clearInterval(interval);
}
}, 50);
}
fadeOut('sfddsfs');
I think I got it. Forgot to mention that I have already a render loop and text objects which draw themselves on the canvas each frame.
So the solution is to add alpha variable to the text objects:
this.alpha = 1;
and each x frames or time reduce this a bit.
and in the render loop:
context.globalAlpha = textObject.alpha;
//draw the text
context.globalAlpha = 1;
There is no built-in solution to this. You have to do the animation(fade) by drawing each frame individually:
Set up some timing function that calculates the gradient between #FF0000 and the background color and redraws the text over and over until the background color is reached.
I've got an array like this:
var hitColors = ["#ff0000","#00ff00","#0000ff","#ffff00","#00ffff","#ff00ff"];
I've got a canvas that I'm "redrawing" every few seconds like this:
// main canvas rectangle
context.beginPath();
context.rect(0, 0, canvasWidth, canvasHeight);
context.fillStyle = '#FFFFFF';
context.fillRect(0, 0, canvasWidth, canvasHeight);
context.rect(thisXPos-1, thisYPos-1, words[activeWord][2].width+2, words[activeWord][2].height+2);
context.strokeStyle = hitColors[hitSpot];
alert('"' + hitColors[hitSpot] + '"');
alert(context.strokeStyle);
context.lineWidth = 1;
context.stroke();
context.closePath();
I can confirm that context.closePath(); is returning the proper color from the array but when I alert context.StrokeStyle it's always set to #000000 and the rect border is grey. How can I fix this?
Add or subtract 0.5 pixels from your values.
Basically, if you try to draw a 1px line centered around an integer pixel value what you end up with is a 2 pixel line centered around that point which and the line will be semi-transparent. Semi-transparent black looks like grey. So, if you want a straight line of any colour that is exactly 1 pixel wide, you need to draw that line with at pixel intervals of 0.5.
I switched the array to this:
var hitColors = ["#f00","#0f0","#00f","#ff0","#0ff","#f0f"];
and it started working properly.
You never set you strokeStyle. its defaulting to #000000.