img src doesn't work when I use local files - javascript

I've had problems with getting a rain effekt on my canvas. After some searching on google I found this
<script type="text/javascript">
var ctx;
var imgBg;
var imgDrops;
var x = 0;
var y = 0;
var noOfDrops = 50;
var fallingDrops = [];
function setup() {
var canvas = document.getElementById('canvasRegn');
if (canvas.getContext) {
ctx = canvas.getContext('2d');
imgBg = new Image();
imgBg.src = "http://lorempixel.com/600/600/sports/";
setInterval(draw, 36);
for (var i = 0; i < noOfDrops; i++) {
var fallingDr = new Object();
fallingDr["image"] = new Image();
fallingDr.image.src = "http://lorempixel.com/10/10/sports/";
fallingDr["x"] = Math.random() * 600;
fallingDr["y"] = Math.random() * 5;
fallingDr["speed"] = 3 + Math.random() * 5;
fallingDrops.push(fallingDr);
}
}
}
function draw() {
drawBackground();
for (var i=0; i< noOfDrops; i++)
{
ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y); //The rain drop
fallingDrops[i].y += fallingDrops[i].speed; //Set the falling speed
if (fallingDrops[i].y > 450) { //Repeat the raindrop when it falls out of view
fallingDrops[i].y = -25 //Account for the image size
fallingDrops[i].x = Math.random() * 600; //Make it appear randomly along the width
}
}
}
function drawBackground(){
ctx.drawImage(imgBg, 0, 0); //Background
}
</script>
The strange thing is that the code works as long as I don't change the image source from the link to my png-files. All I get is copies of my file drawn over and over again til the canvas's is full of lines.
Help please!

It seems that for some reason your background is not rendered.
If you don't want to have any background, you have to clear the canvas before drawing drops at their new positions, or else your canvas will flood :)
Replace: ctx.drawImage(imgBg, 0, 0);
with: clearRect(0, 0, width, height)
See, also, this short demo.

Related

Trying to convert imagedata to an heightmap

I'm just trying to convert imagedata to an heightmap, to show in on the canvas. But when i do this, a strange thing appears, for all the images I tested.
Here is my code :
window.onload = function()
{
var canvas = document.getElementById('game');
if(!canvas)
{
alert("Impossible de récupérer le canvas.");
return;
}
var context = canvas.getContext('2d');
if(!context)
{
alert("Impossible de récupérer le contexte du canvas.");
return;
}
var img = new Image();
img.src = "noise.png";
var size = 250000;
var data = new Float32Array(size);
var pxlData = new Array(size);
for ( var i = 0; i < size; i ++ ) {
data[i] = 0
}
for (var i = 0; i < size; i++)
{
pxlData[i] = new Array(4);
pxlData[i][0] = 0;
pxlData[i][1] = 0;
pxlData[i][2] = 0;
}
img.onload = function()
{
context.drawImage(img, 0, 0);
var imgd = context.getImageData(0, 0, 500, 500);
context.clearRect(0, 0, canvas.width, canvas.height);
var pix = imgd.data;
var j=0;
var x=0;
var y=0;
var i=0;
for (var i = 0, n = pix.length; i < n; i += (4)) {
var all = pix[i]+pix[i+1]+pix[i+2];
pxlData[j][0] = pix[i];
pxlData[j][1] = pix[i+1];
pxlData[j][2] = pix[i+2];
pxlData[j][3] = pix[i+3];
data[j++] = all/3;
}
var alpha;
for(y = 0; y < 500; y++)
{
for(x = 0; x < 500; x++)
{
if(data[x * y] <= 100){
context.fillStyle = "blue";
}else if(data[x * y] >= 100){
context.fillStyle = "green";
}
//context.fillStyle = 'rgba('+ data[x * y] +', '+ data[x * y] +', '+ data[x * y] +', 1)';
context.fillRect(x, y, 1, 1);
// context.fillStyle = 'rgba('+ pxlData[x * y][0] +', '+ pxlData[x * y][1] +', '+ pxlData[x * y][2] +', '+ pxlData[x * y][3] +')';
// context.fillRect(x, y, 1, 1);
}
}
};
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<script type="text/javascript" src="game.js"></script>
<title>Génération de terrain</title>
</head>
<body>
<canvas id="game" width="500" height ="500">Votre navigateur ne supporte pas les canvas.</canvas>
</body>
</html>
That's what it's looking like when i run it :
canvas
The error is how you index the pixels in the 32 bit float array.
You have data[x * y] that means the pixel at 0,0 will be at index 0 * 0 = 0and pixel at 0,100 will also be at 0 * 100 = 0 and all other indexes will be wrong. To get the correct pixel address use x + y * width when indexing from an array where one item is a pixel. If indexing into pixel data 'imageData.data' each pixel is 4 items (r,g,b,a) so you would use data[x * 4 + y * canvas.width * 4] or more simply imageData.data[x + y * canvas.width * 4]
Looking at your code you have create some common mistakes that will make you code run very slow compared to what it could do. I have simplified your code. It does the same but without all the overhead. I have added comments, removing your code and suggesting alternative methods of doing the same.
The biggest change is the rendering green and blue loops. You where setting each pixel with context.fillRect(x,y,1,1); this is very very slow. Rather than draw a rectangle for each pixel use the imageData you got and fill the colour after you read the height then just put that data back onto the canvas. I used two typeArray views to set and read the data this also improved the performance.
// convert r,g,b,a to 32 bit colour using correct little or big endian
function create32Pixel(r, g, b, a){ // dont call this inside loops as very slow
var endianConvert = new Uint8ClampedArray(4); // use to convert to correct endian
var endianConvert32 = new Uint32Array(endianConvert.buffer);
endianConvert[0] = r;
endianConvert[1] = g;
endianConvert[2] = b;
endianConvert[3] = a;
return endianConvert32[0];
}
window.onload = function()
{
var canvas = document.getElementById('game');
if(!canvas)
{
alert("Impossible de récupérer le canvas.");
return;
}
var context = canvas.getContext('2d');
if(!context)
{
alert("Impossible de récupérer le contexte du canvas.");
return;
}
var img = new Image();
img.src = "noise.png";
var size = 250000;
// Do you really need floats?? 16 bit unsigned int array can hold 255 * 3 and all javascript
// numbers are converted to 64 bit floats so you will not lose precision from original when manipulating the 16bit values.
// following array is not needed.
//var dataFloat = new Float32Array(size);
// following array is not needed.
//var pxlData = new Array(size); // bad way to create an array
//var pxlData = []; // create empty array and push onto it.
// can use dataFloat.fill()
/*for ( var i = 0; i < size; i ++ ) {
dataFloat[i] = 0
}*/
//dataFloat.fill(0); // but not needed as array is zeroed when created (not from an existing buffer)
// Very inefficient as you are creating a new array for every pixel. Use flat array instead.
/*for (var i = 0; i < size; i++)
{
pxlData[i] = new Array(4);
pxlData[i][0] = 0;
pxlData[i][1] = 0;
pxlData[i][2] = 0;
}*/
// should do
/*var i;
while(i < size * 4){
pxlData[i++] = 0; // array grows as you increase i;
}*/
img.onload = function()
{
context.drawImage(img, 0, 0);
var imgd = context.getImageData(0, 0, canvas.width, canvas.height);
// don't need to clear
// context.clearRect(0, 0, canvas.width, canvas.height);
// make two views one 8bit and the other 32bit. Both point to the same data change one
// changes the other
var pixChannels = imgd.data;
var pixels = new Uint32Array(pixChannels.buffer);
var j,x,y,j;
j = x = y = i = 0;
// Create pixel colours. Need to ensure correct order as some systems
// use little edian and others big endian
// see https://en.wikipedia.org/wiki/Endianness for info.
var green = create32Pixel(0,255,0,255);
var blue = create32Pixel(0,0,255,255);
// use j as 32bit pixel index and i as 8bit index
// read the height and set pixel colour accordingly.
while(j < pixels.length){
var height = pixChannels[i++] + pixChannels[i++] + pixChannels[i++];
if(height <= 300){ // no need to divide by 3 just test for 3 time 100
pixels[j++] = blue;
}else{
pixels[j++] = green;
}
i++; // skip alpha channel
}
context.putImageData(imgd,0,0); // put pixels back to canvas.
};
}

HTML5 Canvas: Bouncing Balls with Image Overlay

I'm really struggling with a couple problems in the HTML5 canvas.
I've posted the project to GitHub pages (https://swedy13.github.io/) and added an image (the circles are in motion) so you can see the issue. Basically, if you scroll down you'll find several green circles bouncing around on the page. I'd like to replace those with my client logos.
I'm calling requestAnimation from three files based on different actions, all of which can be found in https://github.com/swedy13/swedy13.github.io/tree/master/assets/js
Filenames:
- filters.js (calls requestAnimation when you use the filters)
- main.js (on load and resize)
- portfolio.js (this is where the canvas code is)
Update: I've added the "portfolio.js" code below so the answer can be self-contained.
function runAnimation(width, height, type){
var canvas = document.getElementsByTagName('canvas')[0];
var c = canvas.getContext('2d');
// ---- DIMENSIONS ---- //
// Container
var x = width;
var y = height - 65;
canvas.width = x;
canvas.height = y;
var container = {x: 0 ,y: 0 ,width: x, height: y};
// Portrait Variables
var cPos = 200;
var cMargin = 70;
var cSpeed = 3;
var r = x*.075;
if (y > x && x >= 500) {
cPos = x * (x / y) - 150;
cMargin = 150;
}
// Landscape Variables
if (x > y) {
cPos = y * (y / x) - 50;
cMargin = 150;
cSpeed = 3;
r = x*.05;
}
// ---- CIRCLES ---- //
// Circles
var circles = [];
var img = new Image();
// Gets active post ids and count
var activeName = [];
var activeLogo = [];
var activePosts = $('.active').map(function() {
activeName.push($(this).text().replace(/\s+/g, '-').toLowerCase());
// Returns the image source
/*activeLogo.push($(this).find('img').prop('src'));*/
// Returns an image node
var elem = document.getElementsByClassName($(this).text().replace(/\s+/g, '-').toLowerCase())
activeLogo.push(elem[0].childNodes[0]);
});
// Populates circle data
for (var i = 0; i < $('.active').length; i++) {
circles.push({
id:activeName[i],
r:r,
color: 100,
/*image: activeLogo[i],*/
x:Math.random() * cPos + cMargin,
y:Math.random() * cPos + cMargin,
vx:Math.random() * cSpeed + .25,
vy:Math.random() * cSpeed + .25
});
}
// ---- DRAW ---- //
requestAnimationFrame(draw);
function draw(){
c.fillStyle = 'white';
c.fillRect(container.x, container.y, container.width, container.height);
for (var i = 0; i < circles.length; i++){
/*var img = new Image();
var path = circles[i].image;*/
/*var size = circles[i].r * 2;*/
/*img.src = circles[4].image;*/
var img = activeLogo[i];
img.onload = function (circles) {
/*c.drawImage(img, 0, 0, size, size);*/
var pattern = c.createPattern(this, "repeat");
c.fillStyle = pattern;
c.fill();
};
c.fillStyle = 'hsl(' + circles[i].color + ', 100%, 50%)';
c.beginPath();
c.arc(circles[i].x, circles[i].y, circles[i].r, 0, 2*Math.PI, false);
c.fill();
// If the circle size/position is greater than the canvas width, bounce x
if ((circles[i].x + circles[i].vx + circles[i].r > container.width) || (circles[i].x - circles[i].r + circles[i].vx < container.x)) {
circles[i].vx = -circles[i].vx;
}
// If the circle size/position is greater than the canvas width, bounce y
if ((circles[i].y + circles[i].vy + circles[i].r > container.height) || (circles[i].y - circles[i].r + circles[i].vy < container.y)){
circles[i].vy = -circles[i].vy;
}
// Generates circle motion by adding position and velocity each frame
circles[i].x += circles[i].vx;
circles[i].y += circles[i].vy;
}
requestAnimationFrame(draw);
}
}
The way it works right now is:
1. I have my portfolio content set to "display: none" (eventually it will be a pop-up when they click on one of the circles).
2. The canvas is getting the portfolio objects from the DOM, including the image that I can't get to work.
3. If I use the "onload()" function, I can get the images to show up and repeat in the background. But it's just a static background - the circles are moving above it and revealing the background. That isn't what I want.
So basically, I'm trying to figure out how to attach the background image to the circle (based on the circle ID).
----------------- UPDATE -----------------
I can now clip the image to a circle and get the circle to move in the background. But it isn't visible on the page (I can tell it's moving by console logging it's position). The only time I see anything is when the circle lines up with the images position, then it shows.
function runAnimation(width, height, type){
var canvas = document.getElementsByTagName('canvas')[0];
var c = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
// Collects portfolio information from the DOM
var activeName = [];
var activeLogo = [];
$('.active').map(function() {
var text = $(this).text().replace(/\s+/g, '-').toLowerCase();
var elem = document.getElementsByClassName(text);
activeName.push(text);
activeLogo.push(elem[0].childNodes[0]);
});
var img = new Image();
img.onload = start;
var circles = [];
var cPos = 200;
var cMargin = 70;
var cSpeed = 3;
for (var i = 0; i < 1; i++) {
circles.push({
id: activeName[i],
img: activeLogo[i],
size: 50,
xPos: Math.random() * cPos + cMargin,
yPos: Math.random() * cPos + cMargin,
xVel: Math.random() * cSpeed + .25,
yVel: Math.random() * cSpeed + .25,
});
img.src = circles[i].img;
}
requestAnimationFrame(start);
function start(){
for (var i = 0; i < circles.length; i++) {
var circle = createImageInCircle(circles[i].img, circles[i].size, circles[i].xPos, circles[i].yPos);
c.drawImage(circle, circles[i].size, circles[i].size);
animateCircle(circles[i]);
}
requestAnimationFrame(start);
}
function createImageInCircle(img, radius, x, y){
var canvas2 = document.createElement('canvas');
var c2 = canvas2.getContext('2d');
canvas2.width = canvas2.height = radius*2;
c2.fillStyle = 'white';
c2.beginPath();
c2.arc(x, y, radius, 0, Math.PI*2);
c2.fill();
c2.globalCompositeOperation = 'source-atop';
c2.drawImage(img, 0, 0, 100, 100);
return(canvas2);
}
function animateCircle(circle) {
// If the circle size/position is greater than the canvas width, bounce x
if ((circle.xPos + circle.xVel + circle.size > canvas.width) || (circle.xPos - circle.size + circle.xVel < 0)) {
console.log('Bounce X');
circle.xVel = -circle.xVel;
}
// If the circle size/position is greater than the canvas width, bounce y
if ((circle.yPos + circle.yVel + circle.size > canvas.height) || (circle.yPos + circle.yVel - circle.size < 0)) {
console.log('Bounce Y');
circle.yVel = -circle.yVel;
}
// Generates circle motion by adding position and velocity each frame
circle.xPos += circle.xVel;
circle.yPos += circle.yVel;
}
}
I'm not sure if I'm animating the correct thing. I've tried animating canvas2, but that didn't make sense to me.
PS - Sorry for the GitHub formatting, not sure why it looks like that.
PPS - Apologies for any junk code I didn't clean up. I've tried a lot of stuff and probably lost track of some of the changes.
PPPS - And forgive me for not making the answer self-contained. I thought linking to GitHub would be more useful, but I've updated the question to contain all the necessary info. Thanks for the feedback.
To get you started...
Here's how to clip an image into a circle using compositing.
The example code creates a single canvas logo-ball that you can reuse for each of your bouncing balls.
var logoball1=dreateImageInCircle(logoImg1,50);
var logoball2=dreateImageInCircle(logoImg2,50);
Then you can draw each logo-ball onto your main canvas like this:
ctx.drawImage(logoball1,35,40);
ctx.drawImage(logoball2,100,75);
There are many examples here on Stackoverflow of how to animate the balls around the canvas so I leave that part to you.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/m%26m600x455.jpg";
function start(){
var copy=createImageInCircle(img,50);
ctx.drawImage(copy,20,75);
ctx.drawImage(copy,150,120);
ctx.drawImage(copy,280,75);
}
function createImageInCircle(img,radius){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=c.height=radius*2;
cctx.beginPath();
cctx.arc(radius,radius,radius,0,Math.PI*2);
cctx.fill();
cctx.globalCompositeOperation='source-atop';
cctx.drawImage(img,radius-img.width/2,radius-img.height/2);
return(c);
}
body{ background-color:white; }
#canvas{border:1px solid red; }
<canvas id="canvas" width=512 height=512></canvas>

Canvas game, where to write code for background?

The Problem
I have been creating a game, I have got to a stage where I want to see what it looks like with a mockup background I have created.
The Question
Where about in my code should I place this code as the place it currently is doesnt show the background.
I want this background on the canvas, the dimensions are correct.
The Code
var game = create_game();
game.init();
function create_game() {
debugger;
var level = 1;
var projectiles_per_level = 1;
var min_speed_per_level = 1;
var max_speed_per_level = 2;
var last_projectile_time = 0;
var next_projectile_time = 0;
var width = 600;
var height = 500;
var delay = 1000;
var item_width = 30;
var item_height = 30;
var total_projectiles = 0;
var projectile_img = new Image();
var projectile_w = 30;
var projectile_h = 30;
var player_img = new Image();
var background_img = new Image();
var c, ctx;
var projectiles = [];
var player = {
x: 200,
y: 400,
score: 0
};
function init() {
projectile_img.src = "projectile.png";
player_img.src = "player.png";
background_img.src = "background.png";
background_img.onload = function(){
context.drawImage(background_img, 0, 0);
}
level = 1;
total_projectiles = 0;
projectiles = [];
c = document.getElementById("c");
ctx = c.getContext("2d");
ctx.fillStyle = "#410b11";
ctx.fillRect(0, 0, 500, 600);
c.addEventListener("mousemove", function (e) {
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
player.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - player_img.width / 2;
}, false);
setupProjectiles();
requestAnimationFrame(tick);
}
function setupProjectiles() {
var max_projectiles = level * projectiles_per_level;
while (projectiles.length < max_projectiles) {
initProjectile(projectiles.length);
}
}
function initProjectile(index) {
var max_speed = max_speed_per_level * level;
var min_speed = min_speed_per_level * level;
projectiles[index] = {
x: Math.round(Math.random() * (width - 2 * projectile_w)) + projectile_w,
y: -projectile_h,
v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
delay: Date.now() + Math.random() * delay
}
total_projectiles++;
}
function collision(projectile) {
if (projectile.y + projectile_img.height < player.y + 20) {
return false;
}
if (projectile.y > player.y + 74) {
return false;
}
if (projectile.x + projectile_img.width < player.x + 20) {
return false;
}
if (projectile.x > player.x + 177) {
return false;
}
return true;
}
function maybeIncreaseDifficulty() {
level = Math.max(1, Math.ceil(player.score / 10));
setupProjectiles();
}
function tick() {
var i;
var projectile;
var dateNow = Date.now();
c.width = c.width;
for (i = 0; i < projectiles.length; i++) {
projectile = projectiles[i];
if (dateNow > projectile.delay) {
projectile.y += projectile.v;
if (collision(projectile)) {
initProjectile(i);
player.score++;
} else if (projectile.y > height) {
initProjectile(i);
} else {
ctx.drawImage(projectile_img, projectile.x, projectile.y);
}
}
}
ctx.font = "bold 24px sans-serif";
ctx.fillStyle = "#410b11";
ctx.fillText(player.score, c.width - 50, 50);
ctx.fillText("Level: " + level, 20, 50);
ctx.drawImage(player_img, player.x, player.y);
maybeIncreaseDifficulty();
requestAnimationFrame(tick);
ctx.drawImage(background_img, 0, backgroundY);
}
return {
init: init
};
}
As already pointed out in a comment, here more precisely:
First of all, the background picture must be rendered first in every animation frame.
However, the picture didn't show up at all. This is due to the fact that variable was used (backgroundY), which is never declared somewhere.
This should actually printed to the console as an error "backgroundY" is not defined.
Whenever an the property src of an image object is set to a value, it takes some time until it's loaded. So in many cases, it's necessary to indicate the moment, when it's finished loading by the onload callback.
In this case, however, it's not necessary. The tick / animation loop function will just draw nothing (an empty image object) until it's loaded. After it's loaded it will continue to draw the loaded image every frame.
If the background is really important, meaning, the app should only start, when it's there, of course, one can only start the whole game / animation from within the img.onload handler.
You must draw:
the background first
the player later
level/score info last
Background < Player < UI < You Looking
The drawing order is from back to top (painters algorithm)
Also note that for performance reasons if you background never changes you could draw it in another 'static' canvas under the game canvas.
Otherwise the background will be drawn above/over the player and hide it.

Rotating images in canvases

I'm trying to create some of rotating images. So I create an array of canvases and put in each picture. But for some reason they are not displayed. Help me please.
var canvas = [], ctx = [], particles = [];
for (var i = 0; i < 10; i++){
sym.$( sym.$("Rectangle") ).append('<canvas id="partical' + i + '"></canvas>');
canvas.push(document.getElementById("partical" + i));
canvas[i].width = 550;
canvas[i].height = 400;
ctx[i] = canvas[i].getContext("2d");
}
for(var i = 0; i < 10; i++){
particles.push({
x: Math.random()*canvas[i].width, //x-coordinate
y: Math.random()*canvas[i].height, //y-coordinate
img: new Image()
})
particles[i].img.src = "images/Flake" + Math.floor(Math.random()*4+1) + ".png";
}
function draw(){
for(var i = 1; i < 10; i++){
ctx[i].clearRect(0, 0, canvas[i].width, canvas[i].height);
var p = particles[i];
ctx[i].drawImage(p.img,p.x,p.y,50,50);
ctx[i].fill();
}
}
draw();
jsFiddle : https://jsfiddle.net/CanvasCode/u0p9wtut/
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var Particle = function(xSet, ySet)
{
this.XPos = xSet;
this.YPos = ySet;
this.Sprite = new Image();
this.Sprite.src = "http://s.cdn.gaiaonline.com/images/thumbnails/85449184bbb9.png";
this.Rotation = 0;
}
var particles = new Array();
for(var i = 0; i < 10; i++){
particles.push(new Particle(Math.random()*c.width, Math.random()*c.height));
}
function draw()
{
ctx.fillStyle = "#000";
ctx.fillRect(0,0,c.width,c.height);
for(var i = 0; i < particles.length; i++)
{
var particle = particles[i];
particle.YPos += 1;
// Draw image rotated
ctx.save();
ctx.save();
ctx.translate(particle.XPos + particle.Sprite.width / 2, particle.YPos + particle.Sprite.height / 2);
ctx.rotate( particle.Rotation );
ctx.translate(-(particle.XPos + (particle.Sprite.width / 2)), -(particle.YPos));
ctx.drawImage(particle.Sprite, particle.XPos, particle.YPos);
ctx.restore();
ctx.restore();
if(particle.YPos > c.height)
{
particle.YPos = 0;
particle.XPos = Math.random()*c.width;
}
particle.Rotation += 0.01;
}
}
setInterval(draw, 3);
What you can do is use the ctx.save, ctx.restore and ctx.translate, you simply first save your canvas context so we can reload it later, we then translate the canvas, basically a translate is like setting an offset on where the image is drawn, we set the translate position to the center of the sprite, then we rotate the image around (the translate means we will rotate the image around its centre point). We then once again update the translate, draw the image rotated and then restore the canvas context because we may want to draw something else. If we don't restore the context then the next image that was draw would take into account the translate and rotate.

Editing Canvas Image

I have set a canvas to display an image with JavaScript, now I'm trying to get the image to convert to a set colour palette. I've searched through other questions and even the MDN and have had trouble finding anything on it.
I came up with this:
var image = "http://upload.wikimedia.org/wikipedia/commons/d/d7/RGB_24bits_palette_sample_image.jpg";
var canvas = document.getElementById("c");
var context = canvas.getContext("2d");
// load image from data url
var imageObj = new Image();
imageObj.src = image;
imageObj.onload = function() {
context.drawImage(this, 0, 0);
};
var imgData = context.getImageData(0,0,canvas.width,canvas.height);
var data = imgData.data;
var palette = [[0,0,0],[118,38,64],[64,51,127],[228,52,254],[14,89,64],[128,128,128],[27,154,254],[191,179,255]];
for(var i = 0; i < data.length; i += 4) {
var red = data[i];
var green = data[i+1];
var blue = data[i+2];
var alpha = data[i+3];
min = 9999999999;
paleteMatch = null;
for (var j = 0; j < palette.length; j++) {
var lsd = (Math.pow(palette[j][0] - red, 2) + green + blue) / 3;
if (lsd < min) {
min = lsd;
paletteMatch = palette[j];
}
}
data[i] = paletteMatch[0];
data[i+1] = paletteMatch[1];
data[i+2] = paletteMatch[2];
}
imgData.data.set(data);
context.putImageData(imgData, 0, 0);
The variable data seems to just hold 0s and nothing else. This is a problem when it enters the for-loop as nothing happens. As far as I can tell, I've done nothing wrong.
How come the image data is telling me every pixel is black and how can I fix this to work?

Categories

Resources