Draw rectancle with border without filling in html5 - html

I am trying to create a grid in the canvas as below
var canvas = $("#canvas");
var ctx = canvas.get(0).getContext("2d");
ctx.strokeStyle = "rgb(0, 0, 0)";
for(x=0;x<=300;x++){
for(y=0;y<=300;y++){
ctx.strokeRect(x, y, 20, 20);
}
}
but it just fills the HTML5 canvas instead of drawing squares with border. Can someone enlighten me on what I'm doing wrong here?

I re-wrote it like this
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
context.strokeStyle = "rgb(255, 0, 0)";
for(x=0; x<5; x++){
for(y=0; y<5; y++){
context.strokeRect(y*20, x*20, 20, 20);
}
}

Related

HTML canvas: How to achieve dropshadow on clipped object?

I am trying to draw a dropshadow on a clipped image.
function drawCircle(ctx,w,h) {
ctx.beginPath();
ctx.ellipse(w/2, h/2, w/2, h/2, 0, 2 * Math.PI, false);
//ctx.fill(); // This helps, but not suitable for transparent images!
}
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
// Draw ellipse & clip (removing these 2 lines makes the dropshadow appear)
drawCircle(ctx, img.width,img.height);
ctx.clip();
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 4;
ctx.shadowColor = '#000';
ctx.clip();
ctx.drawImage(img, 0, 0);
}
img.src = 'https://i.imgur.com/NdrmFsr.jpg';
Without clipping, the image on the canvas has a very visible drop shadow.
With clipping applied, the drop shadow is not visible.
What do I need to change to make the drop shadow visible on a clipped image?
Fiddle is here: https://jsfiddle.net/av01d/xdemLs2u/
Using the css property filter
filter: drop-shadow(10px 6px 3px rgba(50, 50, 0, 1));
https://jsfiddle.net/nj2rpxz6/
Here is the mozzila doc about the drop-shadow() CSS function
Edit :
Here is how you can add css with Javascript :
const canvas = document.getElementById('c');
canvas.style.filter = "drop-shadow(10px 6px 3px rgba(50, 50, 0, 1))"
I found a solution. Draw the clipped object on a temporary canvas, then draw that canvas with shadow applied to the main canvas.
function drawCircle(ctx,w,h) {
ctx.beginPath();
ctx.ellipse(w/2, h/2, w/2, h/2, 0, 2 * Math.PI, false);
}
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = () => {
ctx.save();
drawCircle(ctx, img.width,img.height);
ctx.clip();
ctx.drawImage(img, 0, 0);
ctx.restore();
const canvas2 = document.createElement('canvas'), ctx2 = canvas2.getContext('2d');
canvas2.width = canvas.width; canvas2.height = canvas.height;
ctx2.shadowOffsetX = 4;
ctx2.shadowOffsetY = 4;
ctx2.shadowBlur = 4;
ctx2.shadowColor = '#000';
ctx2.drawImage(canvas,0,0);
//ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(canvas2,0,0);
}
img.src = 'https://i.imgur.com/NdrmFsr.jpg';

Draw Kinetic.Shape in for-loop - var i of for-loop isn't taken properly in drawFunc()

Is it possible to use the variable i of a for-loop (for(i=0; i<3; i++)) in wich the Kinetic.Shape is created to set the y-value in the custom drawFunc();
My code of the for-loop for the dynamic shape creation looks the following:
var layer = new Kinetic.Layer();
for (i = 0; i < 3; i++){
layer.add(new Kinetic.Shape({
x: 0,
y: 0,
width: 400,
height: 400,
drawFunc: function(canvas){
console.log(i); //THIS LOG ALWAYS OUTPUTS THE MAX i-VALUE (here 3)
var ctx = canvas.getContext();
ctx.beginPath();
ctx.fillStyle = 'black';
ctx.fillRect(10, i*30+2, 200, 30);
ctx.closePath();
ctx.fill();
}
}));
}
stage.add(layer);
If i log the i-value in the custom drawFunc(); the result is always 3instead of 0, 1, 2, and because of that the ctx.fillRect draws all three shapes at y = 92.
Here is a fiddle of my code with the explained behaviour.
Am I missing something obvious? Any help is greatly appreciated.
You can try something like this. By adding the layers using a function the value passed to the createLayer function is saved with each Kinetic.Shape object that's created through closures.
function createLayer(nbr){
layer.add(new Kinetic.Shape({
x: 0,
y: 0,
width: 400,
height: 400,
drawFunc: function(canvas){
console.log(nbr);
var ctx = canvas.getContext();
ctx.beginPath();
ctx.fillStyle = 'black';
ctx.fillRect(10, nbr*30+2, 200, 30);
ctx.closePath();
ctx.fill();
}
}));
}
for (var i = 0; i < 3; i++){
createLayer(i);
}

Canvas transparency mask effect reset

I'm trying to overlay a canvas on a page in an attempt to make it look like it has been frosted over and then use mousemove to clear it away, following this post:
http://www.stevecalderon.com/2012/03/html5-canvas-tricks-transparency-mask-for-eraser-effect.html
I have created a jsfiddle - http://jsfiddle.net/ZWsG6/2/
var canvas = "";
var ctx = "";
function frost2(){
var int=self.setInterval(function(){clock()},1000);
canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height= window.innerHeight;
canvas.style.position = "absolute";
canvas.style.top = "0px";
canvas.style.left = "0px";
var objTo = document.getElementById("fltouch");
objTo.appendChild(canvas);
ctx = canvas.getContext('2d');
ctx.globalAlpha = 0.95;
ctx.fillStyle = "rgb(0, 255, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
function drawPoint(pointX,pointY){
///scrape
var grd = ctx.createLinearGradient(pointX - 75,pointY-5,pointX + 75,pointY + 5)
grd.addColorStop(0, "transparent");
grd.addColorStop(0.3, "rgba(255,255,255,.6)");
grd.addColorStop(0.7, "rgba(255,255,255,.6)");
grd.addColorStop(1, "transparent");
ctx.fillStyle = grd;
ctx.fillRect(pointX - 75,pointY,400,30);
}
canvas.addEventListener('mousemove',function(e){
e.preventDefault();
drawPoint(e.pageX,e.pageY);
},false);
}
function clock(){
ctx.globalAlpha = 0.95;
ctx.fillStyle = "rgb(0, 255, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
}
I've added a function clock() to run every second and refill the canvas with the colour so that it needs to be cleared again but it doesn't work, only remove the fill altogether.
Can anyone please tell how to reset the canvas to be filled with colour again? If it could be done slowly to look sorta like it is freezing over again that would be a bonus.
You need to set globalCompositeOperation back to default source-over value before refilling a canvas:
function clock() {
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.95;
ctx.fillStyle = "rgb(0, 255, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
}
http://jsfiddle.net/VqCbv/1/

Rectangular Gradient with HTML5 Canvas Element

How can I draw a rectangle with a gradient effect like the one pictured below using the HTML5 canvas element?
Edit: Thanks for all the feedback. Yes, I have already tried many methods. For example, can I use the createRadialGradient method as #Loktar suggests? Here is some sample code:
<html>
<head>
<title>test</title>
<script type="application/x-javascript">
function draw() {
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
var grad1 = ctx.createRadialGradient(50, 50, 0, 50, 50, 50);
grad1.addColorStop(0, 'rgba(255, 252, 0, 1)');
grad1.addColorStop(1, 'rgba(68, 205, 37, 1)');
ctx.fillStyle = grad1;
ctx.fillRect(0, 0, 100, 100);
}
</script>
</head>
<body onload="draw();">
<div>
<canvas id="canvas" width="100" height="100"></canvas>
</div>
</body>
</html>
But the result is not quite what I want:
This should be done easily with a method like PathGradientBrush provided by GDI+.
I'm not sure is it possible with the HTML5 canvas element.
You could try to use a combination of linear gradient and clipping. Demo. Code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var outerColor = 'rgba(68,205,37,1)';
var innerColor = 'rgba(255,252,0,1)';
var w = 200;
var h = 50;
canvas.width = w;
canvas.height = h;
function gradient(dir) {
var grad = ctx.createLinearGradient(dir[0], dir[1], dir[2], dir[3]);
grad.addColorStop(0, outerColor);
grad.addColorStop(0.5, innerColor);
grad.addColorStop(1.0, outerColor);
return grad;
}
// idea: render background gradient and a clipped "bow"
function background() {
ctx.fillStyle = gradient([0, 0, 0, h]);
ctx.fillRect(0, 0, w, h);
}
function bow() {
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(w, h);
ctx.lineTo(w, 0);
ctx.lineTo(0, h);
ctx.clip();
ctx.fillStyle = gradient([0, 0, w, 0]);
ctx.fillRect(0, 0, w, h);
ctx.restore();
}
background();
bow();

Canvas shapes becoming aliased when re-drawn in safari

I'm drawing a simple progress indicator using canvas. When the element is drawn for the first time it looks all nice and anti-aliased, but when drawn a second time, it loses it's anti-aliasing. Anyone know what could be going on here?
function drawProgress(id, percent) {
var selected = $(safeID(id)).is('.selected');
var canvas = $(safeID("CANVAS_" + id));
var ctx = $(canvas)[0].getContext('2d');
ctx.clearRect();
if ( selected ) {
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ffffff";
}
else {
ctx.fillStyle = "#99a7ca";
ctx.strokeStyle = "#99a7ca";
}
ctx.beginPath();
ctx.arc(canvas.width()/2.0, canvas.height()/2.0, canvas.width()/2.0-1, 0, Math.PI, false);
ctx.fill();
ctx.beginPath();
ctx.arc(canvas.width()/2.0, canvas.height()/2.0, canvas.width()/2.0-1, 0, Math.PI*2.0, false);
ctx.stroke();
}
You need to specify dimensions to clearRect.