Why on dynamically created canvas context does not work? - javascript

Look: http://jsfiddle.net/MrHIDEn/QYL3t/
This code draws 3 boxes Reg,Green,Blue but context("2d") from Blue does do nothing. Why?
HTML:
<div id="divR">
<canvas id="cvsR" width="100" height="100" style="border:1px solid red"></canvas>
</div>
<div id="divG"></div>
<div id="divB"></div>
Javascript:
var cvsR = document.getElementById("cvsR");
var ctxR = cvsR.getContext("2d");
ctxR.fillStyle = "red";
ctxR.fillRect(0, 0, 50, 75);
var divG = document.getElementById("divG");
divG.innerHTML = '<canvas id="cvsG" width="100" height="100" style="border:1px solid green"></canvas>';
var cvsG = document.getElementById("cvsG");
var ctxG = cvsG.getContext("2d");
ctxG.fillStyle = "green";
ctxG.fillRect(0, 0, 50, 75);
// Dynamiclly
var divB = document.getElementById("divB");
var cvsB = document.createElement("canvas");
cvsB.width = 100;
cvsB.height = 100;
cvsB.style.border = "1px solid blue";
cvsB.id = "cvsB";
var ctxB = cvsB.getContext("2d");
ctxB.fillStyle = "blue";
ctxB.fillRect(0, 0, 50, 75);
divB.innerHTML = cvsB.outerHTML;

Your problem is here divB.innerHTML = cvsB.outerHTML;, with this code you aren't adding the canvas cvsB to divB but a can vas with the same html as cvsB. To add cvsB to the div just append it
divB.appendChild(cvsB);
http://jsfiddle.net/QYL3t/14/

I would append the canvas before reading the context, but it works without this, so this is just my personal preference:
cvsB.id = "cvsB";
divB.appendChild(cvsB);
var ctxB = cvsB.getContext("2d");
ctxB.fillStyle = "blue";
ctxB.fillRect(0, 0, 50, 75);

Related

How to pass new variable at one Canvas on javascript (No Jquery)

I have a problem with the canvas in javscript, I have a function that passes four values ​​to another function as soon as I click an image, each image passes different values, these values ​​I use to draw the chart with rectangles on the canvas, and it works! But as soon as I click another image, the rectangle values ​​of the graph do not change, they remain the same.
Where's the problem?
html
<canvas id="canvas" width="500" height="250"></canvas>
javascript
function gestoreInformazioni(){
for (var i = 0; i < pizzeRegioni.length; i++){
var pizza = pizzeRegioni[i];
if( this.id === pizza.nome ){
generaGrafico(pizza.prezzo, pizza.carboidrati, pizza.grassi, pizza.proteine);
}
}
}
function generaGrafico(prezzo, carboidrati, grassi, proteine){
try{
var ctx = canvas.getContext("2d");
// ctx.beginPath();
ctx.fillStyle='rgb(255,255,0)';
ctx.translate(0,200);
ctx.fillRect(10,-(prezzo),40,150);
ctx.fillRect(100,-(carboidrati),40,150);
ctx.fillRect(200,-(grassi),40,150);
ctx.fillRect(300,-(proteine),40,150);
}catch(e){
alert("generaGrafico " + e);
}
}
init
nodoImgPizza = document.getElementsByClassName("img_pizza");
for(var i = 0; i<nodoImgPizza.length; i++){
nodoImgPizza[i].onclick = gestoreInformazioni;
}
accociativeArray
var pizzeRegioni=[
{
nome:"Lardellata",
regione:"Toscana",
ingredienti :["pomodoro","mozzarella","lardo di Colonnata","ciliegini","porcini"],
minX:134,
minY:128,
maxX:202,
maxY:222,
prezzo:6.50,
carboidrati : 10,
grassi : 15,
proteine : 20,
},
{
nome:"Senese",
regione:"Toscana",
ingredienti :["pomodoro","mozzarella","crudo di cinta senese","porcini"],
minX:134,
minY:128,
maxX:202,
maxY:222,
prezzo:10,
carboidrati : 100,
grassi : 30,
proteine : 40,
}
];
To Re-Draw the same canvas over and over again, first you must reset canvas and then you can draw again.
See this snippet example:
// on document ready
document.addEventListener("DOMContentLoaded", function(){
function grafic(price, carbo, fat, protein){
try{
// Canvas Element
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d");
// Reset Canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, 500, 400);
// Draw (Re-Draw) Canvas
ctx.fillStyle='rgb(255,255,0)';
ctx.translate(0,200);
ctx.fillRect(10,-(price),40,150);
ctx.fillRect(100,-(carbo),40,150);
ctx.fillRect(200,-(fat),40,150);
ctx.fillRect(300,-(protein),40,150);
} catch(e){
alert("generaGrafico " + e);
}
}
// test buttons
document.getElementById("a").addEventListener("click",function() {
grafic(20, 40, 60, 80);
})
document.getElementById("b").addEventListener("click",function() {
grafic(40, 20, 60, 100);
})
document.getElementById("c").addEventListener("click",function() {
grafic(60, 40, 20, 10);
})
document.getElementById("d").addEventListener("click",function() {
grafic(80, 100, 40, 20);
})
});
div {
margin: 5px;
padding: 5px;
display: inline-block;
border: 1px solid black;
cursor: pointer;
}
<div id="a">Image A</div>
<div id="b">Image B</div>
<div id="c">Image C</div>
<div id="d">Image D</div>
<br/>
<canvas id="canvas" width="500" height="250"></canvas>
There is a typo "far" should be "fat"
ctx.fillRect(200,-(far),40,150);
I've slightly edited your code to demonstrate it works now.
function grafic(price, carbo, fat, protein){
try{
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d");
ctx.fillStyle='rgb(255,255,0)';
ctx.translate(0,200);
ctx.fillRect(10,-(price),40,150);
ctx.fillRect(100,-(carbo),40,150);
ctx.fillRect(200,-(fat),40,150);
ctx.fillRect(300,-(protein),40,150);
}catch(e){
alert("generaGrafico " + e);
}
}
grafic(4,4,4,4);
<canvas id="canvas" width="500" height="250" style="border:1px solid; height 20px; min-widht: 200px"></canvas>

Dynamically generated canvas elements in ASP.NET

I have multiple canvas elements which appear dynamically on my page based on VB code.
This is what my aspx page looks like:
<canvas id="canvasnhlrc" width="225" height="200" runat="server"></canvas>
<canvas id="canvascwl" width="225" height="200" runat="server"></canvas>
<canvas id="canvashslanguages" width="225" height="200" runat="server"></canvas>
This is what my aspx.vb code looks like:
canvasnhlrc.Visible = False
canvascwl.Visible = False
canvashslanguages.Visible = False
If RouteData.Values("mediasubType") IsNot Nothing Then
Dim qsubMedia As String = RouteData.Values("mediasubType")
Select Case qsubMedia
Case "nhlrc"
canvasnhlrc.Visible = True
Case "cwl"
canvascwl.Visible = True
Case "hslanguages"
canvashslanguages.Visible = True
End Select
End If
So, if my page is example.com/nhlrc, then the canvas is generated as
<canvas id="ContentPlaceHolder2_canvasnhlrc" width="225" height="200"></canvas>
Accordingly, I have formatted my js file as follows:
function init()
{
var w1 = document.getElementById('ContentPlaceHolder2_canvasnhlrc')
var w1x = w1.getContext('2d');
w1x.shadowOffsetX = 0;
w1x.shadowOffsetY = 0;
w1x.shadowBlur = 20;
w1x.shadowColor = "rgba(0, 0, 0, 0.75)";
w1x.fillStyle = 'rgb(218, 233, 246)';
w1x.beginPath();
w1x.moveTo(25, 25);
w1x.lineTo(175, 25);
w1x.lineTo(175, 50);
w1x.lineTo(200, 75);
w1x.lineTo(175, 100);
w1x.lineTo(175, 175);
w1x.lineTo(25, 175);
w1x.closePath();
w1x.fill();
var w2 = document.getElementById('ContentPlaceHolder2_canvascwl')
var w2x = w2.getContext('2d');
w2x.shadowOffsetX = 0;
w2x.shadowOffsetY = 0;
w2x.shadowBlur = 20;
w2x.shadowColor = "rgba(0, 0, 0, 0.75)";
w2x.fillStyle = 'rgb(12, 64, 114)';
w2x.beginPath();
w2x.moveTo(25, 25);
w2x.lineTo(175, 25);
w2x.lineTo(175, 50);
w2x.lineTo(200, 75);
w2x.lineTo(175, 100);
w2x.lineTo(175, 175);
w2x.lineTo(25, 175);
w2x.closePath();
w2x.fill();
var w3 = document.getElementById('ContentPlaceHolder2_canvashslanguages')
var w3x = w3.getContext('2d');
w3x.shadowOffsetX = 0;
w3x.shadowOffsetY = 0;
w3x.shadowBlur = 20;
w3x.shadowColor = "rgba(0, 0, 0, 0.75)";
w3x.fillStyle = 'rgb(12, 64, 114)';
w3x.beginPath();
w3x.moveTo(25, 25);
w3x.lineTo(175, 25);
w3x.lineTo(175, 50);
w3x.lineTo(200, 75);
w3x.lineTo(175, 100);
w3x.lineTo(175, 175);
w3x.lineTo(25, 175);
w3x.closePath();
w3x.fill();
}
onload = init;
Sadly, I can only get the first canvas element (NHLRC) to appear while the subsequent canvases (example.com/cwl, etc.) do not render. There is nothing wrong with the code because when I comment out the other two elements in the JS code, it works fine, so what am I missing, doing wrong, or what's conflicting that's not allowing each of the canvas elements to render in its corresponding page?
Your init function has too many responsibilities (find, verify and draw) * 3 .
When any one of those responsibilities meets with a failure, i.e. can't find an element, the show stops. In your case w1, w2, w3 will only be defined in their respective pages, not for every page.
You can simplify it as below:
function draw(theCanvasEl, theFill)
{
var w1x = theCanvasEl.getContext('2d');
w1x.shadowOffsetX = 0;
w1x.shadowOffsetY = 0;
w1x.shadowBlur = 20;
w1x.shadowColor = "rgba(0, 0, 0, 0.75)";
w1x.fillStyle = theFill;
w1x.beginPath();
w1x.moveTo(25, 25);
w1x.lineTo(175, 25);
w1x.lineTo(175, 50);
w1x.lineTo(200, 75);
w1x.lineTo(175, 100);
w1x.lineTo(175, 175);
w1x.lineTo(25, 175);
w1x.closePath();
w1x.fill();
}
function init()
{
var canvases = [['ContentPlaceHolder2_canvasnhlrc', 'rgb(218, 233, 246)'],
['ContentPlaceHolder2_canvascwl', 'rgb(12, 64, 114)'],
['ContentPlaceHolder2_canvashslanguages', 'rgb(12, 64, 114)']];
for(var i=0;i<canvases.length;i++)
{
var theCanvas = document.getElementById(canvases[i][0]);
if (theCanvas!=null) {
draw(theCanvas, canvases[i][1]);
break;
}
}
}
onload = init;

how to set div background as canvs

Here is my code:
<!DOCTYPE html>
<html>
<body>
<div id='rect' style='width:200px;height:200px;border:1px solid red'>
</div>
<canvas id="myCanvas" style="border:1px solid #d3d3d3;">
<script>
patternStyle = document.getElementById("myCanvas");
var patternContext = patternStyle.getContext('2d');
patternStyle.width = 6;
patternStyle.height = 6;
patternContext.globalAlpha = 10;
patternContext.fillStyle = 'white';
patternContext.rect(0, 0, 6, 6);
patternContext.fillRect(0, 0, 6, 6);
patternContext.strokeStyle = 'red';
patternContext.lineWidth = 2;
patternContext.beginPath();
patternContext.moveTo(3, -3);
patternContext.lineTo(-3, 3);
patternContext.moveTo(0, 6);
patternContext.lineTo(6, 0);
patternContext.moveTo(9, 3);
patternContext.lineTo(3, 9);
patternContext.stroke();
</script>
</body>
</html>
I need to set the rect(id of the div) background image as myCanvas(id of the canvas). How can I achieve this?
Find the jsfiddle link here: http://jsfiddle.net/yLL48one/
Check out the updated fiddle: http://jsfiddle.net/yLL48one/1/
The key lines are:
dataUrl = document.getElementById('myCanvas').toDataURL();
document.getElementById('rect').style.background='url('+dataUrl+')';

Adding Click Event Handler onto Multiple Canvas

I am fairly new to javascript and HTML5, so excuse me if it turns out to be a silly mistake
I am drawing 3 canvas programmatically with some text and a rectangle and i want a click event on each one of them, also I need to know which canvas has been clicked, i wrote the following code but doMouseDown function is executed even without click
<canvas id="myCanvas1" width="452" height="80" style="border:0px solid #d3d3d3;"></canvas>
<canvas id="myCanvas2" width="452" height="80" style="border:0px solid #d3d3d3;"></canvas>
<canvas id="myCanvas3" width="452" height="80" style="border:0px solid #d3d3d3;"></canvas>
<script>
function init()
{
var rect = { w: 300, h: 60 };
var point = { x: 150, y: 10 };
for (var i = 1 ; i < 4 ; i++) {
var canvasStr = "myCanvas" + Number(i);
var c = document.getElementById(canvasStr);
var context = c.getContext("2d");
// text
context.font = "22pt Arial";
context.lineWidth = 2;
context.fillStyle = "#000000";
var studentStr = "Student " + Number(i);
context.fillText(studentStr, 5, 50);
// rectangle
context.strokeStyle = "black";
context.strokeRect(point.x, point.y, rect.w, rect.h);
context.fillStyle = "#00FF00";
context.fillRect(point.x, point.y, rect.w, rect.h);
c.addEventListener('mousedown', doMouseDown(canvasStr), false);
}
}
function doMouseDown(canvasStr)
{
alert(canvasStr);
}
init();
</script>
How can i fix it and know which canvas has been clicked (canvasStr in this case)
You can do it this way
c.addEventListener("mousedown", function () {
doMouseDown(canvasStr)
}, false);
and then write in that function
function doMouseDown(canvasStr) {
alert(canvasStr);
}
if you're attaching listeners in a loop, you have to create a closure, otherwise canvasStr will allways be == myCanvas3:
(function(str) {
c.addEventListener('mousedown', doMouseDown.bind(str), false);
}(canvasStr));
Then your callback should be:
function doMouseDown(e, canvasStr) {
alert(canvasStr);
}
First argument e is the Event object which is always passed to callbacks.
ADDED
There is no point in doing this:
var canvasStr = "myCanvas" + Number(i);
i is already a number and you are adding it to a string. Just write:
var canvasStr = "myCanvas" + i;
Another way is to wrap all 3 canvases in a container div and listen for events on the container
http://jsfiddle.net/m1erickson/g7fsS/
<div id="container">
<canvas id="myCanvas1" width="45" height="80"></canvas>
<canvas id="myCanvas2" width="45" height="80"></canvas>
<canvas id="myCanvas3" width="45" height="80"></canvas>
</div>
document.getElementById("container").addEventListener("click",function(e){
console.log(e.target.id);
},false);

Toggle Onclick Issue in Javascript

Simply put, I'm trying to toggle a button to make a line bold (or not). I read a few questions here similar to this problem, but the solutions haven't helped me. Here's my code:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="DrawLineDiv">
<canvas id="DrawLineCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('DrawLineCanvas');
var context = canvas.getContext('2d');
// Use beginPath() to declare that a new path is to be drawn
context.beginPath();
// Place the drawing cursor at the desired point
context.moveTo(100, 150);
// Determine where to stop drawing
context.lineTo(450,50);
//Draw the line
context.stroke();
</script>
</div>
<script>
var canvas = document.getElementById("DrawLineCanvas");
//var context = canvas.getContext('2d');
function toggleLineBold(button) {
var button;
if (button == "BoldNow") {
context.lineWidth = 15;
context.stroke();
document.getElementById("BoldLineButton").onclick = function(){
toggleLineBold('Regular');
};
} else {
context.lineWidth = 1;
context.stroke();
document.getElementById("BoldLineButton").onclick = function(){
toggleLineBold('BoldNow');
};
return;
};
};
</script>
<div id="BoldLineButton" style="height:50px; width:120px; border:2px solid #6495ed; background-color:#bcd2ee; border-radius:10px; margin-left: 5px; text-align:center" onclick="toggleLineBold('BoldNow')">
<br/>Toggle Bold Line<br/>
</div>
</body>
</html>
The line changes to bold, but triggers an error in the javascript at the line trying to change the onclick event. I know I've got something wrong, I'm just not sure what.
Thank's in advance for your assistance.
LIVE DEMO
HTML:
<canvas id="DrawLineCanvas" width="578" height="200"></canvas>
<button id="BoldLineButton">Line size: <b>1</b></button>
JS:
var doc = document,
canvas = doc.querySelector('#DrawLineCanvas'),
boldBtn = doc.querySelector('#BoldLineButton'),
ctx = canvas.getContext('2d'),
size = [1, 3, 5, 10, 15], // use only [1, 15] if you want
currSize = 0; // size[0] = 1 // Index pointer to get the value out of the
// size Array
function draw(){
canvas.width = canvas.width;
ctx.beginPath();
ctx.moveTo(100, 150);
ctx.lineTo(450,50);
ctx.lineWidth = size[currSize]; // Use currSize Array index
ctx.stroke();
}
draw();
function toggleLineBold() {
++currSize; // Increase size and
currSize %= size.length; // loop if needed.
boldBtn.getElementsByTagName('b')[0].innerHTML = size[currSize];
draw();
}
boldBtn.addEventListener("click", toggleLineBold);

Categories