How to get JavaScript object to properly display rectangle on screen? - javascript

I'm doing an eCard for class and I have decided to create an animation using classes for the specific objects. The first thing I am doing is trying to get the background to draw a black rectangle across the whole canvas using Background.DrawBackgound. But nothing is working.
I have tried even copy/pasting the drawing code at the bottom to get it to draw but it will not draw. I have done classes in C# before but am a bit rusty so I am thinking I have some error somewhere in how I've set up my classes.
Here's the .js:
//james gossling multimedia for web design spring 2018
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
//game classes go here
Background = function() {
};
Background.prototype = {
DrawBackground: function() {
context.strokeStyle = 'black';
context.fillStyle = 'black';
context.beginPath();
context.rect(0,0,canvas.width,canvas.height);
context.stroke;
context.fill;
context.closePath();
},
};
Confetti = function() {
};
Confetti.prototype = {
};
Firework = function() {
};
Firework.prototype = {
};
UncleSam = function() {
};
UncleSam.prototype = {
};
Text = function() {
};
Text.prototype = {
};
//other functions
var ClearScreen = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
};
var DrawObjects = function() {
//ClearScreen();
Background.DrawBackground();
};
var UpdatePositions = function(modifier) {
};
var Reset = function() {
};
//MAIN GAME LOOP FXN///////////////////
// The main game loop
var main = function() {
var now = Date.now();
var delta = now - then;
DrawObjects();
UpdatePositions(delta / 1000);
then = now;
//possibly do RESET
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
//START ECARD
var then = Date.now();
Background = new Background();
Reset();
main();
Background.DrawBackground();
and here's the .html:
<!DOCTYPE html>
<html>
<head>
<title>JamesG WebDesign</title>
<meta charset='UTF-8'>
<style>
body {
background-color: aqua;
}
h1 {
text-align: center;
}
h2 {
text-align: center;
}
p {
text-align: center;
}
#toMain {
margin-left: auto;
margin-right: auto;
text-align: center;
}
a {
font-size: 150%;
}
#canvas {
display: block;
margin: 0 auto;
background: #ffffff;
border: thin inset #aaaaaa;
}
#ResetAboveCanvas {
margin: 20px 0px 20px 450px;
}
</style>
</head>
<body>
<h2>James Gossling Multimedia for Web Design Spring 2018 </h2>
<p><strong>4th of July eCard</strong>
</p>
<canvas id='canvas' width='600' height='800'>
Canvas not supported
</canvas>
<script src='TestPC.js'></script>
<br>
<div id="toMain">
Back to Main
</div>
</body>
</html>

You are not invoking the functions fill and stroke.invoke the fill and stroke method should fix your problem
DrawBackground: function() {
console.log('here')
context.strokeStyle = 'black';
context.fillStyle = 'black';
context.beginPath();
context.rect(0,0,canvas.width,canvas.height);
context.stroke(); // invoke stroke
context.fill(); // invoke fill
context.closePath();
},

Related

Why some rectangles are disappearing when there is a rectangle that covers the whole area?

I'm facing a problem with css paint worklet and am wondering whether it's a browser bug or there's something that i'm doing wrong.
In a worklet i'm drawing a few rectangles. If one of them covers the whole area, others are starting to disappear when i'm changing zoom level. But when i remove the context.fillRect(0, 0, width, height) everything works like a charm.
Here's sandbox code that i've prepared to better illustrate the problem: https://codesandbox.io/s/magical-villani-py8x2
That indeed looks like a bug in Chrome "experimental" implementation, you might want to let them know on their issue tracker, since that should work.
Now, while you are not doing anything bad per se, note that if instead of the non-standard zoom we do use the transform property, then the bug would not occur:
(()=> {
if( !CSS.paintWorklet ) {
return console.error('CSS Paint API is not supported in this browser, you may have to enable it from chrome://flags/#enable-experimental-web-platform-features');
}
const worklet_script = document.querySelector('[type="paint-worklet"]').textContent;
const worklet_blob = new Blob([worklet_script], { type: 'text/javascript' });
CSS.paintWorklet.addModule(URL.createObjectURL(worklet_blob));
window.addEventListener("DOMContentLoaded", () => {
const slider = document.getElementById("slider");
slider.addEventListener("input", () => {
const el = document.querySelector(".content");
el.style.transform = `scale(${slider.value},${slider.value})`;
});
});
})();
.content {
background: paint(sandbox);
border: 1px solid black;
height: 200px;
width: 200px;
transform-origin: top left;
}
<input type="range" id="slider" min="0.5" max="4" value="1" step="0.1" />
<div class="content"></div>
<script type="paint-worklet">
class SandboxPaintWorklet {
paint(context, geometry, properties) {
const { width, height } = geometry;
// background
context.fillStyle = "#8866aa";
context.fillRect(0, 0, width, height);
context.fillStyle = "#000000";
context.beginPath();
// vertical line
context.fillRect((width * 3) / 4, 0, 1, height);
// horizontal lines
const distance = Math.ceil(height / 20);
for (let i = 0; i < 20; ++i) {
context.fillRect(0, i * distance, width / 2, 1);
}
}
}
registerPaint("sandbox", SandboxPaintWorklet);
</script>
And even with zoom, if instead of that many fillRect, if we do fill a single sub-path by using rect() instead, then that would also work.
(()=> {
if( !CSS.paintWorklet ) {
return console.error('CSS Paint API is not supported in this browser, you may have to enable it from chrome://flags/#enable-experimental-web-platform-features');
}
const worklet_script = document.querySelector('[type="paint-worklet"]').textContent;
const worklet_blob = new Blob([worklet_script], { type: 'text/javascript' });
CSS.paintWorklet.addModule(URL.createObjectURL(worklet_blob));
window.addEventListener("DOMContentLoaded", () => {
const slider = document.getElementById("slider");
slider.addEventListener("input", () => {
const el = document.querySelector(".content");
el.style.zoom = slider.value;
});
});
})();
.content {
background: paint(sandbox);
border: 1px solid black;
height: 200px;
width: 200px;
}
<input type="range" id="slider" min="0.5" max="4" value="1" step="0.1" />
<div class="content"></div>
<script type="paint-worklet">
class SandboxPaintWorklet {
paint(context, geometry, properties) {
const { width, height } = geometry;
// background
context.fillStyle = "#8866aa";
context.fillRect(0, 0, width, height);
context.fillStyle = "#000000";
context.beginPath();
// vertical line
context.rect((width * 3) / 4, 0, 1, height);
// horizontal lines
const distance = Math.ceil(height / 20);
for (let i = 0; i < 20; ++i) {
context.rect(0, i * distance, width / 2, 1);
}
context.fill();
}
}
registerPaint("sandbox", SandboxPaintWorklet);
</script>

Canvas only being displayed on the first image of the slider or connected to the bottom of each image

So I tried to make it so that whenever an image is clicked it will draw a circle on a canvas. The image and the canvas are suppose to overlay. However, I have a problem when I have
cnvs.style.position = 'absolute'; active all of my canvas' are stacked on each other on the first image. So if I were to click other images the circle would be drawn on the first image but not on the image clicked. However, if I comment out cnvs.style.position = 'absolute'; the canvas is being connected to the bottom of the image instead of being overlaid. I need to make it so that each canvas and image are overlaid so that when one image is clicked a circle will appear. I'm thinking I have a css problem, but I'm not sure how to fix it.
document.body.onload = addElement;
function addElement() {
// image path
const imagePath = ['https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fen%2F8%2F84%2FAssociation_of_Gay_and_Lesbian_Psychiatrists_logo.jpg&f=1&nofb=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fstatic01.nyt.com%2Fnewsgraphics%2F2016%2F07%2F14%2Fpluto-one-year%2Fassets%2Ficon-pluto.png&f=1&nofb=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse4.mm.bing.net%2Fth%3Fid%3DOIP.oFxADNN67dYP-ke5xg7HbQHaHG%26pid%3DApi&f=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia.glassdoor.com%2Fsqll%2F1065746%2Felevation-church-squarelogo-1453223965790.png&f=1&nofb=1'];
for (const image of imagePath) {
// get the item id of an image
var slice = image.slice(26, 34);
var id = image;
var hdnName = document.getElementById("sendServ");
const img = document.createElement("img");
img.src = image;
img.classList.add("new");
img.id = slice;
const cnvs = document.createElement("canvas");
cnvs.classList.add("suiteiCanvas");
// cnvs.style.position = 'absolute';
cnvs.style.left = img.offsetLeft + "px";
cnvs.style.top = img.offsetTop + "px";
cnvs.style.display = 'none';
var ctx = cnvs.getContext("2d");
ctx.clearRect(0, 0, cnvs.width, cnvs.height);
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2 * Math.PI, false);
ctx.lineWidth = 15;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
var div = document.createElement("div");
var div1 = document.createElement("div");
div.id = id;
div1.id = '1';
div.classList.add("image");
img.onclick = function draw() {
cnvs.style.display = '';
hdnName.value = img.id;
};
cnvs.onclick = function remove() {
cnvs.style.display = 'none';
hdnName.value = null;
};
document.getElementById('suitei-slider').appendChild(div);
document.getElementById(image).appendChild(img);
document.getElementById(image).appendChild(cnvs);
}
}
// slick slider
canvas.suiteiCanvas{
height: auto;
width: auto;
max-height: 200px;
max-width: 150px;
margin-left: 100px;
margin-right: 100px;
border:3px solid rgb(20, 11, 11);
}
#draw-btn {
font-size: 14px;
padding: 2px 16px 3px 16px;
margin-bottom: 8px;
}
img.new {
height: auto;
width: auto;
max-height: 200px;
max-width: 150px;
margin-left: 100px;
margin-right: 100px;
border:3px solid rgb(20, 11, 11);
}
<div class="multiple-items" id="suitei-slider"></div>
<input type="hidden" id="sendServ">
You need to set your canvases in position: absolute inside a container in position: relative so that your canvases are still contained in the container. Since the containers are not in position: absolute, they don't overlay, but their content will, so your canvases will overlay with the images.
Then, you have to center you canvases (I suspect), so I set the canvases dimensions (for now it's hard coded) and fixed the x position of the circle.
I hope it is what you were looking for.
document.body.onload = addElement;
function addElement() {
// image path
const imagePath = ['https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fen%2F8%2F84%2FAssociation_of_Gay_and_Lesbian_Psychiatrists_logo.jpg&f=1&nofb=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fstatic01.nyt.com%2Fnewsgraphics%2F2016%2F07%2F14%2Fpluto-one-year%2Fassets%2Ficon-pluto.png&f=1&nofb=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse4.mm.bing.net%2Fth%3Fid%3DOIP.oFxADNN67dYP-ke5xg7HbQHaHG%26pid%3DApi&f=1', 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia.glassdoor.com%2Fsqll%2F1065746%2Felevation-church-squarelogo-1453223965790.png&f=1&nofb=1'];
for (const image of imagePath) {
// get the item id of an image
var slice = image.slice(26, 34);
var id = image;
var hdnName = document.getElementById("sendServ");
const img = document.createElement("img");
img.src = image;
img.classList.add("new");
img.id = slice;
const cnvs = document.createElement("canvas");
cnvs.classList.add("suiteiCanvas");
// cnvs.style.position = 'absolute';
cnvs.style.left = img.offsetLeft + "px";
cnvs.style.top = img.offsetTop + "px";
cnvs.style.display = 'none';
cnvs.width = 150;
cnvs.height = 150;
var ctx = cnvs.getContext("2d");
ctx.clearRect(0, 0, cnvs.width, cnvs.height);
ctx.beginPath();
ctx.arc(75, 75, 50, 0, 2 * Math.PI, false);
ctx.lineWidth = 15;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
var div = document.createElement("div");
var div1 = document.createElement("div");
div.id = id;
div1.id = '1';
div.classList.add("image");
img.onclick = function draw() {
cnvs.style.display = '';
hdnName.value = img.id;
};
cnvs.onclick = function remove() {
cnvs.style.display = 'none';
hdnName.value = null;
};
document.getElementById('suitei-slider').appendChild(div);
document.getElementById(image).appendChild(img);
document.getElementById(image).appendChild(cnvs);
}
}
// slick slider
.image {
position: relative; /* add this */
user-select: none; /* and this maybe */
}
canvas.suiteiCanvas{
height: auto;
width: auto;
height: 150px;
max-width: 150px;
/*margin-left: 100px;
margin-right: 100px;*/
border:3px solid rgb(20, 11, 11);
position: absolute; /* add this */
}
#draw-btn {
font-size: 14px;
padding: 2px 16px 3px 16px;
margin-bottom: 8px;
}
img.new {
height: auto;
width: auto;
max-height: 200px;
max-width: 150px;
/*margin-left: 100px;
margin-right: 100px;*/
border:3px solid rgb(20, 11, 11);
}
<div class="multiple-items" id="suitei-slider"></div>
<input type="hidden" id="sendServ">
Just in case you wonder what each line means here it is a more clean code and with comments on many lines... for my understanding you code is a little confuse. You should use more times functions to be more readable, etc.
let index = 0;
const display = "table"; // or "grid" if horizontal, but this migh depend where you place the rest of the code, cause i added the style to the body
const x = 0;
const y = 0;
const images = {
height: 50,
width: 50,
url: [
'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fen%2F8%2F84%2FAssociation_of_Gay_and_Lesbian_Psychiatrists_logo.jpg&f=1&nofb=1',
'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fstatic01.nyt.com%2Fnewsgraphics%2F2016%2F07%2F14%2Fpluto-one-year%2Fassets%2Ficon-pluto.png&f=1&nofb=1',
'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse4.mm.bing.net%2Fth%3Fid%3DOIP.oFxADNN67dYP-ke5xg7HbQHaHG%26pid%3DApi&f=1',
'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia.glassdoor.com%2Fsqll%2F1065746%2Felevation-church-squarelogo-1453223965790.png&f=1&nofb=1'
]
}
function createHTML() {
console.log('E: Execute & R: Request & I: Informative');
//loop to go true all images
document.body.style.display = display;
for (const image of images.url) {
//each image will correspond to a canvas element
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
//each canvas element will has is own properties (in this case all the same)
canvas.id = 'option' + [index];
canvas.height = images.height;
canvas.width = images.width;
canvas.style.padding = '10px';
//function to get the corresponded image of that particular canvas element
drawImages(canvas);
//add an event listener for when a user click on the particular canvas
canvas.addEventListener("click", optionClick, false);
//all html part was handle we can append it to the body
document.body.appendChild(canvas);
index++;
}
}
function drawImages(canvas) {
//we need to use the getContext canvas function to draw anything inside the canvas element
const ctx = canvas.getContext('2d');
const background = new Image();
//This is needed because if the drawImage is called from a different place that the createHTML function
//index value will not be at 0 and it will for sure with an heigher id that the one expected
//so we are using regex to remove all letters from the canvas.id and get the number to use it later
index = canvas.id.replace(/\D/g, '');
//console.log('E: Drawing image ' + index + ' on canvas ' + canvas.id);
//get the image url using the index to get the corresponded image
background.src = images.url[index];
//no idea why but to place the image, we need to use the onload event
//https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
background.onload = function() {
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
}
}
function drawX(canvas) {
const ctx = canvas.getContext('2d');
console.log('E: Placing X on canvas ' + canvas.id);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(images.width, images.height);
ctx.moveTo(images.height, 0);
ctx.lineTo(0, images.width);
ctx.closePath();
ctx.stroke();
}
function clear(canvas) {
console.log('E: clearing canvas ' + canvas.id);
canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
drawImages(canvas);
}
function optionClick(e) {
log = true;
const canvas = document.getElementsByTagName('canvas');
for (const option of canvas) {
if (log) console.log('I: User clicked at option ' + e.target.id + ':' + option.id);
log = false;
if (e.target.id === option.id) {
console.log('R: Drawing request at canvas ' + option.id);
drawX(option);
} else {
console.log('R: Clearing request at canvas ' + option.id);
clear(option);
}
}
}
//We start by calling createHTML (that will handle with all HTML elements)
window.onload = createHTML;
canvas.suiteiCanvas {
height: auto;
width: auto;
max-height: 200px;
max-width: 150px;
margin-left: 100px;
margin-right: 100px;
border: 3px solid rgb(20, 11, 11);
}
#draw-btn {
font-size: 14px;
padding: 2px 16px 3px 16px;
margin-bottom: 8px;
}
img.new {
height: auto;
width: auto;
max-height: 200px;
max-width: 150px;
margin-left: 100px;
margin-right: 100px;
border: 3px solid rgb(20, 11, 11);
}
<body></body>

Why can't JavaScript read more than 3 keys at times?

I have an array of keys that stores which keys are being pressed. Whenever I press the left arrow, spacebar, and the up arrow together, the array will only keep two of the keycodes, leaving one not to be pushed into the array. When these three keys are pressed, the character is supposed to move left, jump up, and shoot a bullet. One of those three actions won't occur. I am using Google Chrome, and I don't know what will happen on other browsers.
var $c = $('canvas');
var ctx = $c[0].getContext('2d');
var x = 20;
var y = 150;
var keys = [];
var bulletX = x + 2;
var bulletY = 0;
var bullets = [];
var face = 1;
function plr() {
ctx.fillStyle = 'black';
ctx.fillRect(x, y, 20, 20);
}
$c.keydown(function(e) {
if (_.includes(keys, e.which) === false) {
keys.push(e.which);
}
});
$c.keyup(function(e) {
_.pull(keys, e.which);
});
function shoot() {
bullets.forEach(function(bullet) {
ctx.fillStyle = 'red';
ctx.fillRect(bullet.bX, bullet.bY, 8, 4);
if (bullet.direction === 0) {
bullet.bX -= 7;
}
if (bullet.direction === 1) {
bullet.bX += 7;
}
if (bullet.bX > 700 || bullet.bX < 0) {
_.pull(bullets, bullet);
}
});
}
setInterval(function() {
ctx.clearRect(0, 0, 700, 500);
if (keys.includes(32)) {
bullets.push({
direction: face,
bX: x + face * 12,
bY: y + 8
});
}
if (keys.includes(37)) {
face = 0;
x -= 3;
}
if (keys.includes(38)) {
y-=3;
}
if (keys.includes(39)) {
face = 1;
x += 3;
}
plr();
shoot();
}, 30);
.canvas {
background-color: #a3c2ba;
outline: none;
border: #fff;
margin: auto;
display: block;
position: relative;
top: 50px;
border-radius: 0px;
}
body {
margin: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
<script src='https://code.jquery.com/jquery-3.4.1.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/lodash#4.17.11/lodash.min.js'></script>
</head>
<body>
<canvas class='canvas' width='300' height='200' tabindex='1' />
</body>
</html>
I have concluded that this is a problem with my keyboard. I tried this on my brother's computer and it worked fine. Thanks to everyone who attempted to help though!

Fabric.js multiple clipping based on svg

I have canvas with svg path on it. I want to do something like this:
http://jsfiddle.net/tbqrn/
var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.rect(10,10,150,150);
ctx.rect(180,10,200,200);
ctx.closePath();
ctx.stroke();
ctx.clip();
fabric.Image.fromURL(img01URL, function(oImg) {
oImg.scale(.25);
oImg.left = 50;
oImg.top = 100;
canvas.add(oImg);
canvas.renderAll();
});
fabric.Image.fromURL(img02URL, function(oImg) {
oImg.scale(.25);
oImg.left = 300;
oImg.top = 100;
canvas.add(oImg);
canvas.renderAll();
});
but with one difference: the image after leaving one area should immediately appear in another one.
How can I do it?
This is not doable with a single canvas. The only way I can think of that works is this:
Have two canvases with two different images and "synchronize" the position of the image between them. You actually have to use two images.
HTML:
<canvas id="c1" width="200" height="400"></canvas>
<canvas id="c2" width="200" height="400"></canvas>
CSS:
#c1, #c2 {
border: 1px solid #ccc;
}
#c2 {
margin-left: 20px;
}
.canvas-container {
float: left;
}
JS:
var offsetLeft = 220; // #c1 width + #c2 margin-left
var canvas1 = new fabric.Canvas('c1');
var canvas2 = new fabric.Canvas('c2');
var c1Img, c2Img;
fabric.Image.fromURL(img01URL, function(oImg) {
c1Img = oImg;
c1Img.scale(.25);
c1Img.left = 0;
c1Img.top = 0;
c1Img.hasControls = false;
c1Img.hasRotatingPoint = false;
canvas1.add(c1Img);
canvas1.renderAll();
});
fabric.Image.fromURL(img01URL, function(oImg) {
c2Img = oImg;
c2Img.scale(.25);
c2Img.left = -offsetLeft;
c2Img.top = 0;
c2Img.hasControls = false;
c2Img.hasRotatingPoint = false;
canvas2.add(c2Img);
canvas2.renderAll();
});
canvas1.on('object:moving', function(e) {
c2Img.set({left: e.target.left -offsetLeft, top: e.target.top});
c2Img.setCoords();
canvas2.renderAll();
});
canvas2.on('object:moving', function(e) {
c1Img.set({left: e.target.left + offsetLeft, top: e.target.top});
c1Img.setCoords();
canvas1.renderAll();
});
Test it here: http://jsfiddle.net/se9sw1d8/2/

Iteratively change the fillStyle color in canvas while drawing a fractal

I'm using the following code to generate a Pythagoras fractal tree using HTML5 canvas element:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="jquery.js" type="text/javascript"></script>
<style>
#sketch
{
border: 1px solid black;
}
</style>
<script type="text/javascript">
window.onload = function()
{
var canvas = document.getElementById("sketch");
var context = canvas.getContext("2d");
context.fillStyle = "rgba(0, 0, 200, 0.5)";
context.beginPath();
context.moveTo(450,550);
context.lineTo(450,450);
context.lineTo(550,450);
context.lineTo(550,550);
context.fill();
fractal(context,[450,550],[450,450],[550,450],[550,550],5);
};
function fractal(context,P1,P2,P3,P4,depth)
{
context.fillStyle = "rgba(0,0,200,"+(depth/8).toString()+")";
context.save();
if(depth < 0)
{
return null;
}
/*Find C*/
C = divide(add(divide(add(P1,P2),2),divide(add(P3,P4),2)),2);
var V1 = divide(minus(C,P1),length(C,P1));
var V2 = divide(minus(C,P4),length(C,P4));
var P6 = add(P2,multiply(V2,length(P1,P2)/Math.sqrt(2)));
var P7 = add(P6,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P5 = add(P2,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P9 = add(P3,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P8 = add(P9,multiply(V2,length(P1,P2)/Math.sqrt(2)));
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
fractal(context,P2,P6,P7,P5,depth-1);
fractal(context,P5,P8,P9,P3,depth-1);
}
function multiply(v, num){
return [v[0]*num, v[1]*num];
}
function divide(v, num){
return [v[0]/num, v[1]/num];
}
function add(a, b){
return [a[0]+b[0], a[1]+b[1]];
}
function minus(a, b){
return [a[0]-b[0], a[1]-b[1]];
}
function length(a, b){
return Math.sqrt(Math.pow(a[0] - b[0],2) +
Math.pow(a[1] - b[1],2));
}
</script>
<title>Square</title>
</head>
<body>
<canvas id="sketch" height="1000" width="1000"></canvas>
</body>
</html>
I'm changing the opacity value with every iteration. But I don't see it in the result.
How can this be fixed??
You were really close to the right solution. Look here:
http://jsfiddle.net/mbessey/Wj4VH/
The key difference here is calling beginPath() before starting the moveTo() and lineTo() for each square. So, instead of:
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
You want:
context.beginPath()
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.beginPath()
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
What you were doing was essentially creating one large path with all the squares in it and then filling it all with the same color.
Check This I have changed the opacity of the canvas itself ,making it simple and easy to achieve the target.
Adding rgba(0, 0, 200, 1) and
#sketch
{
border: 1px solid black;
opacity: 0.3;
}
will suffice what you want

Categories

Resources