so I am experimenting with 2d drawings in Javascript and what I am trying to do is change the ctx.fillStyle (which is the drawing colour) and change it to another colour when the URL changes.
Any help would be greatly appreciated. Here is a part of my code:
The codepen link for the animation: https://codepen.io/LudovicTomlo/pen/PEWEwJ
window.draw = setInterval(function() {
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "#00ff00";
ctx.font = font_size + "px Sawarabi Gothic";
if(location.pathname.endsWith("/401?e=1")) {
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "#ff0000";
ctx.font = font_size + "px Sawarabi Gothic";
}
for(var i = 0; i < rain.length; i++) {
// random character from the set
var text = chars[Math.floor(Math.random()*chars.length)];
ctx.fillText(text, i*font_size, rain[i]*font_size);
if(rain[i]*font_size > c.height && Math.random() > 0.975) {
rain[i] = 0;
}
//incrementing Y coordinate
rain[i]++;
}
}, speed);
}
Related
I want an image to fall from the top and clear the entire canvas when the condition is true. everything is fine until ctx.clearRect(0, 0, c.width, c.height);
inactive. please help me. Thank you in advance. Here is my code
let c = document.getElementById("myCanvas"),
ctx = c.getContext("2d"),
img = new Image;
img.src = "./img/l1.png";
c.width = 300;
c.height = 600;
let s = setInterval(() => {
if (yBlock + Math.max(y1, y2, y3, y4) * 30 > 570) {
clearInterval(s);
yBlock -= 1;
ctx.clearRect(0, 0, c.width, c.height);
}
ctx.clearRect(0, 0, 300, 600);
ctx.beginPath();
ctx.drawImage(img, xBlock * 30, yBlock, xSize, ySize);
ctx.closePath();
yBlock += 1;
},
1);
I have made an audio-player and it has a canvas for its seeklider.
The ctx is the pointer that tracks audio.currentTime.
I am trying to achieve an effect so that when the ctx is moving along the X axis, the canvas before that point should have globalAlpha set to 0.4, and canvas after the ctx set to globalAlpha = 0.6.
<div class="slider-container ">
<canvas id ="canvas" height ="90" width ="300"></canvas>
</div>
//Javascript
//Load canvasbackground image.
function drawbg(){
canvasbackground_index = playlist_index;
canvasbg.src = cdir+canvasbackground[canvasbackground_index]+png;
ctx.drawImage(canvasbg,0,0,canvas.width, canvas.height);
}
//calculate canvas.ctx position on X-axis relative to audio.currentTime
function ctxupdate() {
ct = audio.currentTime * (100 / audio.duration);
ctx.x = (ct/100) * canvas.width;
seekto = ctx.x;
}
//draw a thin vertical rectangle relative to audio.currentTime
function draw() {
ctx.fillStyle = "rgb(250,250,250)";
ctx.fillRect(ctx.x, 0, 1, 90);
ctx.x = ct;
}
//animate canvas
function canvasAnimate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
requestAnimationFrame(canvasAnimate);
drawbg();
ctxupdate();
draw();
}
canvasAnimate();
Would using js instead of css be ok. Something similar to this?
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
canvas.width = 300;
canvas.height= 100;
let pic = new Image();
pic.src="https://static.toiimg.com/photo/72975551.cms"
class Cursor {
constructor(x) {
this.x = x;
}
draw() {
ctx.strokeStyle = "white";
ctx.strokeRect(this.x ,0, 2, 100);
ctx.stroke();
}
update() {
this.x == canvas.width ? this.x = 0 : this.x++
this.draw();
}
}
let cursor = new Cursor(0);
function changeBG() {
ctx.drawImage(pic,0,0,canvas.width,canvas.height);
ctx.fillStyle = "rgba(255, 255, 255, 0.4)"
ctx.fillRect(0, 0, 0 + cursor.x, canvas.height);
ctx.fillStyle = "rgba(255, 255, 255, 0.6)";
ctx.fillRect(0, 0, cursor.x + canvas.width, canvas.height);
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cursor.update();
changeBG();
requestAnimationFrame(animate);
}
animate();
<canvas id ="canvas" height ="90" width ="300"></canvas>
UPDATE: I took your ctxupdate() function and moved the contents of that to drawbg(). Then I added the fillRect and fillStyle code from above to drawbg(). The stopCanvasbg() is not used but I left it because you had it in there.
So from your sizeCanvas() to your canvasAnimate() here;s what it looks like
function sizecanvas() {
if(window.innerWidth >= 1469) {
canvas.width = 1469
canvas.clientWidth = canvas.width;
} else {
canvas.width = canvas.clientWidth;
}
}
function drawbg(){
ct = audio.currentTime * (100 / audio.duration);
//if (isNaN(ctx.x)) return;
ctx.x = (ct/100) * canvas.width;
seekto = ctx.x;
canvasbackground_index = playlist_index;
canvasbg.src = cdir+canvasbackground[canvasbackground_index]+png;
ctx.drawImage(canvasbg,0,0,canvas.width, canvas.height);
ctx.fillStyle = "rgba(255, 255, 255, 0.6)"
ctx.fillRect(0, 0, 0 + seekto, canvas.height);
ctx.fillStyle = "rgba(255, 255, 255, 0.2)";
ctx.fillRect(0, 0, seekto + canvas.width, canvas.height);
}
function stopCanvasbg(){
canvasbackground_index = (canvasbackground.length -1);
console.log(canvasbackground_index);
canvasbg.src = canvasbackground_index;
ctx.drawImage(canvasbg,0,0,canvas.width, canvas.height);
}
function canvasAnimate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawbg();
requestAnimationFrame(canvasAnimate);
}
canvasAnimate();
See if that works on your end.
I'm trying to draw a coordinate system. I have a problem with the horizontal axis. I need to turn every number by 90 degrees.
my attempt:
var canvasGraphElem = document.getElementById("canvasGraph");
canvasGraphElem.width = 300;
canvasGraphElem.height = 200;
var ctx = canvasGraphElem.getContext('2d');
for(var i = 0; i <= 300; i = i + 30) {
ctx.save();
ctx.font = "10px Arial";
ctx.textAlign = "right";
ctx.translate(140, 140);
ctx.rotate(-Math.PI/2);
ctx.fillText(i, 0 + i, 0 - 25);
ctx.restore();
};
jsfiddle
The result should look like this:
Image is teal with numbers
You can approach this two ways:
Rotating text using local transformation. This allows you to rotate the text independently an at any angle and it's easier to place text and "logic" locations, but it requires a few more steps.
Rotate the whole context at once. This require you to "switch" axis as x axis is now y, and vica verse. It also limit the rotation to 90° and you have to think in terms of switched axis.
Method 1
var ctx = document.querySelector("canvas").getContext("2d");
ctx.font = "10px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
for(var i = 0; i <= 300; i += 30) {
ctx.setTransform(1, 0, 0, 1, 10 + i, 30); // absolute transform
ctx.rotate(-Math.PI*0.25); // any angle (demo 45°)
ctx.fillText(i, 0, 0);
};
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transforms
<canvas></canvas>
Method 2
var ctx = document.querySelector("canvas").getContext("2d");
ctx.font = "10px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.translate(20, 30); // set pivot
ctx.rotate(-Math.PI*0.5); // rotate canvas -90° around pivot
for(var i = 0; i <= 300; i += 30) {
ctx.fillText(i, 10, i); // increase y, since now "y=x"
};
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transforms
<canvas></canvas>
I have made a small red rectangle inside an orange canvas. I introduced a click event which will occur when I only click on the red portion. It works fine and gives me (255 0 0). But at the lower right corner it gives me (255 165 0) which is orange and clearly not what I wanted. Why is this happening? If there is any smarter way to do this, please advise. Thanks!
<html>
<head>
<style>
</style>
</head>
<body>
<script>
function makeit() {
var canvas = document.getElementById("mycanvas");
canvas.width = 200;
canvas.height = 50;
canvas.style.position = "absolute";
canvas.style.top = "30px";
canvas.style.left = "100px";
canvas.style.border = "1px solid black";
var ctx = canvas.getContext('2d');
ctx.fillStyle = "orange";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 20, 20);
ctx.fill();
canvas.addEventListener('click', myfunc, false);
function myfunc(e) {
if (e.layerX <= 20 && e.layerY <= 20) {
var imageData = ctx.getImageData(e.layerX, e.layerY, 1, 1);
alert(imageData.data[0] + " " + imageData.data[1] + " " + imageData.data[2]);
}
}
}
window.onload = makeit;
</script>
<canvas id="mycanvas"></canvas>
</body>
</html>
You should change to:
if (e.layerX < 20 && e.layerY < 20)
Here's why: context2D.getImageData samples a rectangle. If you sample a rectangle:
(20, any_value, 1, 1)
or
(any_value, 20, 1, 1)
your sample is outside of your red rectangle (0, 0, 20, 20). In other words, pixels at positions (x, 20) and (20, y) are orange.
The CSS border is nudging the whole thing off by 1px. If you want a border, draw it on the canvas :)
var canvas = document.getElementById("mycanvas");
canvas.width = 200;
canvas.height = 50;
canvas.style.position = "absolute";
canvas.style.top = "30px";
canvas.style.left = "100px";
var ctx = canvas.getContext('2d');
ctx.fillStyle = "orange";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 20, 20);
ctx.fill();
canvas.addEventListener('click', myfunc, false);
function myfunc(e) {
if (e.layerX <= 20 && e.layerY <= 20) {
var imageData = ctx.getImageData(e.layerX, e.layerY, 1, 1);
alert(imageData.data[0] + " " + imageData.data[1] + " " + imageData.data[2]);
}
}
http://jsfiddle.net/UQM9Q/
I need to add a gradient to a canvas. I have tested all solutions, but nothing works.
Original code:
ctx.strokeStyle = params.wheelBorderColor;
ctx.lineWidth = params.wheelBorderWidth;
ctx.font = params.wheelTextFont;
ctx.clearRect(0, 0, 500, 500);
var text = null,
i = 0,
totalJoiner = pplLength;
var width = ctx.measureText(text).width + blur * 2;
for (i = 0; i < totalJoiner; i++) {
text = pplArray[i];
var angle = startAngle + i * arc;
ctx.fillStyle = colorCache.length > totalJoiner ? colorCache[i] : genHex(text);
ctx.beginPath();
// ** arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);
ctx.arc(250, 250, params.outterRadius, angle, angle + arc, false);
ctx.arc(250, 250, params.innerRadius, angle + arc, angle, true);
ctx.stroke();
ctx.fill();
ctx.save();
ctx.fillStyle = params.wheelTextColor;
ctx.translate(250 + Math.cos(angle + arc / 2) * params.textRadius, 250 + Math.sin(angle + arc / 2) * params.textRadius);
ctx.rotate(angle + arc / 2 + Math.PI / 1);
ctx.fillText(text, -ctx.measureText(text).width / 2, 6);
ctx.restore();
ctx.closePath();
}
drawArrow();
And i add this code for gradiant and the fill() is already sent to original code
var grd = ctx.createLinearGradient(0.000, 150.000, 300.000, 150.000);
// Add colors
grd.addColorStop(0.000, 'rgba(0, 0, 0, 1.000)');
grd.addColorStop(1.000, 'rgba(255, 255, 255, 1.000)');
// Fill with gradient
ctx.fillStyle = grd;
ctx.fill();
The genHex() is:
color = "#666"; colorCache.push('#'+color); return '#'+color;"
Any guidance would be helpful.
Are you drawing a rectangle within your context? Try something like this:
var canvas = document.getElementById('test-canvas');
var ctx = (canvas !== null ? canvas.getContext('2d') : null);
var grd = (ctx !== null ? ctx.createLinearGradient(0.000, 150.000, 300.000, 150.000) : null);
if (grd) {
ctx.rect(0, 0, canvas.width, canvas.height);
grd.addColorStop(0.000, 'rgba(0, 0, 0, 1.000)');
grd.addColorStop(1.000, 'rgba(255, 255, 255, 1.000)');
ctx.fillStyle = grd;
ctx.fill();
}
I have posted a working example at JSFiddle: http://jsfiddle.net/briansexton/e6rC3/