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