I am trying to style the closePath() on my canvas but am at a loss on how to do that, as a matter of fact I would actually like all the lines to have a different style, for this question lets stick to getting different colors. ! As you can see I have a triangle, how can I have differing strokestyles for each line? Here is link to the Code Pen
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "red";
ctx.moveTo(20, 140);
ctx.lineTo(120, 10);
ctx.strokeStyle = "green";
ctx.lineTo(220, 140);
ctx.closePath();
ctx.strokeStyle = "blue";
ctx.stroke();
<canvas id="canvas"></canvas>
You would need to have the three lines as three separate paths.
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(20, 140);
ctx.lineTo(120, 10);
ctx.strokeStyle = "red";
ctx.stroke();
ctx.beginPath();
ctx.moveTo(120, 10);
ctx.lineTo(220, 140);
ctx.strokeStyle = "green";
ctx.stroke();
ctx.beginPath();
ctx.moveTo(220, 140);
ctx.lineTo(20, 140);
ctx.strokeStyle = "blue";
ctx.stroke();
<canvas id="canvas"></canvas>
Each segment needs to be coloured.
function qsa(sel,par=document){return par.querySelectorAll(sel)}
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
draw();
}
class vec2d
{
constructor(x=0,y=0)
{
this.x = x;
this.y = y;
}
}
function draw()
{
var verts = [ new vec2d(20,140), new vec2d(120, 10), new vec2d(220,140) ];
var colours = ['red', 'green', 'blue'];
let can = qsa('canvas')[0];
let ctx = can.getContext('2d');
var numLineSegs = verts.length;
for (var lineSegIndex=0; lineSegIndex<numLineSegs; lineSegIndex++)
{
var index1 = lineSegIndex;
var index2 = (lineSegIndex+1)%verts.length;
ctx.beginPath();
ctx.strokeStyle = colours[index1];
ctx.moveTo(verts[index1].x, verts[index1].y);
ctx.lineTo(verts[index2].x, verts[index2].y);
ctx.stroke();
}
ctx.closePath();
}
<canvas width=512 height=512></canvas>
Related
How do I make a row of triangles?
Here's the code I have so far.
I'm new I don't know what to do here.
function showDrawing() {
let coolCanvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
ctx.lineWidth = 5;
for (let i = 0; i < 5; i += 1) {
ctx.beginPath();
ctx.moveTo(126, 300);
ctx.lineTo(200, 400);
ctx.lineTo(50, 400);
ctx.closePath();
ctx.strokeStyle = 'blue';
ctx.fillStyle = 'purple';
ctx.fill();
ctx.stroke();
}
}
<canvas id="canvas" width="1500" height="700" style="border:3px solid #000000;">
</canvas>
<button onclick="showDrawing()">Drawing</button>
You can use the iteration (i) and multiply it by the spacing you want and add it to the x value.
function showDrawing() {
let coolCanvas = document.getElementById("canvas");
let ctx = coolCanvas.getContext("2d");
ctx.lineWidth = 5;
for (let i = 0; i < 5; i += 1) {
ctx.beginPath();
ctx.moveTo(126+(i*170), 300);
ctx.lineTo(200+(i*170), 400);
ctx.lineTo(50+(i*170), 400);
ctx.closePath();
ctx.strokeStyle = 'blue';
ctx.fillStyle = 'purple';
ctx.fill();
ctx.stroke();
}
}
<canvas id="canvas" width="1500" height="700" style="border:3px solid #000000;">
</canvas>
<button onclick="showDrawing()">Drawing</button>
You should use a variable to add to the X positions and increment as you want :
function showDrawing() {
let coolCanvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let delta = 0;
ctx.lineWidth = 5;
for (let i = 0; i < 5; i += 1) {
ctx.beginPath();
ctx.moveTo(126 + delta, 300);
ctx.lineTo(200 + delta, 400);
ctx.lineTo(50 + delta, 400);
ctx.closePath();
ctx.strokeStyle = 'blue';
ctx.fillStyle = 'purple';
ctx.fill();
ctx.stroke();
delta += 174;
}
}
<canvas id="canvas" width="1500" height="700" style="border:3px solid #000000;">
</canvas>
<button onclick="showDrawing()">Drawing</button>
You can create a separate function to handle drawing the triangles, then pass in the xStart as the base x-coordinate value for any triangle to be drawn. Then in the showDrawing function, run a loop and multiply the i variable to some spacing value. In your code, your triangle is 150 pixels wide and starts at x-value of 50, so I multiplied the i value by 200 for consistency in my solution code.
Additionally, I highly advise using the variable name you set (coolCanvas) as the reference to the canvas or set this variable to be named canvas instead. If you only ever set the canvas once and reference it once, you can probably skip setting the reference altogether:
let ctx = document.getElementById("canvas").getContext("2d");
function drawTriangle(ctx, xStart) {
ctx.lineWidth = 5;
ctx.strokeStyle = "blue";
ctx.fillStyle = "purple";
ctx.beginPath();
ctx.moveTo(xStart + 126, 300);
ctx.lineTo(xStart + 200, 400);
ctx.lineTo(xStart + 50, 400);
ctx.closePath();
ctx.fill()
ctx.stroke();
}
function showDrawing() {
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
ctx.lineWidth = 5;
for (let i = 0; i < 5; i += 1) {
drawTriangle(ctx, i * 200);
}
}
document.getElementById("draw").addEventListener("click", showDrawing);
canvas {
border: 3px solid #000000;
}
<div><button id="draw">Drawing</button></div>
<div><canvas id="canvas" width="1500" height="700"></canvas></div>
I'm trying to clear only the strokeRect() and keep content in that rectangle.
In this example, how do I clear green rectangle without affecting the red one?
var cut = [50, 70, 100, 100]
var cut1 = [60, 85, 60, 60]
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(cut[0], cut[1], cut[2], cut[3]);
ctx.lineWidth = 3;
ctx.strokeStyle = 'green';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.rect(cut1[0], cut1[1], cut1[2], cut1[3]);
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.stroke();
ctx.closePath();
<canvas id="canvas" width=400px height=200px></canvas>
Can't figure out how..
Thanks in advance!
You need to clear the canvas and draw the red rectangle again.
var c = document.getElementById("canvas");
c.width=400;
c.height=200;
var ctx = c.getContext("2d");
var cut = [50, 70, 100, 100]
var cut1 = [60, 85, 60, 60]
function drawRectangle(cut,fill){
ctx.beginPath();
ctx.rect(cut[0], cut[1], cut[2], cut[3]);
ctx.lineWidth = 3;
ctx.strokeStyle = fill;
ctx.stroke();
ctx.closePath();
}
drawRectangle(cut,"green");
drawRectangle(cut1,"red");
clear.addEventListener("click",()=>{
ctx.clearRect(0,0, c.width, c.height);
drawRectangle(cut1,"red");
});
canvas{display:block;}
<button id="clear">clear</button>
<canvas id="canvas" width=400px height=200px></canvas>
In your case, clear & redraw is what you really need, but just for completeness, to clear in any shape, you can use compositing operations.
By setting the compositing mode to destination-out, all the pixels that should normally have been filled by your drawings will actually get rendered as transparent.
So to make a simple clear-stroke-rect:
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(20, 20, 80, 80);
// clear
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 5;
ctx.strokeRect(40,40,30,30);
// set back to 'normal'
ctx.globalCompositeOperation = 'source-over';
<canvas id="canvas"></canvas>
But using compositing, you can really clear in any shape, even from bitmap with transparency:
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
ctx.fillStyle = 'red';
ctx.fillRect(20, 20, 80, 80);
// clear
ctx.globalCompositeOperation = 'destination-out';
ctx.drawImage(img, 40,40);
// set back to 'normal'
ctx.globalCompositeOperation = 'source-over';
};
img.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';
<canvas id="canvas"></canvas>
So I have a drawn object:
and it is placed in a block
I need it to animate it with requestAnimationFrame() method and use translate, rotate, scale while it jumps from the bottom to the top sliding to the right.
The problem is I dont know how to merge all of the shapes I've made to one (or how to animate it).
The code of the shape is:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var counterClockwise = false;
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "white";
ctx.moveTo(10, 10);
ctx.lineTo(10, 100);
ctx.stroke();
ctx.beginPath();
ctx.arc(12, 38, 26, 4.7, Math.PI * .5, false);
ctx.lineWidth = "5";
ctx.strokeStyle = 'white';
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(60, 10);
ctx.lineTo(40, 100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(60, 10);
ctx.lineTo(80, 100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "purple";
ctx.moveTo(80, 10);
ctx.bezierCurveTo(100, 145, 150, 100, 145, 10);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "cyan";
ctx.moveTo(160, 10);
ctx.lineTo(160, 95);
ctx.lineTo(200, 95);
ctx.stroke();
#myCanvas { background: #F00; }
<canvas id="myCanvas"></canvas>
Thanks in advance.
You can draw the content of another canvas on your "output" canvas using drawImage (see MDN). This example shows how to scale the image using the dWidth and dHeight parameters:
var c = document.getElementById("myCanvas");
var out = document.getElementById("out");
var ctx = c.getContext("2d");
var outCtx = out.getContext("2d");
var counterClockwise = false;
draw();
outCtx.drawImage(c, 0, 10, 150, 150)
function draw() {
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "white";
ctx.moveTo(10, 10);
ctx.lineTo(10, 100);
ctx.stroke();
ctx.beginPath();
ctx.arc(12, 38, 26, 4.7, Math.PI * .5, false);
ctx.lineWidth = "5";
ctx.strokeStyle = 'white';
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(60, 10);
ctx.lineTo(40, 100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(60, 10);
ctx.lineTo(80, 100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "purple";
ctx.moveTo(80, 10);
ctx.bezierCurveTo(100, 145, 150, 100, 145, 10);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "cyan";
ctx.moveTo(160, 10);
ctx.lineTo(160, 95);
ctx.lineTo(200, 95);
ctx.stroke();
}
canvas { background: #F00; }
<canvas id="myCanvas"></canvas>
<canvas id="out"></canvas>
You dont need a extra canvas tag .
You will need to create new object .
Like this for example :
Change enableRotate to true to see rotate in same time .
var c = document.getElementById("myCanvas");
var out = document.getElementById("out");
var ctx = c.getContext("2d");
var outCtx = out.getContext("2d");
var counterClockwise = false;
var IAM_ANIMATION = {
globalLeft : 0 , // increment all x
globalTop : 0 , // increment all y
rotate : 0 , // rotate angle
speed : 0.1 ,
enableRotate : false ,
translate : function (){
// look at
// http://stackoverflow.com/questions/13849185/moving-an-object-along-a-straight-line-at-a-constant-speed-from-point-a-to-b
// http://jsfiddle.net/loktar/CajbL/
},
};
draw();
// just for example i will create interval
setInterval( function (){
IAM_ANIMATION.globalLeft = IAM_ANIMATION.globalLeft +
IAM_ANIMATION.speed;
if (IAM_ANIMATION.enableRotate == true) {
IAM_ANIMATION.rotate = IAM_ANIMATION.rotate + IAM_ANIMATION.speed;
}
draw()
} ,10);
outCtx.drawImage(c, 0, 0)
function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.save()
ctx.rotate( IAM_ANIMATION.rotate * Math.PI/180);
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "white";
ctx.moveTo( IAM_ANIMATION.globalLeft + 10, IAM_ANIMATION.globalTop + 10);
ctx.lineTo(IAM_ANIMATION.globalLeft + 10, IAM_ANIMATION.globalTop + 100);
ctx.stroke();
ctx.beginPath();
ctx.arc(IAM_ANIMATION.globalLeft +12,IAM_ANIMATION.globalTop + 38, 26, 4.7, Math.PI * .5, false);
ctx.lineWidth = "5";
ctx.strokeStyle = 'white';
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo( IAM_ANIMATION.globalLeft + 60,IAM_ANIMATION.globalTop + 10);
ctx.lineTo(IAM_ANIMATION.globalLeft + 40, IAM_ANIMATION.globalTop +100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo( IAM_ANIMATION.globalLeft + 60,IAM_ANIMATION.globalTop + 10);
ctx.lineTo( IAM_ANIMATION.globalLeft + 80, IAM_ANIMATION.globalTop +100);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "purple";
ctx.moveTo(IAM_ANIMATION.globalLeft +80,IAM_ANIMATION.globalTop + 10);
ctx.bezierCurveTo(IAM_ANIMATION.globalLeft +100, IAM_ANIMATION.globalTop + 145, IAM_ANIMATION.globalLeft +150, IAM_ANIMATION.globalTop +100,IAM_ANIMATION.globalLeft + 145, IAM_ANIMATION.globalTop +10);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "cyan";
ctx.moveTo( IAM_ANIMATION.globalLeft + 160,IAM_ANIMATION.globalTop + 10);
ctx.lineTo( IAM_ANIMATION.globalLeft + 160,IAM_ANIMATION.globalTop + 95);
ctx.lineTo( IAM_ANIMATION.globalLeft + 200,IAM_ANIMATION.globalTop + 95);
ctx.stroke();
ctx.restore();
}
<canvas id="myCanvas"></canvas>
<canvas id="out"></canvas>
<style>canvas { background: #F00; }</style>
Next level is to create class PAUL :
for example var NEW_PAUL = new PAUL("enter text");
I build whole system support for canvas object. My idea is one canvas for user visible view . See more about my canvas code :
https://bitbucket.org/nikola_l/visual-js
Rotate and translate
View it all at jsFiddle online examples
I am drawing a canvas and rotating it based on a value, it works if i use the canvas one time on a page.
If i add it the second time to the page, only the last one gets drawn, i cant find the error in my code and i dont get a js error.
i think the problem is in the next function:
function animate(){
function drawnumbers()
{context.save();
context.fillStyle = "#000000";
context.translate(73,0);
context.font="10px Orbitron";
context.textAlign = "center";
context.rotate(((i*(180/min)))*Math.PI/180);
context.fillText(data.values[i].amount,0,3);
context.restore();
};
if (d < defer){
context.clearRect(0,0,400,400);
d++;
context.save();
var ang = ((((d-minn)*(180/angle)))*(Math.PI/180));
context.translate(38,39);
context.scale(.8,.8);
base_image = new Image();
base_image.src = 'http://oi44.tinypic.com/2hfkx8p.jpg';
context.translate(base_image.width/2, base_image.height/2);
context.rotate(ang );
context.drawImage(base_image, -base_image.width/2, -base_image.height/2);
context.restore();
context.save();
context.beginPath();
context.arc(100,100,64,1*Math.PI,2*Math.PI, false);
context.lineWidth = .4;
context.strokeStyle="#00A1DE";
context.globalAlpha = 0.7;
context.stroke();
context.restore();
context.save();
context.translate(100,100);
context.rotate(Math.PI/180);
context.strokeStyle = "#00A1DE";
context.lineWidth = .7;
for (var i=0;i < data.values.length; i++){
context.beginPath();
context.moveTo(62,0);
context.lineTo(67,0);
context.stroke();
context.globalAlpha = 0.7;
drawnumbers();
context.rotate((182/(min))*(-Math.PI/180));
}
context.restore();
context.fillStyle="white";
context.fillRect(38,101,123,75);
context.save();
context.fillStyle = "#00a1de";
context.font = "22px Orbitron";
context.textAlign = "center";
context.fillText(defer, 100, 90);
context.restore();
context.save();
context.fillStyle = "#000000";
context.font = "10px arial";
context.textAlign = "center";
context.fillText(eenheid, 100, 115);
context.restore();
}
else
{
clearTimeout(t);
};
t=setTimeout("animate()",30-d);
};
check example to better understand:
http://jsbin.com/ogEgURu/1/
I had it in a function but it remains the same problem so i think something is wrong with my code.
Can anyone see the problem i am not seeing ?
Your code is way too complex, especially since there is no good reason for this complexity.
Copying a big (>200) lines block of code to duplicate a functionality is error-prone.
You'll be able to see easily the issue once you refactored your code.
Just a few hints :
Very easy one : beautify the code.
No redundancy : If a code lies here twice or more, make a function and factorize.
Break down the code into smaller parts. For example : drawText(context, text, x,y, font ) (to print eenheid and defer), drawNumbers(context), drawRotatingImage(context, angle), ...
use closePath() each time you beginPath();
load once the image when page loads, and wait for it to be loaded before animating.
do not define a function in a loop (drawnumbers).
use a single object to store the several parameters (context, angle, ...), or
even switch to an object oriented style.
have only one animate() loop, that will call several draw(...) functions if need be.
after all this, your code will look much simpler, and the bug should vanish very quickly.
I did this work (partially), in this fiddle :
http://jsfiddle.net/gamealchemist/ztczK/1/ (edited)
The code looks like :
// parameters : settings for one gauge display
var parameters1 = {
data: data,
defer: '520',
context: context,
left: 38,
top: 30,
d: 0,
angle: 0,
scale: 0.8,
//... whatever parameter here
};
var parameters2 = ... ;
split the draw into many functions so it's much simpler to understand :
// draws a gauge
function drawGauge(param) {
preDraw(param);
drawBaseImage(param);
drawArc(param);
drawTheNumbers(param);
writeDefer(param);
writeEenheid(param);
postDraw(param);
}
// translate and scales context, and updates some values for the gauge
function preDraw(param) {
var minn = param.data.values[param.data.values.length - 1].amount;
var maxn = data.values[0].amount;
var angle = maxn - minn;
var d = param.d;
param.ang = ((((d - minn) * (180 / angle))) * (Math.PI / 180));
var ctx = param.context;
ctx.save();
ctx.translate(param.left, param.top);
ctx.scale(param.scale, param.scale);
context.fillStyle = "white";
context.fillRect(0, 60, 123, 75);
}
// restore context
function postDraw(param) {
var ctx = param.context;
ctx.restore();
param.d++;
}
function drawBaseImage(param) {
var ctx = param.context;
var ang = param.ang;
ctx.save();
ctx.translate(base_image.width / 2, base_image.height / 2);
ctx.rotate(ang);
ctx.drawImage(base_image, -base_image.width / 2, -base_image.height / 2);
ctx.restore();
}
function drawArc(param) {
var ctx = param.context;
ctx.save();
ctx.beginPath();
ctx.arc(base_image.width / 2, base_image.height / 2, 64, 1 * Math.PI, 2 * Math.PI, false);
ctx.lineWidth = .4;
ctx.strokeStyle = "#00A1DE";
ctx.globalAlpha = 10.7;
ctx.stroke();
ctx.restore();
}
function writeDefer(param) {
var ctx = param.context;
var defer = param.defer;
ctx.save();
ctx.fillStyle = "#00a1de";
ctx.font = "22px Orbitron";
ctx.textAlign = "center";
ctx.fillText(defer, base_image.width / 2, base_image.height / 2);
ctx.restore();
}
function writeEenheid(param) {
var ctx = param.context;
ctx.save();
ctx.fillStyle = "#000000";
ctx.font = "10px arial";
ctx.textAlign = "center";
ctx.fillText(eenheid, base_image.width / 2, base_image.height / 2 + 20);
ctx.restore();
}
function drawTheNumbers(param) {
var ctx = param.context;
var dataValues = param.data.values;
var count = dataValues.length;
ctx.save();
ctx.translate(base_image.width / 2, base_image.height / 2);
ctx.rotate(Math.PI / 180);
ctx.strokeStyle = "#00A1DE";
ctx.lineWidth = .7;
ctx.fillStyle = "#000000";
ctx.font = "10px Orbitron";
ctx.textAlign = "center";
ctx.globalAlpha = 0.7;
for (var i = 0; i < count; i++) {
ctx.beginPath();
ctx.moveTo(62, 0);
ctx.lineTo(67, 0);
ctx.stroke();
ctx.closePath();
ctx.fillText(dataValues[i].amount, 60, 3);
ctx.rotate(-Math.PI / count);
}
context.restore();
}
then animate becomes very simple, even with several gauges :
function animate() {
context.clearRect(0, 0, canvasWidth, canvasHeight);
drawGauge(parameters1);
drawGauge(parameters2);
setTimeout(animate, 15);
};
base_image.onload = animate();
I'm trying to draw a house using Canvas and Javascript. If you look at my drawHouse() method, I want to color the roof red, and everything else white. But only the white is filling in to color everything.
Jsfiddle link
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Site's Title</title>
</head>
<body>
<canvas id="myDrawing" width="300" height="300" style="border:1px solid #EEE">
</canvas>
<script>
var canvas = document.getElementById("myDrawing");
var ctx = canvas.getContext("2d");
//draws a house
function drawImage() {
drawSky();
drawGrass();
drawHouse();
}
//sets the dimensions of the canvas
var x = canvas.width / 2;
var y = 400;
var radius = 200;
var startAngle = 0;
var endAngle = 22 * Math.PI;
//draws the sky
function drawSky() {
var context = canvas.getContext('2d');
context.beginPath();
context.rect(0, 0, 300, 300);
context.fillStyle = '#0099FF';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'black';
context.stroke();
}
//draws green grass
function drawGrass() {
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.stroke();
ctx.fillStyle = "#009900";
ctx.fill();
}
function drawHouse() {
var c = document.getElementById('myDrawing');
var ctx = c.getContext('2d');
ctx.beginPath();
ctx.moveTo(95, 165);
ctx.lineTo(140, 215);
ctx.lineTo(260, 215);
ctx.lineTo(240, 165);
ctx.lineTo(95, 165);
ctx.closePath();
ctx.fillStyle = "#C81E1E";
ctx.fill();
ctx.moveTo(139, 215);
ctx.lineTo(94, 165);
ctx.lineTo(45, 215)
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.moveTo(48, 212);
ctx.lineTo(48, 275);
ctx.lineTo(139, 275);
ctx.lineTo(139, 215);
ctx.lineTo(45, 215);
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.stroke();
ctx.moveTo(139, 275);
ctx.lineTo(260, 267);
ctx.lineTo(260, 215);
ctx.lineTo(140, 215);
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.stroke();
}
drawImage();
</script>
</body>
</html>
You are missing a call to ctx.beginPath in your drawHouse funciton. The fillStyle is per path, so will need to have multiple paths.
Here is the fiddle: http://jsfiddle.net/sVDSs/6/
var canvas = document.getElementById("myDrawing");
var ctx = canvas.getContext("2d");
//draws a house
function drawImage() {
drawSky();
drawGrass();
drawHouse();
}
//sets the dimensions of the canvas
var x = canvas.width / 2;
var y = 400;
var radius = 200;
var startAngle = 0;
var endAngle = 22 * Math.PI;
//draws the sky
function drawSky() {
var context = canvas.getContext('2d');
context.beginPath();
context.rect(0, 0, 300, 300);
context.fillStyle = '#0099FF';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'black';
context.stroke();
}
//draws green grass
function drawGrass() {
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.stroke();
ctx.fillStyle = "#009900";
ctx.fill();
}
function drawHouse() {
var c = document.getElementById('myDrawing');
var ctx = c.getContext('2d');
ctx.beginPath();
ctx.moveTo(95, 165);
ctx.lineTo(140, 215);
ctx.lineTo(260, 215);
ctx.lineTo(240, 165);
ctx.lineTo(95, 165);
ctx.fillStyle = "red";
ctx.closePath();
ctx.fill();
ctx.beginPath(); // THIS IS THE LINE
ctx.moveTo(139, 215);
ctx.lineTo(94, 165);
ctx.lineTo(45, 215)
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.moveTo(48, 212);
ctx.lineTo(48, 275);
ctx.lineTo(139, 275);
ctx.lineTo(139, 215);
ctx.lineTo(45, 215);
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.stroke();
ctx.moveTo(139, 275);
ctx.lineTo(260, 267);
ctx.lineTo(260, 215);
ctx.lineTo(140, 215);
ctx.closePath();
ctx.fillStyle = "white";
ctx.fill();
ctx.stroke();
}
drawImage();