Dynamically created canvas not recognized/manipulatable - javascript

I am trying to create and fill a canvas as blue without using any html. I have been successful in rendering an empty canvas. The issue occurs when I try to fill the canvas with a color as seen below in the second code snippet. In the two snippets below, the only difference is which canvas is filled with blue (document.getElementsByClassName("blueCanvas")[0] in the first one, which works, and document.getElementsByClassName("blueCanvas")[2], which should fill the dynamically created canvas, and fails.
some things I have tried/noticed:
First I thought it was an issue with the order in the execution in the creation of the canvas and the js that tries to fill it, but the problem persists even when I create the canvas in the beginning of the <body>. I also thought it might be an issue of append the element to the DOM but it renders an empty canvas so I don't see how that's possible.
Thanks.
var newCanvas = document.createElement('canvas');
newCanvas.width = '300';
newCanvas.height = '150'
newCanvas.className = 'blueCanvas';
newCanvas.style = 'border:1px solid black'
newCanvas.innerHTML = '<canvas> </canvas>';
document.body.appendChild(newCanvas);
var canvas = document.getElementsByClassName("blueCanvas")[0];
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
<canvas id="canvas" class='blueCanvas' width="300" height="150" style="border:1px solid black"></canvas>
<canvas id="canvas" class='blueCanvas' width="300" height="150" style="border:1px solid black"></canvas>
var newCanvas = document.createElement('canvas');
newCanvas.width = '300';
newCanvas.height = '150'
newCanvas.className='blueCanvas';
newCanvas.style= 'border:1px solid black'
newCanvas.innerHTML = '<canvas> </canvas>';
document.body.appendChild(newCanvas);
var canvas = document.getElementsByClassName("blueCanvas")[2];
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
<canvas id="canvas" class='blueCanvas' width="300" height="150" style="border:1px solid black"></canvas>
<canvas id="canvas" class='blueCanvas' width="300" height="150" style="border:1px solid black"></canvas>

Since I know you read my comments:
function blueCanvas(){
let canvas = document.createElement('canvas'), style = canvas.style, ctx;
canvas.width = 300; canvas.height = 150; canvas.className = 'blueCanvas';
style.border = '1px solid black'; ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue'; ctx.fillRect(0, 0, 300, 150);
document.body.appendChild(canvas);
}
blueCanvas();

Its not clear what you want.
Maybe this will help
const canvas = document.createElement('canvas');
canvas.width = 400; // size it
canvas.height = 300;
canvas.className = 'blueCanvas'; // assign class name
document.body.appendChild(canvas); // add to document
// get context
const ctx = canvas.getContext("2d");
// fill it with blue
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.font = "32px Arial";
ctx.textAlign = "center";
ctx.fillText("Dynamically added canvas", 200, 100);

Related

Downloading canvas with border sytle

I want to download canvas with border. On screen Canvas has border but when I download canvas, its border doesnt appear
let canvas=qrRef.current.querySelector("canvas")
canvas.style.border="black 30px solid"
if(type=="PNG"){
let image=canvas.toDataURL("image/png")
let anchor=document.createElement("a");
anchor.href=image;
anchor.download=`qr-pollective.png`
document.body.appendChild(anchor);
anchor.click()
document.body.removeChild(anchor)
}
console.log(canvas)
<canvas height="400" width="400" style="border: 30px solid black; border-radius: 5px; border-collapse: collapse;">
What you can do is create a bigger canvas which has space for the black border.
Then copy the canvas you have created onto this bigger one, offset by 30px to make room for the border.
Then draw the 4 black rectangles that make up the border. This bigger canvas is then the one that you want to download.
const canvas = document.querySelector('canvas');
const biggerCanvas = document.createElement('canvas');
const w = canvas.width + 60;
const h = canvas.height + 60;
biggerCanvas.width = w;
biggerCanvas.height = h;
const ctx = biggerCanvas.getContext('2d');
ctx.drawImage(canvas, 30, 30);
ctx.beginPath();
ctx.rect(0, 0, w, 30);
ctx.fillStyle = "black";
ctx.fill();
ctx.rect(0, 0, 30, h);
ctx.fill();
ctx.rect(w - 30, 0, w - 30, h);
ctx.fill();
ctx.rect(0, h - 30, w, h);
ctx.fill();
document.body.append(biggerCanvas); //just to show it has drawn the border
<canvas height="400" width="400" style="border: 30px solid black; border-radius: 5px; border-collapse: collapse;">
I solved my problem with html2canvas here is my code
html2canvas(canvas,{backgroundColor: "transparent"}).then(function (canvas) {
var myImage = canvas.toDataURL();
downloadURI(myImage, `qr-pollective.png`);
});
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
}

HTML5 Canvas stroke text overlap joinning part in Arabic, Hindi, Bengali etc language

In Arabic, Hindi, Bengali etc language, each letter joining each other while writing. But in HTML5 Canvas textStroke, these strokes are not joining. Is there any way to join these overlapping joining point?
Picture: Problem with an overlap of joining parts
Picture: These joining parts should be joined
var arabic = document.getElementById("arabic");
var ctx = arabic.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 3;
ctx.strokeText(" اَلْعَرَبِيَّةُ ", 10, 100);
var hindi = document.getElementById("hindi");
var ctx = hindi.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 3;
ctx.strokeText("हिन्दी", 10, 100);
var bengali = document.getElementById("bengali");
var ctx = bengali.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 3;
ctx.strokeText("বেঙ্গলি", 10, 100);
JSFiddle example: https://jsfiddle.net/qa9t64bd/
Custom Shadow Filter is no need to solve this problem. Just add ctx.globalCompositeOperation = "destination-out"; and then add fillText. It will automaticly clip the text stroke and fillText.
var arabic = document.getElementById("arabic");
var ctx = arabic.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 8;
ctx.strokeText(" اَلْعَرَبِيَّةُ ", 10, 100);
ctx.globalCompositeOperation = "destination-out";
ctx.fillText(" اَلْعَرَبِيَّةُ ", 10, 100);
var hindi = document.getElementById("hindi");
var ctx = hindi.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 8;
ctx.strokeText("हिन्दी", 10, 100);
ctx.globalCompositeOperation = "destination-out";
ctx.fillText("हिन्दी", 10, 100);
var bengali = document.getElementById("bengali");
var ctx = bengali.getContext("2d");
ctx.font = "100px Georgia";
ctx.lineWidth = 8;
ctx.strokeText("বেঙ্গলি", 10, 100);
ctx.globalCompositeOperation = "destination-out";
ctx.fillText("বেঙ্গলি", 10, 100);
canvas {
background: #FFFF00;
}
<canvas id="arabic" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<canvas id="hindi" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<canvas id="bengali" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
JSFiddle Link - https://jsfiddle.net/1nc5owp7/1/

HTML5 Canvas - Hide text parts when it's out of my rectangle

My problem is simple. I just want to make invisible text parts when it's out of my rectangle. This image will help to understand what I want. How can I make invisible gray parts of text at canvas? Thanks for help!
After drawing your rectangle, invoke
ctx.clip();
Then draw the parts that should be only inside it.
Source
I would use ctx.globalCompositeOperation = "source-atop"
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 400;
let ch = canvas.height = 110;
ctx.fillStyle = "#ccc";
ctx.beginPath();
ctx.fillRect(100,25,200,60);
ctx.globalCompositeOperation = "source-atop"
ctx.font="2em Verdana";
ctx.fillStyle = "#f00";
ctx.fillText("This is some text",110,65);
canvas{border:1px solid;}
<canvas id="canvas"></canvas>

Unable to apply different fill style to two canvas rectangle

Why am I not able to add two different styles to two Rectangles ctx and ctx2 in the following code?
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = 'red';
ctx.rect(20, 20, 150, 100);
ctx.fill();
var ctx2 = c.getContext("2d");
ctx2.fillStyle = 'green';
ctx2.rect(60, 120, 150, 100);
ctx2.fill();
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

Text with different color from colored square inside canvas rectangle

May be is something easy but is it possible to make this green text Text 1 black in order to be visible above green square?
var c = document.getElementById("canva");
var ctx = c.getContext("2d");
ctx.font = "20px Arial black";
ctx.strokeStyle = 'black';
ctx.fillStyle = "green";
ctx.fillRect(60,60,80,80);
ctx.fillText("Text 2",120,130);
ctx.strokeText("Text 1",55,50);
<canvas id="canva" width="200" height="200" style="border:3px dotted red; border-radius: 5px;"></canvas>
Text 1 is already black but it's just a stroke, not a fill. You can change the fill colour (of Text 2) by resetting the fillStyle after drawing the box but before setting the text:
var c = document.getElementById("canva");
var ctx = c.getContext("2d");
ctx.font = "20px Arial black";
ctx.strokeStyle = 'black';
ctx.fillStyle = "green";
ctx.fillRect(60,60,80,80);
ctx.fillStyle = 'black';
ctx.fillText("Text 2",120,130);
ctx.strokeText("Text 1",55,50);
<canvas id="canva" width="200" height="200" style="border:3px dotted red; border-radius: 5px;"></canvas>
<script>
var c = document.getElementById("canva");
var ctx = c.getContext("2d");
ctx.font = "20px Arial black";
ctx.strokeStyle = 'black';
ctx.fillStyle = "green";
ctx.fillRect(60,60,80,80);
ctx.strokeText("Text 2",120,130);
ctx.strokeText("Text 1",55,50);
</script>

Categories