Picture background for canvas particle - javascript

I'm trying to create background for every created particle.
Canvas pattern is not working properly. I'm getting this error >> "SyntaxError: An invalid or illegal string was specified"
HTML
<canvas id="canvas"></canvas>
JS
(function(){
window.onload = function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d'),
particles = {},
particleIndex = 0,
particleNum = 1;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.width);
function Particle(){
this.x = canvas.width / 2;
this.y = 0;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.2;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.test = 0;
this.maxLife = 100;
}
Particle.prototype.draw = function(){
this.x += this.vx;
this.y += this.vy;
this.vy += this.gravity;
this.test++;
if ( this.test >= this.maxLife ) {
delete particles[this.id];
};
var img = new Image();
img.src = 'img/aaa.png';
var pattern = ctx.createPattern(img,'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(this.x, this.y, 20, 20);
};
setInterval(function(){
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
};
for(var i in particles) {
particles[i].draw();
}
},30)
}})();
I was trying to do this also with ctx.drawImage(), but picture was displayed one time only.
Any tips?:)
Fiddle

I think the issue is the image being loaded later than its used.
Inside your draw() you have:
var img = new Image();
img.src = 'img/aaa.png';
var pattern = ctx.createPattern(img,20,20);
It is a bad idea to create new images everytime you want to draw. I strongly suggest you create the img variable outside of the draw loop. Once you set the .src of an image, you have to wait until it is loaded to use it. There is an onload event you can use to let you know when its ready.
Here is an example:
var imgLoaded = false;
var img = new Image();
img.src = 'img/aaa.png';
img.onload = function() { imgLoaded = true; };
function draw() {
...
if (imgLoaded) {
var pattern = ctx.createPattern(img, 'repeat');
...
}
...
}

Related

Drawn image not moving on canvas

I make the game with html canvas.I need to move the image sprite but my code only redraw the image on the same position.Where is problem?The code is here
class Duck{
constructor(x,y){
this.x = x;
this.y = y;
this.skin = 'img/path/';
}
draw() {
var img = new Image();
img.src = this.skin;
img.onload = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img,this.x, this.y);
ctx.restore();
}
}
move(){
this.x+=10;
this.y+=10;
}
}
var canvas = document.getElementById("canv");
var ctx = canvas.getContext("2d");
var d = new Duck(0,0);
//this function called from another file and it works
function mainLoop() {
d.move();
d.draw();
requestAnimationFrame(mainLoop);
}
Here is your code fixed:
You don't need ctx.restore();
You need to store this context in the draw method, for reference in the img.onload callback
class Duck {
constructor(x, y) {
this.x = x;
this.y = y;
this.skin = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggc3R5bGU9ImZpbGw6I0ZGREU3NjsiIGQ9Ik00MzMuNjYxLDIzNy44MzdjLTQuNDk3LTYuMjE0LTQuODgtMTQuNDQtMS4yMjUtMjEuMTg0YzExLjM2NS0yMC45NjcsMTcuNzczLTQ1LjAxNCwxNy42NTEtNzAuNTY2DQoJQzQ0OS43MDEsNjQuODY5LDM4Mi41NjQtMS4wMzcsMzAxLjM1MiwwLjAxMmMtODAuMTgzLDEuMDM2LTE0NC44NjQsNjYuMzU5LTE0NC44NjQsMTQ2Ljc4OGMwLDMyLjU1MywxMC41OTUsNjIuNjMsMjguNTI2LDg2Ljk3Mg0KCWM3Ljc1MywxMC41MjYsNy4yMTMsMjUuMS0xLjU0MywzNC44MDhjLTEzLjI5NywxNC43NDEtNDEuOTM1LDI0LjMwNi0xMDIuNTk1LTE2LjI3N2MtNi42NTItNC40NS0xNC40NjItNi44NjQtMjIuNDY1LTYuODY0bDAsMA0KCWMtMTkuOTQ3LDAtMzYuODMzLDE0LjYyOC0zOS43NzYsMzQuMzU3QzcuODg5LDM1MS44MTYsNi41Miw1MTIsMjA2Ljk2Niw1MTJoNzEuMDgzQzQ2Ni4wNSw1MTIsNTE2LjEyNywzNTEuODAxLDQzMy42NjEsMjM3LjgzN3oiLz4NCjxnPg0KCTxwYXRoIHN0eWxlPSJmaWxsOiNGRkI2NDE7IiBkPSJNMTgzLjQ3LDI2OC41ODJjLTMuOTMsNC4zNTctOS4yMDIsOC4yNjEtMTYuMjQ0LDEwLjU1MmMyNC40NjksNS44ODIsMzguODItMS4zMTksNDcuMTQ5LTEwLjU1Mg0KCQljOC43NTctOS43MDgsOS4yOTYtMjQuMjgxLDEuNTQzLTM0LjgwOGMtMTcuOTMtMjQuMzQyLTI4LjUyNi01NC40Mi0yOC41MjYtODYuOTczYzAtNzUuODMzLDU3LjUwMy0xMzguMjI2LDEzMS4yODEtMTQ1Ljk4DQoJCWMtNS42ODktMC42MDEtMTEuNDY3LTAuODg0LTE3LjMyMy0wLjgwOWMtODAuMTgzLDEuMDM2LTE0NC44NjQsNjYuMzU5LTE0NC44NjQsMTQ2Ljc4OGMwLDMyLjU1MywxMC41OTUsNjIuNjMsMjguNTI2LDg2Ljk3Mw0KCQlDMTkyLjc2NiwyNDQuMywxOTIuMjI2LDI1OC44NzMsMTgzLjQ3LDI2OC41ODJ6Ii8+DQoJPHBhdGggc3R5bGU9ImZpbGw6I0ZGQjY0MTsiIGQ9Ik00OS41MzksMjc5Ljc5NmMyLjEzNy0xNC4zMTcsMTEuNjE4LTI1Ljk0MiwyNC4yODItMzEuMjQ1Yy00Ljg2Ni0yLjAyMi0xMC4wOTEtMy4xMS0xNS40MTItMy4xMQ0KCQlsMCwwYy0xOS45NDcsMC0zNi44MzMsMTQuNjI4LTM5Ljc3NiwzNC4zNTdDNy44ODksMzUxLjgxNiw2LjUyLDUxMiwyMDYuOTY2LDUxMmgzMC45MDVDMzcuNDI1LDUxMiwzOC43OTQsMzUxLjgxNiw0OS41MzksMjc5Ljc5NnoNCgkJIi8+DQoJPHBhdGggc3R5bGU9ImZpbGw6I0ZGQjY0MTsiIGQ9Ik04MC41MTgsMzQ0LjMzNmMtOC43NjYsOC42NTYtMTAuMjc3LDIyLjI2OC0zLjU5OCwzMi42MTkNCgkJYzE5LjUwNCwzMC4yMjcsNjguMzUxLDg2LjI4MywxNjIuMzcyLDg2LjI4M2M1Ny4yNTYsMCwxMTcuNzkxLTM1LjgwOSwxMjkuMDY0LTk1LjA5N2M5LjMxLTQ4Ljk2Ni0xOS4yNDYtMTA4LjgyMS03NS4zMy0xMDYuMjQ3DQoJCWMtNDEuMDk3LDEuODg3LTY1LjEzNSwzNy40MTUtOTkuODY1LDUzLjg0MWMtMjQuMzk4LDExLjU0LTUwLjg0NCwxOC42NTEtNzcuNjg3LDIxLjMwNw0KCQlDMTAyLjY5OCwzMzguMzA2LDkwLjgwNSwzMzQuMTc4LDgwLjUxOCwzNDQuMzM2eiIvPg0KPC9nPg0KPHBhdGggc3R5bGU9ImZpbGw6IzM4NDg0QTsiIGQ9Ik0zODguMzk0LDExMC44MzNjLTMuNTAyLDAtNi42NzQtMi4zOTYtNy41MTMtNS45NTFsLTMuNzE1LTE1LjczDQoJYy0wLjk4MS00LjE1MywxLjU5MS04LjMxNSw1Ljc0My05LjI5NWM0LjE1Mi0wLjk3OSw4LjMxNSwxLjU5MSw5LjI5NSw1Ljc0M2wzLjcxNSwxNS43M2MwLjk4MSw0LjE1My0xLjU5MSw4LjMxNS01Ljc0Myw5LjI5NQ0KCUMzODkuNTgsMTEwLjc2NSwzODguOTgyLDExMC44MzMsMzg4LjM5NCwxMTAuODMzeiIvPg0KPHBhdGggc3R5bGU9ImZpbGw6I0ZGQjY0MTsiIGQ9Ik00MjcuNjE4LDY4Ljk5NGMwLDAsMy4xOTgsNDUuODMyLTE4LjAzMyw2Ni41OTFjLTIxLjIzMSwyMC43NTksMTQuMTU0LDUzLjMxNCw1Ni4xNDUsMjIuNjQ2DQoJYzYuMDMyLTQuNDA1LDEyLjE0My03LjIwNCwxOC4xODQtOC43NjhjNy43NzctMi4wMTIsMTMuMjQzLTguOTY3LDEzLjI0My0xNi45OTlsMCwwYzAtNy43MjQtNS4wMzEtMTQuNTk3LTEyLjQzOC0xNi43ODYNCgljLTQuOTI1LTEuNDU2LTExLjE4LTIuMzI1LTE4LjUxNi0xLjMyNWMwLDAsMjUuMzkzLTIyLjEzOCwxOS4xMTktNDcuNzUzYy0yLjAyNy04LjI4LTExLjg1Ni0xMS43MjYtMTguODM2LTYuODMyDQoJQzQ1Ny40NjEsNjYuMDk0LDQ0My40NTQsNzIuNzY0LDQyNy42MTgsNjguOTk0eiIvPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo=';
}
draw() {
var img = new Image();
img.src = this.skin;
const that = this;
img.onload = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, that.x, that.y);
}
}
move() {
this.x += 10;
this.y += 10;
}
}
var canvas = document.getElementById("canv");
var ctx = canvas.getContext("2d");
var d = new Duck(0, 0);
//this function called from another file and it works
function mainLoop() {
d.move();
d.draw();
requestAnimationFrame(mainLoop);
}
mainLoop();
<canvas id="canv" height="600px" width="600px"></canvas>

Why wont my image draw but it loads?

I'm starting to make a game and I'm putting together a little "game engine" to do stuff easily and not type so repetitively. I have a sprite function that loads the image and an update function which draws it. The problem is it won't draw, and no errors have been reported in the console.
jsfiddle
var canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "absolute";
canvas.style.right = "0px";
canvas.style.top = "0px";
document.body.appendChild(canvas);
var c = canvas.getContext("2d");
var Squares = [];
var Square = function(x,y,w,h,color="black") {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
Squares.push(this);
return this
}
var Sprites = [];
var Sprite = function(x,y,w,h,src) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.src = src;
this.img = new Image();
this.img.onload = function() {
}
this.img.src = this.src;
this.img.width = this.w;
this.img.height = this.h;
return this
}
function Clear(x,y,w,h) {
c.clearRect(x,y,w,h);
}
function Update() {
Clear(0,0,canvas.width,canvas.height);
for(var square in Squares) {
c.fillStyle = Squares[square].color;
c.fillRect(Squares[square].x,Squares[square].y,Squares[square].w,Squares[square].h);
}
for(var sprite in Sprites) {
console.log(Sprites[sprite].img)
Sprites[sprite].img.onload = function() {
c.drawImage(Sprites[sprite].img);
}
}
}
var ground = new Square(0,0,canvas.width,canvas.height,color="forestgreen");
var player = new Square(10,10,6,6,color="red");
var Mtn = new Sprite(50,50,50,50,"mountain.png");
console.log(Mtn.img)
function Logic() {
}
function Main() {
Logic();
Update();
}
setInterval(Main,2);

Need assistance with audio visualizer using HTML5 canvas + web audio API

I'm looking at making a simple audio visualizer using canvas and the web audio API. I found this example online and want to learn more in depth to what exactly each part of the code is doing. I have some understanding to a few things.
Also importantly I also wish to change the canvas background color but have yet been successful in trying to do so.
var analyser, canvas, ctx, random = Math.random, circles = [];
window.onload = function() {
canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
setupWebAudio();
for (var i = 0; i < 280; i++) {
circles[i] = new Circle();
circles[i].draw();
}
draw();
};
function setupWebAudio() {
var audio = document.createElement('audio');
audio.src = 'flume.mp3';
document.body.appendChild(audio);
var audioContext = new AudioContext();
analyser = audioContext.createAnalyser();
var source = audioContext.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioContext.destination);
audio.play();
}
function draw() {
requestAnimationFrame(draw);
var freqByteData = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(freqByteData);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 1; i < circles.length; i++) {
circles[i].radius = freqByteData[i] * 1;
circles[i].y = circles[i].y > canvas.height ? 0 : circles[i].y + 1;
circles[i].draw();
}
}
function getRandomColor(){
return random() * 1 >> 0;
}
function Circle() {
this.x = random() * canvas.width;
this.y = random() * canvas.height;
this.radius = random() * 20 + 20;
this.color = 'rgb(' + getRandomColor() + ',' + getRandomColor() + ',' +
getRandomColor() + ')';
}
Circle.prototype.draw = function() {
var that = this;
ctx.save();
ctx.beginPath();
ctx.globalAlpha = random() / 8 + 0.2;
ctx.arc(that.x, that.y, that.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
}
Change the color in draw() function.
This lines creates a rectangle as the background.
ctx.clearRect(0, 0, canvas.width, canvas.height);
Just before it, set the color, e.g.:
ctx.fillStyle = rgb(1, 2, 3);
ctx.clearRect(0, 0, canvas.width, canvas.height);

Draw SVG on canvas [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have a set of coordinates and for every pair I'd like to place a SVG on the canvas. The problem is in getCircle function. The SVG doesn't work, but if I draw a circle(see commented code) it works.
function getCircle() {
var circle = document.createElement("canvas"),
ctx = circle.getContext("2d"),
r2 = radius + blur;
circle.width = circle.height = r2 * 2;
/*
ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2;
ctx.shadowBlur = blur;
ctx.shadowColor = "purple";
ctx.beginPath();
ctx.arc(-r2, -r2, radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
*/
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = "https://upload.wikimedia.org/wikipedia/en/0/09/Circle_Logo.svg";
return circle;
}
var radius = 5;
var blur = 1;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 200;
var circle = getCircle();
ctx.clearRect(0, 0, canvas.width, canvas.height);
var data = [[38,20,2]];
for (var i = 0, len = data.length, p; i < len; i++) {
p = data[i];
ctx.drawImage(circle, p[0] - radius, p[1] - radius);
}
#c {
width: 400px;
height: 200px;
}
<canvas id="c"></canvas>
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 200;
var data = [[0,20,2],[125,20,2],[250,20,2]];
drawImage();
function drawImage() {
var img = new Image();
img.onload = function() {
for (var i = 0, len = data.length, p; i < len; i++) {
p = data[i];
ctx.drawImage(this, p[0] , p[1] , 150, 150);
}
};
img.src = "https://upload.wikimedia.org/wikipedia/en/0/09/Circle_Logo.svg";
}
#c {
width: 400px;
height: 200px;
}
<canvas id="c"></canvas>
in img.onload() draw your image in specified position with widht and height using drawImage().

How do I add four rotating images to an animated background?

I am trying to add four rotating images to an animated background.
I can only get one image working correctly with my code below.
How can I add in the other three images?
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('img');
img.onload = function(){
render();
}
img.src = 'nano3.png';
function drawImage(img,x,y,r,sx,sy){
sx=sx||0;
sy=sy||0;
r=(r*Math.PI/180)||0;
var cr = Math.cos(r);
var sr = Math.sin(r);
ctx.setTransform(cr,sr,-sr,cr,x-(cr*sx-sr*sy),y-(sr*sx+cr*sy));
ctx.drawImage(img,1,2);
}
var r = 1;
function render(){
requestAnimationFrame(render);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,800,800);
drawImage(img,50,50,r++,img.width/2,img.height/2);
}
This should help you out, I just created an object known as rotatingimage which stores a location, an image and its current rotation. We call the 'draw' method in a 'setInterval' function call which deals with rotating the canvas and then drawing the sprite correctly.
Just a note rotating many images can cause the canvas to lag also the CurrentRotation variable never gets reset to 0 when it reaches >359 so the CurrentRotation variable will keep going higher and higher, you may want to fix that in the RotatingImage.prototype.Draw function
jsFiddle:https://jsfiddle.net/xd8brfrk/
Javascript
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function RotatingImage(x, y, spriteUrl, rotationSpeed) {
this.XPos = x;
this.YPos = y;
this.Sprite = new Image();
this.Sprite.src = spriteUrl;
this.RotationSpeed = rotationSpeed;
this.CurrentRotation = 0;
}
RotatingImage.prototype.Draw = function(ctx) {
ctx.save();
this.CurrentRotation += 0.1;
ctx.translate(this.XPos + this.Sprite.width/2, this.YPos + this.Sprite.height/2);
ctx.rotate(this.CurrentRotation);
ctx.translate(-this.XPos - this.Sprite.width/2, -this.YPos - this.Sprite.height/2);
ctx.drawImage(this.Sprite, this.XPos, this.YPos);
ctx.restore();
}
var RotatingImages = [];
RotatingImages.push(new RotatingImage(50, 75, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(270, 25, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(190, 180, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
RotatingImages.push(new RotatingImage(100, 270, "http://static.tumblr.com/105a5af01fc60eb94ead3c9b342ae8dc/rv2cznl/Yd9oe4j3x/tumblr_static_e9ww0ckmmuoso0g4wo4okosgk.png", 1));
setInterval(function() {
ctx.fillStyle = "#000"
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < RotatingImage.length; i++) {
var rotatingImage = RotatingImages[i];
rotatingImage.Draw(ctx);
}
}, (1000 / 60));
you can use save and restore to apply different transform to your drawing
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore

Categories

Resources