How to rendering Socket data in canvas html5? - javascript

1) How to rendering Socket data in canvas html5?
Using constant data i rending canvas.
When i am getting data from socket that is not rending like above one
1) socket data coming like same above example every 10 seconds

I think; your data array should be outside of 'drawWave' method as your fiddle ex and you should call 'drawWave' method just once in 'socket.on'. After a call of 'drawWave'. you should change your data array at 'socket.on' , not at 'drawWave'.
Could you try that?
var data = [];
var drawWaveCaught=false;
socket.on('canvasData', function (incomeData) {
console.log(incomeData);
data = JSON.parse("[" + incomeData + "]");
if(!drawWaveCaught){
drawWaveCaught = true;
that.drawWave();
}
});
function drawWave() {
requestAnimFrame(drawWave);
var n = 0;
var canvas = document.getElementById('canvas');
//alert(id);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#dbbd7a";
ctx.fill();
ctx.lineWidth = "2";
ctx.strokeStyle = 'green';
// Drawing code goes here
for(n=1;n<=data.length;n++)
{
ctx.beginPath();
ctx.moveTo(n - 1, data[n - 1] * 2);
ctx.lineTo(n, data[n] * 2);
ctx.stroke();
ctx.clearRect(n + 1, 0, 10, canvas.height);
}
}

Related

how to draw multiple square using a loop to change the position only in java script?

I am trying to use a button that can build a small square every time I click it with changing only position x
this is the code but it doesn't draw a square instead it's drawing a long rectangle
let addBlock = document.getElementById('addBlock')
var c = document.getElementById('canvas1');
var ctx = c.getContext("2d");
let s =0;
for(let i=0; i<=100; i=i+5 ){
addBlock.addEventListener('click', function(){
ctx.beginPath();
ctx.rect(10+i, 20,9, 100);
ctx.fill()
s=s+i; })}
rect(x,y,height,width)
I think you just need to change the width from 100 to 9.
ctx.rect(10+i, 20, 9, 9);
if i understood the purpose of your application correctly then you want to change the position on each click. Your code doesnt work because the foorloop finishes before you even get to click once. My solution is the following:
let addBlock = document.getElementById('addBlock');
var c = document.getElementById('canvas1');
var ctx = c.getContext('2d');
let i = 0;
let fn = function() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.rect(20 + i, 20, 100, 100);
ctx.fill();
i += 5;
addBlock.addEventListener('click', fn);
};
addBlock.addEventListener('click', fn);
See my Stackblitz link for a working example:
https://stackblitz.com/edit/web-platform-4dhxpt?file=script.js
EDIT:
changed the code to run a maximum of 20 times:
let fn = function() {
if (i >= 100) {
return;
}
ctx.beginPath();
ctx.rect(20 + i, 20, 100, 100);
ctx.fill();
i += 5;
addBlock.addEventListener('click', fn);
};

How to (re)fill circle in canvas - requestAnimationFrame - HTML, JS

how can I fill the "new" canvas circle that appears next to the older one.
There is no problem with rectangle for example:
**
ctx.fillStyle = 'rgba('+quadratto.r+','+quadratto.g+','+quadratto.b+',1)';
quadratto.x += quadratto.speedX;
quadratto.y += quadratto.speedY;
quadratto.speedY += quadratto.speedY*(-0.15);
ctx.fillRect(quadratto.x-quadratto.h/4, quadratto.y-quadratto.h/2, 2, 2);**
What I want to do?
I'm creating animation in canvas where random-sized-color circle will appear and
it will move in a specified direction. The new canvas layaer will appear in the next frame (fps) with a new(old) circle.
var myCanvasPattern = document.createElement('canvas');
myCanvasPattern.width = window.innerWidth;
myCanvasPattern.height = window.innerHeight;
document.body.appendChild(myCanvasPattern);
var ryC = myCanvasPattern.getContext('2d');
function lottery(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
var allQuadro = [];
var fps = 50;
var lastTime = 0;
animationLoop();
function animationLoop(time){
requestAnimationFrame( animationLoop );
if(time-lastTime>=1000/fps){
lastTime = time;
for(var i=0;i<10;i++){
allQuadro.push({
r : lottery(0, 240),
g : lottery(0, 240),
b : lottery(0, 240),
circleR : lottery(10, 30),
x : myCanvasPattern.width/2,
y : myCanvasPattern.height/2,
speedX : lottery(-1000,1000)/100,
speedY : lottery(-1000,1000)/100
})
}
ryC.fillStyle = 'rgba(255,255,255,0.2)';
ryC.fill(0,0,myCanvasPattern.width, myCanvasPattern.height);
for(var i=0; i<allQuadro.length;i++){
var circle = allQuadro[i];
ryC.fillStyle = 'rgba('+circle.r+','+circle.g+','+circle.b+',1)';
circle.x += circle.speedX;
circle.y += circle.speedY;
//HERE's THE PROBLEM BELOW. HOW TO CREATE NEW ONE THAT APPEARS NEXT TO PREVIOUS ONE WITH NEW RANDOM COLOR
ryC.arc(circle.x-circle.circleR/2, circle.y-circle.circleR/2, circleR, 0, 2 * Math.PI);
//ryC.fill();
}
// ryC.fillStyle = 'rgba('+r+','+g+','+b+',1)';
//ryC.arc(x+speedX, y+speedY, circleR, 0, 2 * Math.PI);
//ryC.fill();
}
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
The fillRect() will fill directly to the canvas without going via a path (versus for example rect()).
The arc() on the other hand will add to a path which needs to be filled later. It also require the path to be cleared in-between the calls using beginPath().
A simple way to think about it is to wrap the necessary code into a function that acts like fillRect():
function fillArc() {
ctx.beginPath(); // clear current path
ctx.arc.apply(ctx, arguments); // apply arguments to arc() call
ctx.fill();
// notice that the arc still exist on the path after this call
// so to "truly" behave like fillRect() you could consider an
// additional beginPath() here.. it will depend on your code
}
In action:
var ctx = c.getContext("2d");
ctx.fillStyle = "#09f";
fillArc(70, 70, 70, 0, 6.28);
ctx.fillStyle = "#0a9";
fillArc(220, 70, 70, 0, 6.28);
function fillArc() {
ctx.beginPath();
ctx.arc.apply(ctx, arguments);
ctx.fill();
}
<canvas id=c></canvas>
If you are bold you can also add the method to the context itself before calling getContext():
CanvasRenderingContext2D.prototype.fillArc = function() {
this.beginPath();
this.arc.apply(this, arguments);
this.fill();
}
The use it like any other method:
ctx.fillArc( ... );
CanvasRenderingContext2D.prototype.fillArc = function() {
this.beginPath();
this.arc.apply(this, arguments);
this.fill();
}
var ctx = c.getContext("2d");
ctx.fillStyle = "#09f";
ctx.fillArc(70, 70, 70, 0, 6.28);
ctx.fillStyle = "#0a9";
ctx.fillArc(220, 70, 70, 0, 6.28);
<canvas id=c></canvas>

Canvas creating two separate animated waterfall objects

I am trying to create a template for initiating as many waterfall objects as I wish without having to create a new canvas for each of them. I want two waterfalls with different colors but it doesn't work. I can't figure out why and I'm on it since a few hours. How can I make both red and blue waterfalls appear where the first has a lower z index than the last instantiation?
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var w = canvas.width = window.innerWidth;
var h = canvas.height = window.innerHeight;
function waterfall(color) {
var self = this;
this.color = color;
this.water = [];
this.Construct = function(y, vel, acc) {
this.y = y;
this.vel = vel;
this.acc = acc;
}
for(var i = 0; i < 1000; i++) {
this.water.push(new this.Construct(Math.random() * 65, 0.1 + Math.random() * 4.3, 0));
}
this.flow = function(color) {
ctx.clearRect(0, 0, w, h);
for(var i = 0; i < this.water.length; i++) {
this.water[i].vel += this.water[i].acc;
this.water[i].y += this.water[i].vel;
ctx.beginPath();
ctx.arc(0 + i * 0.5, this.water[i].y, 2, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
for(var i = 0; i < this.water.length; i++) {
if(this.water[i].y > window.innerHeight) {
this.water[i].y = 0;
}
}
requestAnimationFrame(function() {
self.flow.call(self);
});
}
this.flow(this.color)
}
new waterfall("blue");
new waterfall("red");
Here's my working code: https://jsfiddle.net/testopia/d9jb08xb/5/
and here again my intention to create two separate waterfalls but this time with the prototype inheritance:
https://jsfiddle.net/testopia/d9jb08xb/8/
I do prefer the latter but I just cant get either working.
The problem is that you are clearing the canvas in each waterfall. One is overpainting the other. You can immediately see that by commenting out the line
ctx.clearRect(0, 0, w, h);
Of course the water smears that way.
You have to manage your waterfalls in a way that in each animation frame you first clear the canvas then let them paint all.
Here is a quick attempt using a master flow_all() function:
https://jsfiddle.net/kpomzs83/
Simply move this line...
ctx.clearRect(0, 0, w, h);
... to here...
requestAnimationFrame(function() {
ctx.clearRect(0, 0, w, h); // ensure that w and h are available here.
self.flow.call(self);
});
This ensures that you do not clear the canvas before the 2nd waterfall is drawn. This clears the canvas, then draws the two waterfalls. Make sure you've added them to your water array, of course.

How to make a graph that dynamically loads from a object

$(document).ready(function () {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
function deseneazaGrafic(valori) {
var h = canvas.height;
var w = canvas.width / valori.length;
context.fillStyle = "#DEDEDE";
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "red";
context.strokeStyle = "black ";
context.lineWidth = 2;
var f = canvas.height * 0.9 / Math.max.apply(Math, valori);
for (var i = 0; i < valori.length; i++) {
context.beginPath();
context.rect((i + 0.1) * w, h - valori[i] * f, 0.8 * w, valori[i] * f);
context.fill();
context.stroke();
}
}
$("#btnGrafic").click(function () {
deseneazaGrafic(eval("[" + $("#valori").val() + "]"));
});
$("#scrie").click(function(){
});
});
This is my java script. This makes a graph from some written values. How can i change the "valori" to be jsonObject.values?Thanks a lot
As a formal answer (see question comments for details), the function deseneazaGrafic accepts a simple javascript array. Right now it's evaling (ew... bad) the value of a textarea (#valori). You can use any javascript array. When you get the values from your JSON file, just pass it to deseneazaGrafic as its parameter. For example:
var jsonObject = JSON.parse(myJSONString); // the JSON object contains an array called "values"
deseneazaGrafic(jsonObject.values);
That should render the graph just fine assuming the array is parsed correctly.

Canvas apply different image patterns for differents drawings in a canvas?

I have 4 images to show in a canvas. I have 4 drawings in it. Each image for each drawing. But when i run the loop, it's applying last image for all drawing.
How i apply different image patterns to different drawings?
Thank you.
function draw(){
var ctx = $('#canvas')[0].getContext('2d');
var $width = $('#canvas').parent().width();
var $canvas_width = 380;
var $canvas_margin = 20;
var $canvas_height = 810;
var $total_draw = $width / Math.ceil($canvas_width);
var $start = 0;
for(var i = 1; i <= $total_draw + 1; i++){
var image = new Image();
image.onload = function(){
ctx.save();
ctx.beginPath();
ctx.moveTo($start,0);
ctx.lineTo($start + $canvas_width,0);
ctx.lineTo($start, $canvas_height);
ctx.lineTo(-380 + $start, $canvas_height);
ctx.lineTo($start,0);
ctx.fillStyle = ctx.createPattern(image, "no-repeat");
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
$start = $start + ($canvas_width + $canvas_margin);
};
image.src = 'img/samples/b'+i+'.jpg';
}
}
Since you use the same variable (image), the image.src changes every time until you reach the last iteration.
The loop runs his 4 loops before any of your image is loaded, then the last image is loaded and image.onload is called and draw your stuff.
To fix this, take everything outside the for loop and use different variables name. Or you could probably do something like that :
var imgArray = new Array();
for (var i=1; i<=4; i++)
{
imgArray[i] = new Image();
imgArray[i].src = 'img/samples/b' + i + '.jpg';
imgArray[i].onload = function(){
ctx.save();
ctx.beginPath();
ctx.moveTo($start,0);
ctx.lineTo($start + $canvas_width,0);
ctx.lineTo($start, $canvas_height);
ctx.lineTo(-380 + $start, $canvas_height);
ctx.lineTo($start,0);
ctx.fillStyle = ctx.createPattern(image, "no-repeat");
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
$start = $start + ($canvas_width + $canvas_margin);
};
}
So the onload function applies to different objects.
UPDATE
Hope you'll be happy with that code :) Sorry, I did not found better images with a sequential number.
http://jsfiddle.net/r5QAF/2/ Just merge this code with yours and you'll probably reach the stuff you want
Here some reading about the problem you were facing (javascript closures in a loop) http://www.mennovanslooten.nl/blog/post/62

Categories