Fitting Multiple Images on a web page that update from an API - javascript

I am Trying to Build a simple web page to display a feed from my cameras that pulls a still image from the camera via the cameras api and then regrabs the image with the API (so i can configure the frame rate of the cameras to cut down on mobile data)
I have managed to build a simple website with just one of the displays, but i want to be able to display all 8 of my cameras, IP addresses 192.168.0.157 - 165
My current code is
<html>
<head>
<script type="text/JavaScript">
var refreshInterval = 1000;
var url1 = "http://192.168.0.157/api/still?passwd=pass&"
var drawDate = true;
var img1;
function init() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
img = new Image();
img.onload = function() {
canvas.setAttribute("width", img.width)
canvas.setAttribute("height", img.height)
context.drawImage(this, 0, 0);
if(drawDate) {
var now = new Date();
var text = now.toLocaleDateString() + " " + now.toLocaleTimeString();
var maxWidth = 100;
var x = img.width-10-maxWidth;
var y = img.height-10;
context.strokeStyle = 'black';
context.lineWidth = 2;
context.strokeText(text, x, y, maxWidth);
context.fillStyle = 'white';
context.fillText(text, x, y, maxWidth);
}
};
refresh();
}
function refresh()
{
img.src = img.src = url1 + "t=" + new Date().getTime();
setTimeout("refresh()",refreshInterval);
}
</script>
<title>Test4</title>
</head>
<body onload="JavaScript:init();">
<canvas id="canvas"/>
</body>
</html>
Thanks in advance

I'm thinking make an array for every camera IP, and do all the API stuff for each of those.
var ip = [
"192.168.0.157",
"192.168.0.158",
"192.168.0.159",
"192.168.0.160",
"192.168.0.161",
"192.168.0.162",
"192.168.0.163",
"192.168.0.164",
"192.168.0.165"
];
var img = [];
function init() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
for (var i = 0; i < ip.length; i++) {
img[i] = new Image();
img[i].onload = (function() {
canvas.setAttribute("width", img[i].width);
canvas.setAttribute("height", img[i].height);
context.drawImage(this, 0, 0);
if (drawDate) {
var now = new Date();
var text = now.toLocaleDateString() + " " + now.toLocaleTimeString();
var maxWidth = 100;
var x = img[i].width - 10 - maxWidth;
var y = img[i].height - 10;
context.strokeStyle = 'black';
context.lineWidth = 2;
context.strokeText(text, x, y, maxWidth);
context.fillStyle = 'white';
context.fillText(text, x, y, maxWidth);
}
})();
}
refresh();
};
function refresh() {
for (var i = 0; i < img.length; i++) {
img[i].src = "http://" + ip[i] + "/api/still?passwd=pass&t=" + new Date().getTime();
}
setTimeout("refresh()",refreshInterval);
}

Related

How to code audio visualizer with Javascript

I'm trying to code this particular audio visualization: https://codepen.io/nfj525/pen/rVBaab .
I'm struggling because instead of uploading the audio file like in the example, I want the code to run by clicking the play button of the audio. I want to use my own pre existing audio and play that and not have to upload a file. I'm new to coding and i'm not sure how to edit the javascript to do that.
This is the html I added in the audio I want to be played, "song.mp3"
<div id="content">
<input type="file" id="thefile" accept="audio/*" />
<canvas id="canvas"></canvas>
<audio src="song.mp3" id="audio" controls></audio>
</div>
and this is the js for it
window.onload = function() {
var file = document.getElementById("thefile");
var audio = document.getElementById("audio");
file.onchange = function() {
var files = this.files;
audio.src = URL.createObjectURL(files[0]);
audio.load();
audio.play();
var context = new AudioContext();
var src = context.createMediaElementSource(audio);
var analyser = context.createAnalyser();
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
src.connect(analyser);
analyser.connect(context.destination);
analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
console.log(bufferLength);
var dataArray = new Uint8Array(bufferLength);
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var barWidth = (WIDTH / bufferLength) * 2.5;
var barHeight;
var x = 0;
function renderFrame() {
requestAnimationFrame(renderFrame);
x = 0;
analyser.getByteFrequencyData(dataArray);
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
for (var i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
var r = barHeight + (25 * (i/bufferLength));
var g = 250 * (i/bufferLength);
var b = 50;
ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
audio.play();
renderFrame();
};
};
So, for this you don't need the file input element anymore in your html, so your first piece becomes:
<div id="content">
<canvas id="canvas"></canvas>
<audio src="song.mp3" id="audio" controls></audio>
</div>
As for the Javascript, there is a little more work. In summary, we will extract and name the function that actually does the entire work, and then call it on the window.onload event. So your script section should look like:
<script>
function playAudio() {
var audio = document.getElementById("audio");
// var files = this.files; // not needed
// audio.src = URL.createObjectURL(files[0]); // not needed
audio.load();
audio.play();
var context = new AudioContext();
var src = context.createMediaElementSource(audio);
var analyser = context.createAnalyser();
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
src.connect(analyser);
analyser.connect(context.destination);
analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
console.log(bufferLength);
var dataArray = new Uint8Array(bufferLength);
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var barWidth = WIDTH / bufferLength * 2.5;
var barHeight;
var x = 0;
function renderFrame() {
requestAnimationFrame(renderFrame);
x = 0;
analyser.getByteFrequencyData(dataArray);
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
for (var i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
var r = barHeight + 25 * (i / bufferLength);
var g = 250 * (i / bufferLength);
var b = 50;
ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
audio.play();
renderFrame();
};
window.onload = function () {
// start playing audio once the page is fully loaded
playAudio();
};
</script>
Note that this will have to be hosted on some server.

is there a workaround to get context.getImageData() from a canvas base64 image in casperjs?

I tried with phantomjs 2.1.1 this code :
var webPage = require('webpage');
var page = webPage.create();
page.open("http://google.com", function (status){
var out = page.evaluate(function(){
var image = new Image();
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AwLDiAQSszC7gAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVRYw+2WMYvbQBBGv5ndFegsdC6cTkWKFIEcpDkCqfLz3aQx5KqQ5lAXHRhHurW12pkUJsThDhLJyAlhXyWJWfHYmdkdIJFIJBKJRCIxJ3T+L8qT591f1yqBElgCqzxfGAOgi7HxfgvszvabqFUBlXNv8rxiXhmTEwHwqk2Mtcid93UI9RladprT26K4tfa1c5W1C2YHAAhAJ1IPQ8X8cRjQtvXFtI5OH7LsJssqYwoiR8QAAAGWRNfM18Ys+h5FMdnMjq2nyrlba2+y7KW1BWDpZxkYwBBZwFoLoBN5cG4XwoQ6M6OiXwDvi+Jdlr1yriQ6OtEJAJjIAhmRAi1RfThM0OJR0UugYq6sLU6cfukgIgCWqCCqrK2Yl5OSyKMyuMrzlTELZvec06mZI1owr4xZ5Xk5924tjMmJ3B8sY8ABOdHxSJtX62KM0+pi9KoBkN9FChAAr9rFOK/WDmi8b2LsRIIqAFV9Gnb8GFQ7kSbGxvvZO3EL1CL1MLSqw3Nmx9dBtVWth6EW2U5K4vh6FFkaUxpzxWwBftKMg2oL3Me46fv142Mtcphb6wBARKy9AjKijIiPx+mPeupVd6r3MX7q+3UIn/f7r5fZrR3g+35vjIooQEQB6FW96jfVB5EvIWz6fh3C5oyr+h8dbP6vMXDuoTmRSCQSiURiPN8BXZXzZJhVHqQAAAAASUVORK5CYII=";
var x = 0, y = 0;
image.width = 50;
image.height = 50;
var canvas = document.createElement('canvas');
canvas.id = "mycanvas";
canvas.width = 50;
canvas.height = 50;
var context = canvas.getContext("2d");
document.body.appendChild(canvas);
context.drawImage(
image,
x,
y,
canvas.width,
canvas.height,
0,
0,
image.width,
image.height
);
var imageData = context.getImageData(x, y, canvas.width, canvas.height);
var data = imageData.data;
var pix = 0;
var text = "";
// iterate over all rgba values of each pixels
for (var i = 0; i < data.length; i += 4) {
pix++;
red = data[i];
green = data[i+1];
blue = data[i+2];
alpha = data[i+3];
text += "pix " + pix + " red="+red+" green="+green+" blue="+blue+" alpha="+alpha+"\n";
}
return text;
});
console.log("out"+out);
phantom.exit();
});
The script should print the rgba values of this image, but all are rgba(0,0,0,0).
If you copy paste the evaluate part in chrome dev tools Version 55.0.2883.75 64-bit or firefox 50.0.2 (by example), you will see and values != rgba(0,0,0,0) from within the console.
So in casperjs, I can't get rgba values too. Anyone knows another way to get this rgba values and modify those from a base64 image ? If possible in vanilla javascript
Bug report : https://github.com/ariya/phantomjs/issues/14692
Found a workaround : need to create the image element before in another evaluate() :
var casper = require("casper").create();
casper.start();
casper.on('remote.message', function(message) {
console.log(message);
});
// first evaluate() to create the image
casper.thenEvaluate(function() {
// create original image to be copied
// in the canvas (mandatory to do this first step)
var originalImg = document.createElement('img');
originalImg.id = 'myoriginalimg';
originalImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AwLDiAQSszC7gAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVRYw+2WMYvbQBBGv5ndFegsdC6cTkWKFIEcpDkCqfLz3aQx5KqQ5lAXHRhHurW12pkUJsThDhLJyAlhXyWJWfHYmdkdIJFIJBKJRCIxJ3T+L8qT591f1yqBElgCqzxfGAOgi7HxfgvszvabqFUBlXNv8rxiXhmTEwHwqk2Mtcid93UI9RladprT26K4tfa1c5W1C2YHAAhAJ1IPQ8X8cRjQtvXFtI5OH7LsJssqYwoiR8QAAAGWRNfM18Ys+h5FMdnMjq2nyrlba2+y7KW1BWDpZxkYwBBZwFoLoBN5cG4XwoQ6M6OiXwDvi+Jdlr1yriQ6OtEJAJjIAhmRAi1RfThM0OJR0UugYq6sLU6cfukgIgCWqCCqrK2Yl5OSyKMyuMrzlTELZvec06mZI1owr4xZ5Xk5924tjMmJ3B8sY8ABOdHxSJtX62KM0+pi9KoBkN9FChAAr9rFOK/WDmi8b2LsRIIqAFV9Gnb8GFQ7kSbGxvvZO3EL1CL1MLSqw3Nmx9dBtVWth6EW2U5K4vh6FFkaUxpzxWwBftKMg2oL3Me46fv142Mtcphb6wBARKy9AjKijIiPx+mPeupVd6r3MX7q+3UIn/f7r5fZrR3g+35vjIooQEQB6FW96jfVB5EvIWz6fh3C5oyr+h8dbP6vMXDuoTmRSCQSiURiPN8BXZXzZJhVHqQAAAAASUVORK5CYII=";
document.body.appendChild(originalImg);
})
casper.then(function(){
casper.wait(1000);
})
// second evaluate() to create the canvas from the image
casper.thenEvaluate(function() {
// copy the original image in a canvas
var imgInInput = document.querySelector('#myoriginalimg');
var imageObj = new Image();
imageObj.src = imgInInput.getAttribute('src');
var canvas = document.createElement('canvas');
canvas.width = 50;
canvas.height = 50;
var context = canvas.getContext('2d');
context.drawImage(
imageObj,
0,
0,
canvas.width,
canvas.height,
0,
0,
canvas.width,
canvas.height
);
var imageData = context.getImageData(0, 0, 50, 50);
var data = imageData.data; // data of the current image
var pix = 0;
for(var i = 0; i < data.length; i += 4) {
pix++;
var red = data[i];
var green = data[i+1];
var blue = data[i+2];
var alpha = data[i+3];
data[i+3] = 255; // set transparency to null
data[i+1] = 255; // set green at maximum just for the test
console.log(
pix + "nth pixel" +
" red=" + red +
" green=" + green +
" blue=" + blue +
" alpha=" + alpha
);
}
// overwrite original image
context.putImageData(imageData, 0, 0);
// Create a <div> to put the canva in
var childDiv = document.createElement("div");
childDiv.appendChild(canvas);
// Create the parent <div>
var parentDiv = document.createElement("div");
parentDiv.setAttribute('id', 'outputimage');
parentDiv.setAttribute('style', 'position: absolute;z-index:9999');
document.body.insertBefore(parentDiv, document.body.firstChild);
childDiv.setAttribute('id', 'mydivid');
parentDiv.appendChild(childDiv);
});
casper.then(function() {
casper.capture("out.png");
casper.echo(casper.getHTML());
})
casper.run(function() {
this.exit();
});

Picture background for canvas particle

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

How to add images to each canvas?

I have 10 canvases on the same page. On each canvas I'm trying to add an existent image. Is this possible? I tried this next code but is not displaying any image:
var numberOfPages = $('.draw_pages canvas').length;
var i = 0;
var counter = 0;
for(i=0; i<numberOfPages; i++){
counter++;
var canvas = document.getElementById("canvas_"+counter);
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World "+ counter, 110, 250);
//add images to canvas
var base_image = new Image();
base_image.onload = function(){
init();
}
base_image.src = '../images/page_1.png';
function drawImage(){
ctx.drawImage(base_image, 0, 0, 575, 575);
}
function init(){
drawImage();
}
}
I've also tried this way, but it works only when I hit enter key on the url of the browser and the text is being drawed:
var numberOfPages = $('.draw_pages canvas').length;
var i = 0;
var counter = 0;
for(i=0; i<numberOfPages; i++){
counter++;
console.log(counter);
var canvas = document.getElementById("canvas_"+counter);
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World "+ counter, 110, 250);
//add images to canvas
drawImage();
function drawImage(){
base_image = new Image();
base_image.src = '../jester/images/page_1.png';
//base_image.onload = function(){
ctx.drawImage(base_image, 0, 0, 575, 575);
//}
}
}
Any ideas?
Be simple! Use jquery .each() and do Your operations inside of it.
$(function() {
$('canvas').each(function() {
var n = $(this).attr('id').split('_')[1];
var context = this.getContext('2d');
var image = new Image();
image.src = 'http://lorempixel.com/image_output/abstract-q-c-640-480-'+n+'.jpg';
image.onload = function(){
context.drawImage(image, 0, 0, 575, 575);
context.font = '30px Arial';
context.fillText('Hello World '+ n, 20, 20);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas_1"></canvas>
<canvas id="canvas_2"></canvas>
<canvas id="canvas_3"></canvas>

Javascript array and object/classes

i am trying to display three playing cards on the screen and for some reason everytime i run the code a type error appears and i have tried everything to try to fix it but nothing has worked. I think that the problem is in the array/object constructor but i think that everything is right inside of those.
"use strict";
function main(){
var cvs = document.getElementById("foo");
var ctx = foo.getContext("2d");
function Card(posX, posY, imgX, imgY){
this.posX = posX;
this.posY = posY;
this.imgX = imgX;
this.imgY = imgY;
this.width = 97;
this.height = 129;
}
Card.img = new Image();
Card.img.src = "allcards.png";
var cards = [new Card(0,0,0,0), new Card(400,400,194,258), new Card(200,200,291,387)];
var greaterX = false;
var lessX = false;
var greaterY = false;
var lessY = false;
var offsetX;
var offsetY;
setInterval(draw, 10);
function draw(){
ctx.fillStyle="rgb(0,255,255)";
ctx.clearRect(0,0,600,600);
ctx.drawImage(Card.img,cards[1].imgX,cards[1].imgY,Card.width,Card.height,cards[1].posX, cards[1].posY);
ctx.drawImage(Card.img,cards[2].imgX,cards[2].imgY,Card.width,Card.height,cards[2].posX, cards[2].posY);
}
}
var ctx = foo.getContext("2d");
should this not be
var ctx = cvs.getContext("2d");
You seem to have confused the static properties of the Card function object with those of the Card instances - the width and height properties are instance properties.
var cvs = document.getElementById("foo");
var ctx = cvs.getContext("2d");
function Card(posX, posY, imgX, imgY){
this.posX = posX;
this.posY = posY;
this.imgX = imgX;
this.imgY = imgY;
}
// default values/methods, accessible and overwritable on all instances:
Card.prototype.width = 97;
Card.prototype.height = 129;
Card.prototype.draw = function() {
ctx.drawImage(Card.img, this.imgX, this.imgY, this.width, this.height, this.posX, this.posY);
};
// static property:
Card.img = new Image();
Card.img.src = "allcards.png";
Card.img.onload = draw;
var cards = [new Card(0,0,0,0), new Card(400,400,194,258), new Card(200,200,291,387)];
function draw(){
ctx.fillStyle="rgb(0,255,255)";
ctx.clearRect(0,0,600,600);
for (var i=0; i<2; i++)
cards[i].draw();
};

Categories

Resources