Why wont my function draw multiple bricks? - javascript

So I have this simple function that should show multiple bricks, but it only shows one. Anyone knows why? I doesn't show any errors.
function drawbricks() {
for (var r = 0; r < 12; r++) {
for (var c = 0; c < 6; c++) {
var posix = r + 20;
var posiy = c + 20;
ctx.fillRect(posix, posiy, 50, 50);
}
}
}

I've added some constants so you can configure your bricks.
const c = document.getElementsByTagName('canvas')[0];
const ctx = c.getContext('2d');
ctx.fillStyle = 'orange';
drawbricks(ctx);
function drawbricks(ctx) {
const brickCountRows = 10;
const brickCountColumns = 15;
const brickWidth = 20;
const brickHeight = 10;
const brickSpacingX = 2;
const brickSpacingY = 2;
for (var r = 0; r < brickCountRows; r++) {
for (var c = -1; c < brickCountColumns; c++) { // start at -1 to fill gap caused by offset (see below)
var posix = c * (brickWidth + brickSpacingX); // switched r by c (column is x component)
var posiy = r * (brickHeight + brickSpacingY); // switched c by r (row is y component)
// offset every other row by half brickWidth + brickSpacing
if (r%2 == 1) {
posix += Math.floor((brickWidth + brickSpacingX)/2)
}
ctx.fillRect(posix, posiy, brickWidth, brickHeight);
}
}
}
<canvas/>

I believe you ment to multiply the coordinates instead of adding.
var posix = r * 20;
var posiy = c * 20;
But still, the "bricks" will overlay each other.

Related

Changing Props in React

Im trying to make a Hexagon Grid and each of the Hexes to have data props with coordinates x y z and with value. I've managed to make the logic to create the grid and coordinates, but I can't figure out how to connect them. When I try to assign x,y,z props the TypeError pops out, saying I cannot change props in Element. The code:
import { StyledHexagonGrid } from './StyledHexagonGrid.jsx';
import Hexagon from '../Hexagon/Hexagon.jsx';
export const coordinatesCalc = (radius) => {
let coordinateRadius = radius - 1;
let coordinates = [];
for (let x = -coordinateRadius; x < coordinateRadius + 1; x++) {
for (let z = -coordinateRadius; z < coordinateRadius + 1; z++) {
for (let y = -coordinateRadius; y < coordinateRadius + 1; y++) {
let sum = x + y + z;
let coordinate = { x, y, z };
if (sum === 0) {
coordinates.push(coordinate);
}
}
}
}
return coordinates;
};
function HexagonGrid({ dataparentToChild }) {
let passedRadius = Object.values({ dataparentToChild });
let radius = passedRadius[0];
let columns = 2 * radius - 1;
let height = 600 / columns;
let width = height * 1.1547;
let dom_content = [];
for (let i = 0, j = radius - 1; i < columns; i++, j--) {
for (let k = 0; k < columns - Math.abs(j); k++) {
let left = width * 0.75 * i;
let top = k * height + Math.abs(j * (height / 2));
dom_content.push(
<StyledHexagon
style={{
top: `${top}px`,
left: `${left}px`,
width: `${width}px`,
height: `${height}px`,
}}
data-x=''
data-y=''
data-z=''
value=''
/>
);
}
}
console.log(dom_content);
let coordinates = coordinatesCalc(radius);
let hexElements = [];
for(let i=0;i<coordinates.length;i++){
let el = dom_content[i];
el.props.x = coordinates[i].x;
el.props.y = coordinates[i].y;
el.props.z = coordinates[i].z;
hexElements.push(el);
}
console.log(hexElements);
return (
<StyledHexagonGrid>
<Hexagon
dataparentToChild={passedRadius[0]}
/>
</StyledHexagonGrid>
);
}
export default HexagonGrid;

How to efficiently/quickly generate hex strings of all colors in JavaScript

My initial attempt at generating all the color values takes ~8 seconds to run:
var colors = []
var start = Date.now()
for (var a = 0; a < 16; a++) {
for (var b = 0; b < 16; b++) {
for (var c = 0; c < 16; c++) {
for (var d = 0; d < 16; d++) {
for (var e = 0; e < 16; e++) {
for (var f = 0; f < 16; f++) {
colors.push(color(a, b, c, d, e, f))
}
}
}
}
}
}
var end = Date.now()
console.log('time', end - start + 'ms')
console.log(colors)
function color(a, b, c, d, e, f) {
return String(a)
+ String(b)
+ String(c)
+ String(d)
+ String(e)
+ String(f)
}
Output is this:
node gen-color
time 7906ms
[ '000000',
'000001',
'000002',
'000003',
'000004',
'000005',
'000006',
'000007',
'000008',
'000009',
'0000010',
'0000011',
'0000012',
'0000013',
'0000014',
'0000015',
'000010',
'000011',
'000012',
'000013',
'000014',
'000015',
'000016',
'000017',
'000018',
'000019',
'0000110',
'0000111',
'0000112',
'0000113',
'0000114',
'0000115',
'000020',
'000021',
'000022',
'000023',
'000024',
'000025',
'000026',
'000027',
'000028',
'000029',
'0000210',
'0000211',
'0000212',
'0000213',
'0000214',
'0000215',
'000030',
'000031',
'000032',
'000033',
'000034',
'000035',
'000036',
'000037',
'000038',
'000039',
'0000310',
'0000311',
'0000312',
'0000313',
'0000314',
'0000315',
'000040',
'000041',
'000042',
'000043',
'000044',
'000045',
'000046',
'000047',
'000048',
'000049',
'0000410',
'0000411',
'0000412',
'0000413',
'0000414',
'0000415',
'000050',
'000051',
'000052',
'000053',
'000054',
'000055',
'000056',
'000057',
'000058',
'000059',
'0000510',
'0000511',
'0000512',
'0000513',
'0000514',
'0000515',
'000060',
'000061',
'000062',
'000063',
... 16777116 more items ]
Wondering how to quickly generate all the colors, or if this is actually the quickest way, since there is a lot of data.
I don't think it's ever going to be really fast, but you can do it a lot more simply.
function allColors() {
var num = 256 * 256 * 256, colors = [];
var zeros = "000000";
for (var i = 0; i < num; i++) {
let str = i.toString(16);
colors.push(zeros.slice(str.length) + str);
}
return colors;
}
All the values up to #FFFFFF?
Slightlier pretty version:
Array(0xFFFFFF).fill(0).map((x, y) => (x + y).toString(16).padStart(6, '0'))
Performance (ish) version:
const colors = (_c = []) => {
for (let i=0xFFFFFF; i>=0; --i)
_c[i] = i.toString(16).padStart(6, '0');
return _c;
}

JS (p5.js) canvas multiplying bug and being drawn in weird resolution

I'm experiencing a bug in my code that doubles the display and ends up drawing it twice, besides itself in a weird resolution. After changing a global variable (total_sand) to a different integer, and changing it back, the display has actually tripled.
The intended result is for it to display just once in full resolution (in this case, 301x301 pixels). This bug didn't happen immediately and seemed to happen randomly upon changing the code one day.
total_sand = 100000;
sandpiles = [];
var next_sandpiles;
function setup() {
createCanvas(301, 301);
for (var x = 0; x < width; x++) {
sandpiles[x] = [];
for (var y = 0; y < height; y++) {
sandpiles[x][y] = 0;
}
}
next_sandpiles = sandpiles;
//STARTING CONDITIONS
if (width % 2 == 0) {
sandpiles[width/2][height/2] = total_sand;
} else {
sandpiles[(width-1)/2][(height-1)/2] = total_sand;
}
}
function topple() {
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
if (sandpiles[x][y] > 3) {
toppling = true;
next_sandpiles[x][y] = next_sandpiles[x][y] - 4;
if (x > 0) {
next_sandpiles[x-1][y]++;
}
if (x < width - 1) {
next_sandpiles[x+1][y]++;
}
if (y > 0) {
next_sandpiles[x][y-1]++;
}
if (y < height - 1) {
next_sandpiles[x][y+1]++;
}
}
}
}
sandpiles = next_sandpiles;
}
function update() {
loadPixels();
var r;
var g;
var b;
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
if (sandpiles[x][y] == int(0)) {
r = 255;
g = 255;
b = 0;
} else if(sandpiles[x][y] == 1) {
r = 0;
g = 185;
b = 63;
} else if(sandpiles[x][y] == 2) {
r = 0;
g = 104;
b = 255;
} else if(sandpiles[x][y] == 3) {
r = 122;
g = 0;
b = 229;
} else {
r = 255;
g = 0;
b = 0;
}
var index = (x + y * width)*4;
pixels[index] = r;
pixels[index+1] = g;
pixels[index+2] = b;
pixels[index+3] = 255; // alpha
}
}
updatePixels();
}
function draw() {
background(0);
topple();
update();
}

Canvas getImageData().data return half image

I'm trying to generate a pixelated canvas from image source - but there is a strange behavior of the getImageData() function -
on images that are higher than my canvas I keep getting only the max height data [square of max-height * max-height].
is there anything I'm missing here?
function generatePixels(){
const pixel_size = 10;
const x = 0; const y = 0;
const w = temp_ctx.canvas.width;
const h = temp_ctx.canvas.height;
let min_width = w,
min_height = h,
max_width = 0, max_height = 0;
for (var j = y; j < (y+h); j += pixel_size) {
for (var i = x; i < (x+w); i += pixel_size) {
// get current pixel image data (x,y,10,10);
var data = temp_ctx.getImageData(j, i, pixel_size, pixel_size).data;
// draw pixel on rendered canvas
rendered_ctx.fillStyle = '#' + (data[2] | (data[1] << 8) | (data[0] << 16) | (1 << 24)).toString(16).slice(1);
rendered_ctx.fillRect((j + pixel_size), (i + pixel_size), 10, 10);
}
}
}
You can find an example of the code here:
https://codepen.io/AceDesigns/pen/dZEmjZ
Please find the workable code below. The issue is with the for loop condition.
for (var j = y; j < (y+h); j += pixel_size) {
for (var i = x; i < (x+w); i += pixel_size) {

setInterval javascript memory leak

I can't figure out why the memory is increasing and it stays there each time I run this code:
easingFunction = function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}
processFrame = function () {
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
tile.percent += 4;
if (tile.percent > 0) {
var TH = Math.max(0, Math.min(TILE_HEIGHT, targetObj.height - tile.imageY));
var TW = Math.max(0, Math.min(TILE_WIDTH, targetObj.width - tile.imageX));
var SW, SH, SX, SY, amount;
draw.save();
draw.translate(tile.imageX, tile.imageY);
if (direction == "tb" || direction == "bt") {
amount = easingFunction(tile.percent, 0, TW, 100);
SW = Math.min(TW, amount);
SH = TH;
SX = 0;
SY = 0;
} else {
amount = easingFunction(tile.percent, 0, TH, 100);
SW = TW;
SH = Math.min(TH, amount);
SX = 0;
SY = 0;
}
draw.drawImage(copycanvas, tile.imageX, tile.imageY, SW, SH, SX, SY, SW, SH);
draw.restore();
}
}
var ok = true;
for (i = 0; i < tiles.length; i++) {
if (tiles[i].percent < 100) {
ok = false;
break;
}
}
if (ok) {
clearInterval(interval);
showComplete();
}
};
this.show = function (target, hideTarget) {
createTiles();
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
tile.percent = 0 - i * 10;
}
}
var intervalDelay = (config.duration * 1000) / (tiles.length * 3 + 25);
interval = setInterval(function () {
processFrame();
}, intervalDelay);
};
function Tile() {
this.imageX = 0;
this.imageY = 0;
this.percent = 0;
};
};
I left out some unimportant code. The ideea is that I call externally the show() function. The setInterval is initialized and runs processFrame() about 100 times.
I've tried to leave some code outside from processFrame, and I got to :
processFrame = function () {
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
tile.percent += 4;
}
var ok = true;
for (i = 0; i < tiles.length; i++) {
if (tiles[i].percent < 100) {
ok = false;
break;
}
}
if (ok) {
clearInterval(interval);
showComplete();
}
};
But the memory still increases.
Try validating your code with JSLint. http://www.jslint.com/
Right now your adding easingFunction & processFrame to the Global object (which isn't a good thing). Not that this is the cause of the problem, but I've found that mismanagement of my objects is the usual cause of memory leaks.
You'll want to do something like:
var MyObject = {};
MyObject.easingFunction = function(){};
MyObject.processFrame = function(){};
In short make sure you declare all objects with var before using them.
I found the problem. I was continuously redrawing the canvas. To resolve this problem I had to erase the canvas each time before modifying it.

Categories

Resources