Canvas shapes becoming aliased when re-drawn in safari - html

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.

Related

Create pattern with canvas

I would like to create a pettern with canvas. The Picture which should be used should also be gernerated first. I already did something like this with this code:
document.addEventListener('DOMContentLoaded', function () {
async function draw() {
var canvas = document.getElementById('canvas1')
var ctx = canvas.getContext("2d");
var canvas = ctx.createImageData(500, 300);
ctx.fillStyle = "#7289DA";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Select the color of the stroke
ctx.strokeStyle = '#74037b';
// Draw a rectangle with the dimensions of the entire canvas
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.font = 'bold 70px sans-serif';
// Select the style that will be used to fill the text in
ctx.save();
ctx.rotate(1.7*Math.PI);
ctx.fillStyle = '#23272A';
ctx.fillText('Text', -70, 300);
ctx.restore();
// Actually fill the text with a solid color
}
draw();
});
<canvas id="canvas" width="1500" height="900">Beispiel für eine Kachelung eines Musters in Canvas.</canvas>
Now I want to create some kind of grid with it, it should look like this
How can I do that?
The best way would be using two for loops to go over the x and y values! You can surround the part that draws text with these loops and use the changing x and y values instead of hard-coded ones.
async function draw() {
var canvas = document.getElementById('canvas1')
var ctx = canvas.getContext("2d");
var canvas = ctx.createImageData(500, 300);
ctx.fillStyle = "#7289DA";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Select the color of the stroke
ctx.strokeStyle = '#74037b';
// Draw a rectangle with the dimensions of the entire canvas
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.font = 'bold 70px sans-serif';
ctx.fillStyle = '#23272A';
// Select the style that will be used to fill the text in
for (var x = 0; x < canvas.width; x += 100 ) { // 100 is the width
for (var y = 0; y < canvas.height; y += 70) { // 70 is the height
ctx.save();
ctx.translate(x, y); // offset the text
ctx.rotate(1.7*Math.PI);
ctx.fillText('Text', -70, 300);
ctx.restore();
// Actually fill the text with a solid color
}
}
}
The reason ctx.translate(x, y) is used instead of ctx.fillText('Text', x - 70, y + 300) is because using fillText would move the grid at an angle instead of just rotating the letters.

Canvas shadow / glow effect on a semi-transparent shape?

I have a semi-transparent shape:
this.cx.beginPath();
this.cx.globalAlpha = .1;
this.cx.fillStyle = gradientFill;
this.cx.strokeStyle = gradientStroke;
this.cx.arc(150, 150, 139, 0, Math.PI * 2, true);
this.cx.lineWidth = 1;
this.cx.stroke();
this.cx.fill();
I want to add a bit of shadow, but I want it to only appear outside of the shape, I guess more of a glow than a shadow. Is there a way to do this in canvas as my attempts with:
this.cx.shadowColor = 'rgba(0, 0, 0, .75)';
this.cx.shadowBlur = 5;
this.cx.shadowOffsetX = 5;
this.cx.shadowOffsetY = -5;
Look fairy ordinary as the dark shadow is visible through the semi-transparent shape.
Thanks!
One way is to use globalCompositeOperations in order to keep only your outer shadow first, and then redraw your semi-transparent parts over it.
But note that you'll have a lot of artifact noise...
(async function() {
var ctx = c.getContext('2d');
// commons
var gradientFill = ctx.createLinearGradient(0, 0, 200, 0);
gradientFill.addColorStop(0, 'rgba(0,0,0,0)')
gradientFill.addColorStop(1, 'rgba(255,0,0,1)')
var gradientStroke = ctx.createLinearGradient(0, 0, 200, 0);
gradientStroke.addColorStop(0, 'rgba(0,0,0,0)')
gradientStroke.addColorStop(1, 'rgba(0,255,0,1)')
ctx.lineWidth = 5;
// needed only once
ctx.beginPath();
ctx.arc(150, 150, 139, 0, Math.PI * 2, true);
await wait(1000); // simply to show each step
// firt we draw only the shadow with black fill and stroke
ctx.shadowColor = 'rgba(0, 0, 0, .75)';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = -5;
ctx.stroke();
ctx.fill();
await wait(1000);
// then keep only the shadow
ctx.globalCompositeOperation = 'destination-out'; // will erase existing content at drawn position
ctx.shadowColor = 'transparent'; // remove the shadow
ctx.stroke();
ctx.fill();
await wait(1000);
// finally draw the semi-transparent version
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = .1;
ctx.fillStyle = gradientFill;
ctx.strokeStyle = gradientStroke;
ctx.stroke();
ctx.fill();
})();
function wait(t) {
return new Promise(r => setTimeout(r, t))
}
<canvas id="c" height="300"></canvas>

Canvas, animate line to move up and down

I have created a horizontal line in HTML5 Canvas. I want to animate the line to move infinity up and down. Is it possible?
function horizontal_line() {
context.beginPath();
context.moveTo(100, 100);
context.lineTo(5000, 100);
context.strokeStyle = "Green";
context.stroke();
}
For an animation you will need to have a way to draw different frames, and in each frame you have to delete the previous one, calculate the new position of the line, and then draw the line again:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "Green";
var posY = 0;
var lineLength = 10;
var speed = 2;
function drawLine() {
ctx.beginPath();
ctx.moveTo(10, posY);
ctx.lineTo(10, posY+lineLength);
ctx.stroke();
}
function moveLine () {
posY += speed;
if (posY < 0 || posY > canvas.height) {
speed = speed * -1;
}
}
function loop() {
// clear old frame;
ctx.clearRect(0,0,canvas.width, canvas.height);
moveLine();
drawLine();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
<canvas id="canvas"></canvas>
In this example requestAnimationFrame is what provides you the frames you need, so the function loop() gets called over and over again. In there we clear the old frame with clearRect(), calculate the new position, and then we draw the new Line with drawLine().

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/

Draw rectancle with border without filling in html5

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);
}
}