So I am very new to programming at all and it might seem obvious to you, but I can't figure out why the following code won't work (the first three lines of the script are nescessary for another part of the full Webpage, but I don't see why that would hinder the rest of the code working) :
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
document.getElementById("demo2").style.background = "red";
document.getElementsById("demo2").style.fontSize = "190%";
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
</script>
</body>
</html>
It works fine.
I removed the first 3 lines of code because the element dont exist and that crashes your JS
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
</script>
</body>
</html>
As you said earlier the first three lines of your code is hinder working the rest of your codes.
So why it is happening?
The javascript is a single-threaded language so it will go into your code line by line
1| document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
2| document.getElementById("demo2").style.background = "red";
3| document.getElementsById("demo2").style.fontSize = "190%";
...
So whenever you got this it will run the first line then the second, then the rest line by line. Due to this feature whenever one of your lines throw and error the rest functionality will be stopped.
What we can do in your case then?
Since you got the same script for multiple pages, then you should consider which part of code you want to run (actually which part is runnable).
There are several ways to do this:
Make conditions on your scripts
In this approach you should define a set of condition to check whether the elements exist in the page or not, so your code should be something like this:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var demo2 = document.getElementById("demo2");
if (demo2) {
demo2.innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
}
var c = document.getElementById("myCanvas");
if (c) {
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
}
</script>
</body>
</html>
Make your code modular
In order to run each specific part of code you can create two different modules, so let's assume the first one is:
// demo2.js
document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
document.getElementById("demo2").style.background = "red";
document.getElementsById("demo2").style.fontSize = "190%";
and the second part is:
// canvas.js
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
and this is the page that you using demo2:
<!DOCTYPE html>
<html>
<body>
<div id='demo2'>
...
</div>
<script src="./demo2.js"></script> // I just assuemed they both are in same directory
</body>
</html>
and this is the page that you using canvas:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script src="./canvas.js"></script> // I just assuemed they both are in same directory
</body>
</html>
Create empty div's with display: none; in each page in order to prevent error (not preferable at all)
This approach is not preferred at all because you will add a useless element to your DOM and only make your DOM bigger for no reason.
<!DOCTYPE html>
<html>
<body>
<div style="display: none;" id="demo2"></div>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var demo2 = document.getElementById("demo2");
demo2.innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
</script>
</body>
</html>
I assume you want something like this:
const setup = () => {
const demo2 = document.getElementById("demo2");
if(demo2 !== null) {
demo2.textContent = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
}
const c = document.getElementById("myCanvas");
if(c !== null) {
let ctx = c.getContext("2d");
// Create gradient
let grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
}
}
//load
window.addEventListener('load', setup);
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
</body>
</html>
Related
I want to show a countdown timer using JavaScript. However when I insert the current value to be 31,41,51,99,61,81 and few other numbers I am unable to get the Arc based on the inserted current value. The Arc should display the current value. As the number gets reducing, closer to Zero, the Arc should keep moving towards completing the circle.
I tried using HTML5 Canvas, I almost close to getting the answer but it's throwing some error.
The fields should have Maximum Value input text field and Current Value text field and a button which on clicked should display the Current Value Arc inside Canvas Element. Please help
<!-- Click event function, works when button is clicked -->
function clickevent()
{
var max=document.getElementById("maxsec").value;
var curr=document.getElementById("currsec").value;
myFunction(max,curr);
}
//This is the
function myFunction(maxvalue,currentvalue) {
//alert(maxvalue + ' ' + currentvalue);
if (currentvalue<=maxvalue)
{
var x = (2*3.14*currentvalue/maxvalue);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
ctx.font="15px Georgia";
ctx.textAlign = "center";
ctx.fillText(currentvalue,c.width/2, c.height/2);
ctx.beginPath();
ctx.arc(75, 75, 50, x, 2 * Math.PI);
// ctx.lineWidth = 10;
// line color
ctx.strokeStyle = 'black';
ctx.stroke();
}
if (maxvalue==currentvalue)
{
ctx.clearRect(0, 0, c.width, c.height);
ctx.font="15px Georgia";
ctx.textAlign = "center";
ctx.fillText("Time Up",c.width/2, c.height/2);
ctx.textAlign="center";
}
}
<!DOCTYPE html>
<html>
<body>
<div>
Max Second: <input type="text" id="maxsec" value="300"><br/>
Current Second: <input type="text" id="currsec" value="150">
<button onclick="clickevent()">Click me</button>
<br/>
//This is the canvas section where the Arc or the curvature will be displayed.
<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
</div>
</body>
</html>
You are passing the values as a string into the function instead of number, if you change the below lines of code, it works fine!
JS:
var max=parseInt(document.getElementById("maxsec").value);
var curr=parseInt(document.getElementById("currsec").value);
myFunction(max,curr);
JSFiddle Demo
Please use this attempt of making your timer using setTimeout() function as a reference and build your code!
JSFiddle Demo
In one of my applications, I am reading picture on the canvas as ImageData.
Sample code is
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(100, 100);
var i;
for (i = 0; i < imgData.data.length; i += 4) {
imgData.data[i+0] = 255;
imgData.data[i+1] = 0;
imgData.data[i+2] = 0;
imgData.data[i+3] = 255;
}
ctx.putImageData(imgData, 10, 10);
</script>
<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>
</body>
</html>
I am passing same ImageData to various other APIs and these other APIs need unique id for each ImageData to differentiate. So, I simply modified code as shown below :
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(100, 100);
var i;
for (i = 0; i < imgData.data.length; i += 4) {
imgData.data[i+0] = 255;
imgData.data[i+1] = 0;
imgData.data[i+2] = 0;
imgData.data[i+3] = 255;
}
ctx.putImageData(imgData, 10, 10);
imgData.id = 21323;
alert("imgData.id --"+imgData.id);
imgData.picType = "Rect";
alert("imgData.picType --"+imgData.picType);
</script>
<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>
</body>
</html>
I am curious to know how it worked - addition of some properties to ImageData?
Like everything else in javascript ImageData too is an object and as you might be aware adding new properties to objects in JS is a matter of obj1.prop1 = val1
Now you might ask why adding some random value to your ImageData didn't corrupt your image ? The answer is simple : byte representation of image is stored in data property of ImageData as a Uint8ClampedArray .
Console dump of imageData
I need to draw a text string at a precise position on HTML5 canvas.
Here's my test code:
<!DOCTYPE html>
<html>
<body>
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
ctx.textBaseline = "top";
ctx.font = '100px Arial';
ctx.textAlign = 'left';
ctx.fillStyle = 'rgba(0, 0, 0, 255)';
ctx.fillText('Test', 0, 0);
}
</script>
</body>
</html>
The margin at the top is different in Chrome and Firefox:
I'm going to draw other elements (e.g. images, shapes) on the canvas, and I need to make sure the text appears at the same position in all browsers. Is it possible?
Cause
As #iftah says: This mis-alignment is caused by a Firefox bug.
Please add your voice to the Firefox's bug page so they fix it soon.
Workaround
(Unfortunately), The workaround is to draw the text on a second canvas and scan that pixel data to find the topmost & leftmost pixel of the text.
Then draw the text on the main canvas but pulled upward and leftward by the calculated pixel offsets.
Here is annotated code and a Demo:
// canvas vars
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// test vars
var text='Test';
var fontsize=100;
var fontface='arial';
drawTextAtXY(0,0,text,fontsize,fontface,'black');
function drawTextAtXY(x,y,text,fontsize,fontface,fill){
// find the leftmost & topmost pixel of the text
var minXY=getTextTop(text,fontsize,fontface);
// set the font styles
ctx.textBaseline='top';
ctx.font=fontsize+'px '+fontface;
ctx.fillStyle=fill;
// draw the text
// Pull the text leftward and topward by minX & minY
ctx.fillText(text,x-minXY.x,y-minXY.y);
}
function getTextTop(text,fontsize,fontface){
// create temp working canvas
var c=document.createElement('canvas');
var w=canvas.width;
var h=fontsize*2;
c.width=w;
c.height=h;
var cctx=c.getContext('2d');
// set font styles
cctx.textBaseline='top';
cctx.font=fontsize+'px '+fontface;
cctx.fillStyle='red';
// draw the text
cctx.fillText(text,0,0);
// get pixel data
var imgdata=cctx.getImageData(0,0,w,h);
var d=imgdata.data;
// scan pixel data for minX,minY
var minX=10000000;
var minY=minX;
for(var y=0;y<h;y++){
for(var x=0;x<w;x++){
var n=(y*w+x)*4
if(d[n+3]>0){
if(y<minY){minY=y;}
if(x<minX){minX=x;}
}
}}
// return the leftmost & topmost pixel of the text
return({x:minX,y:minY});
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Text drawn exactly at specified X,Y</h4>
<canvas id="canvas" width=300 height=200></canvas>
You can fix it easily.
you can use textBaseline = "middle";
and must use transform to 50px of top
means:
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
ctx.textBaseline = "middle";
ctx.font = '100px Arial';
ctx.textAlign = 'left';
ctx.fillStyle = 'rgba(0, 0, 0, 1)';
ctx.save();
ctx.transform(1, 0, 0, 1, 0, 50);
ctx.fillText('Test', 0, 0);
ctx.restore();
}
</script>
A another bug is in your code: rgba(0, 0, 0, 255)
fourth number in rgba must be between 0-1 for example 0.75.
why I write .save() and .restore() ?
for reset transform and clear after use it.
Of course you can use
ctx.fillText('Test', 0, 50);
Instead
ctx.save();
ctx.transform(1, 0, 0, 1, 0, 50);
ctx.fillText('Test', 0, 0);
ctx.restore();
This appears to be a bug in Firefox dating back to 2012 and still not fixed!
See https://bugzilla.mozilla.org/show_bug.cgi?id=737852
Edit:
Setting the baseLine to "alphabetic" (the default) results in both Chrome and Firefox having the same vertical location for the text.
Edit:
Unfortunately, the vertical location isn't the only difference between Firefox and Chrome. Changing the string to "Testing" shows clearly that not only is the vertical location different, but also the space between the letters is slightly different - resulting in different width of the text.
If you really must have pixel perfect location AND size of the text maybe you should use Bitmap fonts
As stated in other answer it's some king of bug (or maybe just a different implementation). textBaseline bottom and Y position to 100 can fix it.
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
ctx.textBaseline = "bottom";
ctx.font = '100px Arial';
ctx.textAlign = 'left';
ctx.fillStyle = 'rgba(150, 50, 0, 1)';
ctx.fillText('Test', 0, 100);
}
</script>
In general: Use baseline bottom and increase Y position the font size amount
So my code displays an html page with some text on it and then below that I have a "clear Canvas" button which I would like to have clear the canvas once pushed and then be able to draw on this blank canvas. My clear canvas button isn't working, it isn't doing anything once pushed. I'm using a call back in order to perform the canvas clear and the html file is connected to a javascript file which then draws things on the new cleared canvas. The first code here is the .html file with the canvas that is being cleared that also has the.js file joined to it.
I tried context.Rect(x, y, w, h);
and canvas.width.canvas.width;
and neither seem to work. I'm using Chrome
<html><head></head>
<h3> </h3>
<body >
<canvas id="main" width="300" height="500"></canvas>
<script>
var canvas = document.getElementById("main");
var context = canvas.getContext('2d');
context.fillStyle = "#008000";
context.rect(0,0,300,300);
context.fill();
</script>
</body></html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalble=no,initial-scale=1.0,maximum-scale=1.0" />
<style>
body { padding:10px; margin:0px; background-color: #FF9; }
#main { margin: 10px auto 0px auto; }
</style>
<script src=".js"></script>
</head>
<body >
<button id="clear">Clear Canvas</button><br>
<canvas id="main" width="300" height="500"></canvas>
</body>
</html>
//end of .html file
// JavaScript Document
// wait until window is fully loaded into browser
window.onload = function()
{
// so smart phone does not move/resize image when touched
document.ontouchmove = function(e)
{
e.preventDefault();
}
var canvas = document.getElementById('main');
// Number of pixels used by the Clear button above canvas
var canvasTop = canvas.offsetTop;
var context = canvas.getContext('2d');
var lastX, lastY;
context.strokeStyle = #FA8072;
context.lineCap = 'round';
context.lineJoin = 'round';
context.lineWidth = 8;
context.fill();
// Function to Clear the Canvas
function clear()
{
context.fillStyle = 'blue'
context.rect( 0, 0, 300, 500);
context.fill();
}
// Function Dot (to start a new line or just a point)
function dot(x,y)
{
context.beginPath();
context.fillStyle = '#D2691E';
// draw tiny circle
context.arc(x,y,1,0, Math.PI*2, true);
context.fill();
context.closePath();
}
// Handle the Clear button
var clearButton = document.getElementById('clear');
// set callback funct. clear()for future touch events
clearButton.onclick = clear;
clear(); // do a clear canvas now
} // end window.onload
You've got a typo on this line:
context.strokeStyle = #FA8072;
You need quotes:
context.strokeStyle = '#FA8072';
With that fixed it seems to work: http://jsfiddle.net/eMSXU/
(By the way, you might like to press the "Tidy Up" button in the fiddle to see how your code should've been indented...)
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="100" height="200" style="border:5px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image();
img.onload = function(){
// execute drawImage statements here};
cxt.drawImage(img,0, 0, 50, 50, 0, 0);
}
img.src = "myimg.png";
</script>
</body>
</html>
Maybe I'm missing something, but I don't see any onload. And I think you're missing some arguments. As far as I know, drawImage takes 3, 5, or 9 arguments. Since you're at 7, you're probably looking for the nine argument function.
Try:
<html>
<head>
<script type="text/javascript">
function init() {
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image();
img.onload = function(){
// execute drawImage statements here;
// drawImage( src, sx,sy, sw, sh, dx, dy, dw, dh ); <-- 9 arg form.
// src = the img (new Image();)
// sx, sy, sw, sh = The rectangle to draw to.
// dx, dy = Where to position it.
// dw, dh = Width and height to scale to.
cxt.drawImage(img,0, 0, 50, 50, 0, 0, 50, 50);
}
img.src = "myimg.png";
}
window.onload = init;
</script>
</head>
<body>
<canvas id="myCanvas" width="100" height="200" style="border:5px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
</body>
</html>
Hope that helps. For a better look at how to use canvas with images, try visiting:
http://diveintohtml5.ep.io/canvas.html#images
I'm not sure exactly what you are trying to achieve but to just display the image here's some simplified code:
<script type="text/javascript">
var c=document.getElementById("myCanvas").getContext("2d");
var img=new Image();
img.src = 'myimg.png';
img.onload = function(){
// execute drawImage statements here
c.drawImage(img,0,0);
}
</script>
You're original code is correct except for the drawImage() call which requires either two more arguments, or you can drop all except the first three.
You also don't need to hook the window.onload event because the JavaScript is being executed in the body element which has the same effect so the answer directing you to do that whilst correct, isn't required.
Here is your code with the fix in place:
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="100" height="200" style="border:5px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c = document.getElementById("myCanvas"),
cxt = c.getContext("2d"),
img = new Image();
img.onload = function(){
// Execute drawImage() statements here
cxt.drawImage(img, 0, 0, this.width, this.height, 0, 0, this.width, this.height);
}
img.src = "myimg.png";
</script>
</body>
</html>