Here is my html
<canvas class="row" id="myCanvas" width="500" height="50" style="border:1px solid #c3c3c3;" ></canvas>
and this is javascript
function showProgress() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillText("welcome", c.width/2, c.height/2);
ctx.textAlign = "center";
ctx.font = "30px Arial";
ctx.fillStyle = "#00ff00";
ctx.fillRect(0, 0, 270, 75);
}
showProgress();
I have following two issues.
1. Green fill rectangle is hiding the text. How can I show that text on top of fill color.
2. I would like text (welcome in this case) color to be red. Is there anyway of modifying just the text color.
code could be found at jsfiddle
https://jsfiddle.net/Lp24q01s/
function showProgress() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillStyle = "#00ff00";
ctx.fillRect(0, 0, 270, 75);
ctx.fillStyle = '#ff0000';
ctx.textAlign = "center";
ctx.font = "30px Arial";
ctx.fillText("welcome", c.width/2, c.height/2);
}
showProgress();
The canvas context uses the entire state to draw things and they're drawn in the order you call them. Want the text on top of a rectangle? Draw the rectangle first. Want to change the color? Set color to green, draw rectangle, set color to red, draw text.
It doesn't have a native way to say "the rectangle is green." It's more "the next thing you draw will have a fill style of green, I think I'll draw a rectangle" so you have a green rectangle.
function showProgress() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillStyle = "#00ff00";
ctx.fillRect(0, 0, 270, 75);
ctx.fillStyle = "#ff0000";// red text
ctx.fillText("welcome", c.width/2, c.height/2);
ctx.textAlign = "center";
ctx.font = "30px Arial";
}
showProgress();
you should put the fillText after the fillRect, also you need to set the fillStyle
because canvas is just a Finite State Machine, it can't remember what you was done.
if you make some difference state(such as change the fillStyle), and do another render(such as fillRect), the current result will always cover the result you done before.
Related
When I change from strokeText to fillText the text disappears. I just have a gradient canvas background and I am trying to put fillText over the gradient. strokeText works fine but when I change to fillText, the text is gone.
'''
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var grd = ctx.createRadialGradient(100, 100, 100, 100, 130, 50);
grd.addColorStop(0, "orange");
grd.addColorStop(1, "yellow");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 100);
ctx.font="20px Georgia";
ctx.strokeText("hello",10,30);
'''
HTML
<canvas id="canvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
It “disappears” because you only set fillStyle once therefore both fillRect and fillText are the same gradient color. The text is there but it’s blended into the background. Change the fillStyle again before the text.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var grd = ctx.createRadialGradient(100, 100, 100, 100, 130, 50);
grd.addColorStop(0, "orange");
grd.addColorStop(1, "yellow");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 100);
ctx.fillStyle = "blue";
ctx.font="20px Georgia";
ctx.fillText("hello",10,30);
The reason it doesn’t do that with stroke is because stroke doesn’t get it’s orders from fillStyle so therefore it uses the default which is black.
I have a canvas and I want to print words on it in horizontal and vertical orientation. The printing itself works fine but I have a somewhat annoying spacing at the beginning of the words, which becomes extremely visible on the vertical text like the EX on the example image.
I just created a little example which shows what I mean
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create a red line in position 150
ctx.strokeStyle = "red";
ctx.moveTo(150, 20);
ctx.lineTo(150, 170);
ctx.stroke();
ctx.font = "50px Arial";
// Show the different textAlign values
ctx.textAlign = "start";
ctx.fillText("EX", 150, 50);
ctx.textAlign = "end";
ctx.fillText("EX", 150, 100);
ctx.textAlign = "center";
ctx.fillText("EX", 150, 150);
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
Is there a way to place the beginning of the word at the point I am drawing to or is there a way to calculate the spacing at the beginning and then just subtract it from the starting point of the text?
The TextMetrics interface has actualBoundingBox[...] information that you can use to know by how much the actual bounding box is offset relatively to the textAlign and textBaseline lines.
So adding the measured actualBoundingBoxLeft to your horizontal position when writing LTR text with the "start" text-align will remove this gap.
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const input = document.querySelector("input");
input.oninput = draw;
draw();
function draw() {
const txt = input.value;
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillStyle = "black";
// Create a red line in position 150
ctx.strokeStyle = "red";
ctx.moveTo(150, 20);
ctx.lineTo(150, 180);
ctx.stroke();
ctx.font = "50px Arial";
ctx.textBaseline = "top"; // needed for the ascent and decsent measurements
// Show the original textAlign
ctx.textAlign = "start";
ctx.fillText(txt, 150, 30);
// fixed
ctx.fillStyle = "green";
const metrics = ctx.measureText(txt);
ctx.fillText(txt, 150 + metrics.actualBoundingBoxLeft, 110);
// Draw the box around our text
ctx.translate( 150, 110 );
const x = 0; // we already did offset by actualBoundingBoxLeft
const y = metrics.actualBoundingBoxAscent * -1;
const width = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft;
const height = metrics.actualBoundingBoxDescent + metrics.actualBoundingBoxAscent;
ctx.strokeRect(x, y, width, height);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
<input value="Éxy"><br>
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>
I originally wrote a script in js that I am now rewriting using HTML5 on a canvas. Previously I had
<p id = "collision">Test</p>
function checkHit(){
if (my conditions) {
document.getElementById("collision").innerHTML = "hit!";
}
}
This worked fine, but now in my canvas I have
c.fillStyle = "#ffff00";
c.font = "30px Arial";
c.fillText("Test", 10, 50);
How can I get the ID of "test" so that I can change it to "hit!" on the canvas.
What you should do is clear the canvas, then refill it with text:
c.clearRect(0, 0, canvas.height, canvas.width);
c.fillStyle = "#ffff00";
c.font = "30px Arial";
c.fillText("Hit!", 10, 50);
So basically the javascript draws two triangles, one with a blue border and the second with a green border. I have a button that when is pushed it should fill the triangle with a blue border blue.
Currently it does not work but when the {} are removed from the if statement at the bottom it colors the green bordered triangle green, im not sure why this happens.
Any tips would be very helpful!
window.onload = draw;
function draw() {
var canvas = document.getElementById('myCanvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.moveTo(600, 0);
ctx.lineTo(500, 200);
ctx.lineTo(700, 200);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = "green";
ctx.moveTo(500, 210);
ctx.lineTo(700, 210);
ctx.lineTo(600, 410);
ctx.closePath();
ctx.stroke();
}
}
function fillColor() {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
if (ctx.strokeStyle == "blue") {
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.fill();
}
}
<canvas id="myCanvas" width="700" height="410"></canvas>
You cannot compare rectangles with the stroke color.You need to change your fillColor function a little bit . Please see the below code it may help you
HTML
<body>
<canvas id="myCanvas" width="700" height="410"></canvas>
</body>
Javascript
<script>
window.onload = draw;
function draw() {
var canvas = document.getElementById('myCanvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.moveTo(600, 0);
ctx.lineTo(500, 200);
ctx.lineTo(700, 200);
ctx.closePath();
ctx.stroke();
fillColor(ctx,'blue');
ctx.beginPath();
ctx.strokeStyle = "green";
ctx.moveTo(500, 210);
ctx.lineTo(700, 210);
ctx.lineTo(600, 410);
ctx.closePath();
fillColor(ctx,'red');
}
}
function fillColor(ctx,color) {
ctx.fillStyle = color;
ctx.fill();
}
You need to call the fillColor() function after creating each rectangle with the color to fill.
I am trying to do text masking in javascript.
Below is my code :-
if(this.image!==null)
{
canvasContext.drawImage(this.image, 0, 0, this.width, this.height);
}
canvasContext.font = "55px Arial";
canvasContext.textAlign = "center";
canvasContext.textBaseline = "middle";
canvasContext.globalCompositeOperation = 'destination-out';
canvasContext.fillText("CENSORED", 250, 250);
But its not working. Please help me to resolve this issues.
I’m not sure what “not working” means, but…
There are 2 common kinds of text masking in canvas
destination-out:
The Text will act as a cookie-cutter and remove anything drawn underneath the text, but the Text will not show on transparent pixels.
xor:
The Text will cut out only non-transparent drawings on the canvas, but the Text will otherwise be drawn normally.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/n836N/
<style>
body{ background-color: purple; }
canvas{background-color: white; border:1px solid red;}
</style>
<script>
$(function(){
var canvas1=document.getElementById("canvas1");
var canvasContext1=canvas1.getContext("2d");
var canvas2=document.getElementById("canvas2");
var canvasContext2=canvas2.getContext("2d");
// destination-out
// Text cuts-out everything under it
// background is revealed in the cut-out
makeGradientAndFont(canvasContext1,canvas1);
canvasContext1.globalCompositeOperation = 'destination-out';
canvasContext1.fillText("CENSORED", 175, 50);
// xor
// Text cuts-out everything it overlaps
// But Text is drawn normally where canvas is transparent
// background is revealed in the cut-out
makeGradientAndFont(canvasContext2,canvas2);
canvasContext2.globalCompositeOperation = 'xor';
canvasContext2.fillText("CENSORED", 175, 50);
function makeGradientAndFont(ctx,canvas){
var grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grad.addColorStop( 0, '#0000FF');
grad.addColorStop(.3, '#00FFFF');
grad.addColorStop(.4, '#99FFFF');
grad.addColorStop(.5, '#00FF00');
grad.addColorStop(.6, '#FFFF00');
grad.addColorStop(.8, '#F00000');
ctx.rect(115, 0, canvas.width-115, canvas.height);
ctx.fillStyle=grad;
ctx.fill();
ctx.fillStyle="black";
ctx.font = "55px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas1" width=350 height=100></canvas><br/>
<canvas id="canvas2" width=350 height=100></canvas>
</body>
</html>