Fill area with fixed size elements - javascript

I'm creating an application to calculate how much solar panels would fit on a specific roof.
Users can input the dimensions of their roof.
We only have on size of solar panels available.
I thought a canvas was the way to go but I don't seem to find the information I need..
Requirements
1) Based on the input of the user the canvas should be resized (currently I have a rectangle inside the canvas changing to this size)
2) User should be able to create (and size) objects to put on the roof (chimney, window,..)
3) Based on the open space left solar panels (rectangles) should be automaticly drawn on the canvas
Dimensions and limitations
1px = 2cm
Spacing to edge of roof and object is 7px (14cm)
Solar panel is 169 cm height and 102 cm width
I've checked out the fabric.js library but can't seem to find something close to what I need.
The js I got so far to draw the canvas:
var canvas=document.getElementById("c");
var ctx=canvas.getContext("2d");
var width=50;
var height=35;
var $width=document.getElementById('width');
var $height=document.getElementById('height');
var paneelWidth=101;
var peneelHeight=170;
$width.value=width;
$height.value=height;
draw();
$width.addEventListener("keyup", function(){
width=this.value/2;
draw();
}, false);
$height.addEventListener("keyup", function(){
height=this.value/2;
draw();
}, false);
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(10,10,width,height)
}
Update
The canvas now does resize in a dynamic way based on user input.
I also found the function createPattern(), which is bringing me closer to the solution.
I've added this code to generate a pattern of solar panels in the canvas:
function placepanels(direction) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var img = document.getElementById("paneel");
var pat = ctx.createPattern(img, direction);
var w2 = canvas.width - 7;
var h2 = canvas.height - 7;
ctx.rect(7, 7, w2, h2);
ctx.fillStyle = pat;
ctx.fill();
}
The -7 on width and height is beacause I need 14cm space on each size of the canvas. Hence why I offset the rectangle containing the pattern 7px from left and top. Currently not able to achieve this on right and bottom side.
Current issue
The result I'm getting is not looking correct, it seems like the pattern repeats wrong (to much repeats) or it's not getting the proper size of the image to repeat.
Updated fiddle: https://jsfiddle.net/8e05ghqy/3/

As for the canvas resize, this function would do it:
changeCanvasSize = function( width, height ) {
$('canvas').width(width)
$('canvas').height(height)
}
Example of usage: changeCanvasSize(450,250) would change the canvas size to 450px of width and 250px of height.
I am just resizing the HTML <canvas> element .width( value ) and .height( value ) works for any HTML element.

Related

javascript loaded image is blurry (PNG)

I'm having a problem drawing sprites on canvas for a school project. My code:
treeImage = new Image();
treeImage.src = "sprites/treeSprites.png";
function rocks() { //to create the rock
this.x = 1920 * Math.random(); //random location on the width of the field
this.y = ground[Math.round(this.x/3)]; //ground is an array that stores the height of the ground
this.draw = function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(Math.tan((ground[Math.floor(this.x/3)]-ground[Math.floor(this.x/3)+1])/-3));
//^rotating based on its position on the ground^
ctx.drawImage(treeImage, 200, 50, 50, 50, -25, -50, 50, 50);
ctx.restore();
}
}
len = rockArray.length; //every frame
for (var i = 0;i<len;i++) {
rockArray[i].draw();
}
I only request 50×50px from the image. Exactly outside of the 50×50 there are black lines (which shouldn't interfere because I only request the square within the black lines) but when I draw the rock, the black outlines are visible. (For other reasons, I can't remove the black lines.)
I'm guessing the image JavaScript stores when I load the image is made blurry, and then when I request that part from the image, the lines around are visible too, as the blur "spreads" the lines into the square I request.
Is there a way I can prevent this?
Use ctx.imageSmoothingEnabled = false.
This will make the image sharp instead of smoothed (blurry).
(documentation)
If you draw a vertical line at x=5 and width = 1, the canvas actually draws the line from 4.5 to 5.5 this results in aliasing and a fuzzy line. A quick way to remedy that so it is a solid line is to offset the entire canvas by half a pixel before doing anthing else.
ctx.translate(-0.5, -0.5);
(documentation)

How would you make a wave animated div css/js

One way I can think of is with an animated svg, but there is probably a better way. What would you do if you had to animate these wavy blobs (mobile compatible)
Link to the only pin I've found similar
var wave = document.createElement("div");
wave.className += " wave";
docFrag.appendChild(wave);
wave.style.left = i * waveWidth + "px";
wave.style.webkitAnimationDelay = (i / 100) + "s";
Touch interaction would be nice too. Would there be any problems with canvas stuff ?
Here's an implementation of #DA.'s good answer:
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
var cw=canvas.width;
var ch=canvas.height;
ctx.textAlign='center';
ctx.textBaseline='middle';
ctx.font='16px verdana';
ctx.lineWidth=5;
ctx.strokeStyle='white';
ctx.fillStyle='white';
var offsetX=0;
var bk=makeWave(canvas.width,canvas.height-120,10,2,'lightskyblue','cornflowerblue');
requestAnimationFrame(animate);
function animate(time){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(bk,offsetX,0);
ctx.fillStyle='white';
ctx.font='18px verdana';
ctx.fillText('Multiple Lists',cw/2,30);
ctx.strokeRect(cw/2-50,85,100,50);
ctx.fillStyle='gray';
ctx.font='12px verdana';
ctx.fillText('You can create and save multiple ...',cw/2,250);
offsetX-=1;
if(offsetX< -bk.width/2){offsetX=0;}
requestAnimationFrame(animate);
}
function makeWave(width,midWaveY,amplitude,wavesPerWidth,grad0,grad1){
var PI2=Math.PI*2;
var totValue=PI2*wavesPerWidth;
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
c.width=width*2;
c.height=midWaveY+amplitude;
var grad=ctx.createLinearGradient(0,0,0,midWaveY);
grad.addColorStop(0.00,grad0);
grad.addColorStop(1.00,grad1);
//
ctx.beginPath();
ctx.moveTo(0,0);
for (x=0;x<=200;x++) {
var n=totValue*x/100;
ctx.lineTo(width*x/100,Math.sin(n)*amplitude+midWaveY);
}
ctx.lineTo(c.width,0);
ctx.closePath();
ctx.fillStyle=grad;
ctx.fill();
return(c);
}
body{ background-color:white; }
canvas{border:1px solid red; margin:0 auto; }
<canvas id=canvas width=300 height=300></canvas>
I'd make the wave a PNG (bottom solid gray, top transparent). Place it in a div twice the width of the card, and place that in a div the width of the card (this second div is the 'mask').
Then via CSS, have the nested give transform on the x axis to animate it sideways.
You shouldn't need any JS for this.
I would do this:
on page load create an off-screen canvas (just set display: none)
in a for loop compute the wave:
clear with transparency
paint only the white part because the colored part has a gradient
after each paint, get the PNG data out of the canvas and store it in an array
after the loop you will have an array of PNG images (frames)
cycle through those frames without recomputing the wave over and over again
This requires the wave to have a period that is affine to the number of frames you take (say a 2 second animation at 10 Hz would require 20 frames to be cyclic)
To be honest, you could store that server-side and just download it, without computing it client-side. Those PNG images would be very tiny because there isn't any color involved (just transparent/white/alpha channel). There are optimal settings for this, I guesstimate some 1KB per frame would suffice, that's a tiny 20 KB of images).

Custom cursors for canvas caricatures?

I'm making a whiteboard app just for fun and have tools like the brush tool, eraser, etc and I draw on an HTML5 canvas.
I'm trying to implement custom cursors for my tools (like brush, line, square) and was just going to use the CSS cursor property depending on which tool is selected but I'd like sizes to vary depending on the current line width.
For example, in MS Paint you'll notice with the brush and eraser tool, depending on the size of the line width, the cursor is differently sized when drawing on the canvas.
So I have two questions. The first is if I can use CSS still and somehow alternate the cursor size dynamically from JS.
The second is how you would implement this solution by just deleting the cursor and drawing your own on the canvas that follows the mouse movement. I'm a bit concerned that the latter would be quite glitchy and more complex so am hoping that the first one is possible.
Maintaining the position of your own cursor does not work very well on the browsers. By the time you have handled the mouse move, waited for the next animation frame you are one frame behind. (drawing immediately to canvas in the mouse event does help) The is very off putting, even if you set the cursor to "none" so the two do not overlap, the 1/60th of a second can make a big difference from where you see your rendered cursor to and where the hardware cursor (for want of a better name) is.
But it turns out that the browsers Chrome and Firefox allow you to have full control of the hardware cursor image. I have personally exploited it to the limits and it is a robust and tolerant system.
I started with pre made cursors as DataURLs. But now most of my cursors are dynamic. If a control uses the mouse wheel, I add the wheel indicator on the cursor, when using resize cursor, instead of 8 directions N, NE, E, SE, S, SW, W, NW It is created on demand to line up with whatever I happen to be resizing at what ever angle it is. When drawing the cursor is continuously reorienting to avoid covering pixels I may be working on.
To set a custom cursor, set the elements style.cursor to an image URL, followed by two numbers that are the hotspot (Where the click is focused), and a cursor name. I just use the same name "pointer" and generate the image URL on the fly with toDataURL.
Below is a quick example of changing the cursor dynamically. I am unsure what the limits are in terms of size, but so far I haven't wanted a cursor that it has not given me. Some of them, in games have been very big (lol as cursors go) (128*128 pixels +)
Note a slight bug in code. Will return to fix the first rendered word being clipped soon.
The only issue with this is IE does not support this what of doing cursors, so you will need a fallback
// create an image to use to create cursors
var image = document.createElement("canvas");
image.width = 200;
image.height = 14;
image.ctx = image.getContext("2d");
// some graphic cursors
var cursors = [
"url('data:image/png;base64,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') 0 0, cursor",
"url('data:image/png;base64,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') 0 0, cursor ",
"url('data:image/png;base64,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') 0 0, cursor "
];
// Do the stuff that does the stuff
var el = document.getElementById("customeCurs");
var over = false;
// set up canvas rendering
var c = image.ctx;
// some stuff to say and ABC are graphic flags
var stuff = "A C Hello pointy clicky things are great and easy to use A B C B".split(" ");
var tHandle;
var wordPos=0;
function createCursor(){ // creates cursors from the canvas
// get a word from the word list
var w = stuff[wordPos % stuff.length];
if(w === "A" || w === "B" || w === "C"){ // display graphics cursor
// just for fun. to much time on
// my hands. I really need a job.
var datURL;
switch(w){
case "A":
datURL = cursors[0];
break;
case "B":
datURL = cursors[1];
break;
case "C":
datURL = cursors[2];
}
el.style.cursor = datURL;
}else{ // create a dynamic cursor from canvas image
// get the size. Must do this
var size = c.measureText(w).width + 4;
// resize the canvas
image.width = size;
image.height = 36;
c.font = "28px arial black";
c.textAlign ="center";
c.textBaseline = "middle";
c.lineCap = "round";
c.lineJoin = "round";
// Please always give user a visual guide to the hotspot.
// following draws a little arrow to the hotspot.
// Always outline as single colours can get lost to the background
c.lineWidth = 3;
c.strokeStyle = "white";
c.moveTo(1,5);
c.lineTo(1,1);
c.lineTo(5,1);
c.moveTo(1,1);
c.lineTo(8,8);
c.stroke();
c.strokeStyle = "black";
c.lineWidth = 1;
c.moveTo(1,5);
c.lineTo(1,1);
c.lineTo(5,1);
c.moveTo(1,1);
c.lineTo(8,8);
c.stroke();
c.lineWidth = 5;
c.strokeStyle = "black";
c.fillStyle = "White";
// Draw the text outline
c.strokeText(w, image.width / 2, image.height / 2+2);
// and inside
c.fillText(w, image.width / 2, image.height / 2);
// create a cursor and add it to the element CSS curso property
el.style.cursor = "url('"+image.toDataURL("image/png")+"') 0 0 , pointer"; // last two
// numbers are the
// cursor hot spot.
}
// Next word
wordPos += 1;
// if the mouse still over then do it again in 700 ticks of the tocker.
if(over){
tHandle = setTimeout(createCursor,700);
}
}
// mouse over event to start cursor rendering
el.addEventListener("mouseover",function(){
over = true;
if(tHandle === undefined){
createCursor();
}
});
el.addEventListener("mouseout",function(){
over = false; // clean up if the mouse moves out. But leave the cursor
clearTimeout(tHandle);
tHandle = undefined;
});
<div id="customeCurs" >Move Mouse Over ME.</div>
<!-- Some say don't put style in HTML doc! The standards are indifferent. The author is lazy :P -->
<span style="font-size:small;color:#BBB;">Sorry IE again you miss out.</span>

Responsive Canvas in Bootstrap

I'm trying to do a responsive canvas. All my tests has been doing with a 600x600 canvas and with that height and width it works OK and paint every line correctly. The problem is that I have tried this:
#myCanvas {
background-color: #ffffff;
border:1px solid #000000;
min-height: 600px;
height: 100%;
width: 100%;
}
Just for the record, myCanvas is inside a sm-col-8.
And it looks nice on my laptop and looks nice on my phone but (because of my draw() function, because it was thinking for a square) the draw starts more like in the down-left corner (nearby) and it should start at up-right corner.
So, I don't want to change my draw() function but what I'm looking for is to reescale the canvas size. I mean: If I'm in a laptop/tablet.. with 600x600, show it at that size, but if I'm on my phone which has 384x640 show it like 300x300? I don't know if it could be a good solution.
My draw function:
function drawLines(lines,i,table,xtotal,ytotal){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var xIni;
var xFin;
var yIni;
var yFin;
xIni = (c.width*parseInt(lines[i][1])/xtotal);
yIni = (c.height*parseInt(lines[i][2])/ytotal);
xFin = (c.width*parseInt(lines[i][3])/xtotal);
yFin = (c.height*parseInt(lines[i][4])/ytotal);
ctx.beginPath();
ctx.moveTo(xIni,c.height-yIni);
ctx.lineTo(xFin,c.height-yFin);
ctx.lineWidth=4;
ctx.strokeStyle = colorAleatorio();
ctx.stroke();
}
With Bootstrap, use:
<canvas id="canvas" class='img-responsive' style="border: 1px solid black;"></canvas>
You can make your html Canvas responsive by using the context.scale command.
The .scale command will scale the internal coordinates system used by canvas.
This means you do not need to change any of your own drawing coordinates because canvas will automatically transform your coordinates into scaled canvas coordinates for you.
// save the original width,height used in drawLines()
var origWidth=600;
var origHeight=600;
var scale=1.00;
// reference to canvas and context
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// call this after resizing
// send in the new maximum width,height desired
function resizeAndRedraw(newMaxWidth,newMaxHeight){
// calc the global scaling factor that fits into the new size
// and also maintains the original aspect ratio
scale=Math.min((newMaxWidth/origWidth),(newMaxHeight/origHeight))
// resize the canvas while maintaining correct aspect ratio
canvas.width=origWidth*scale;
canvas.height=origHeight*scale;
// Note: changing the canvas element's width or height will
// erase the canvas so you must reissue all your drawing commands
drawLines(lines,i,table,xtotal,ytotal);
}
// call drawLines
function drawLines(lines,i,table,xtotal,ytotal){
// scale the canvas coordinate system to the current scale
// Note: This scales the coordinates used internally
// by canvas. It does not resize the canvas element
ctx.scale(s,s);
// now do your drawing commands
// You do not need to adjust your drawing coordinates because
// the Canvas will do that for you
var xIni;
var xFin;
var yIni;
var yFin;
xIni = (c.width*parseInt(lines[i][1])/xtotal);
yIni = (c.height*parseInt(lines[i][2])/ytotal);
xFin = (c.width*parseInt(lines[i][3])/xtotal);
yFin = (c.height*parseInt(lines[i][4])/ytotal);
ctx.beginPath();
ctx.moveTo(xIni,c.height-yIni);
ctx.lineTo(xFin,c.height-yFin);
ctx.lineWidth=4;
ctx.strokeStyle = colorAleatorio();
ctx.stroke();
// restore the context to it's unscaled state
ctx.scale(-s,-s);
}

Scaling a canvas. What am I doing wrong

$('#myCanvas').click(function (e) { //Default mouse Position
console.log(e.pageX);
$("#myCanvas2").attr("width", e.pageX );
$("#myCanvas3").attr("width", e.pageX );
var imageData = context.getImageData(0, 0, e.pageX,400);
context2.putImageData(imageData,0,0);
context3.putImageData(imageData,0,0);
context.clearRect ( 0 , 0 , 2000 , 2000 );
$("#myCanvas3").css("scale", "(-1, 1)" );
$("#myCanvas3").css("transform", "scale(-1,1)");
var canvas4 = document.getElementById('myCanvas4');
var context4 = canvas4.getContext('2d');
context4.drawImage( myCanvas2, 0,0 );
context4.drawImage(myCanvas3, e.pageX,0 );
context3.scale(3,3);
});
I am trying to scale my canvas with the scale command.
What am I doing wrong?
I'm not clear what you're trying to do, but these thoughts come to mind:
To get an accurate canvas mouse position, calculate relative to the canvas element:
$('myCanvas').click(function(e){
var BB=canvas.getBoundingClientRect();
var mouseX=parseInt(e.clientX-BB.left);
var mouseY=parseInt(e.clientY-BB.top);
}
About mixing CSS and Canvas:
CSS scale will operate on the center of the element.
Canvas scale will operate from the origin (the origin defaults to 0,0).
CSS scaling will not affect Canvas drawing. So if you "flip" using CSS scaling and then you draw the flipped element to a canvas, the resulting canvas drawing is not flipped.
Changing the canvas element width will also automatically clear the canvas content.
Changing CSS width will retain the canvas content, but will "stretch" the existing pixels into the new width (the content will appear deformed).
Canvas scaling commands only affect drawings done after the scale command. So your context3.scale(3,3) will not affect anything you have previously drawn on myCanvas3.
Here's how to horizontally flip an image on a canvas element:
Example code and a Demo: http://jsfiddle.net/m1erickson/tSPB2/
var img=document.getElementById("theImg");
var iw=img.width;
var ih=img.height;
var canvas2=document.getElementById('myCanvas2');
var context2=canvas2.getContext('2d');
canvas2.width=iw;
canvas2.height=ih;
context2.save();
context2.translate(iw,0);
context2.scale(-1,1);
context2.drawImage(img,0,0);
context2.restore();

Categories