Canvas getImageData().data return half image - javascript

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) {

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;

Why wont my function draw multiple bricks?

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.

Is there a way to reduce the number of coordinates in a complex enclosed SVG path?

What I'd like to do is take an SVG shape drawn by an enclosed path (in this case, a region of a map) and reduce the number of points to create a simpler shape.
I've tried implementing the Ramer-Douglas-Peucker algorithm to reduce the number of points. For example, here's a fiddle using the simplify.js library:
https://jsfiddle.net/0t3n8762/
After reading about the issue, if I understood it correctly, it seems the algorithm isn't really designed to work on enclosed shapes but open ended paths. I tried splitting each path into two (so there are two lines that together make the entire shape) and running the algorithm on each before recombining them, though the results seem essentially identical:
https://jsfiddle.net/caqwL3t7/
It may be (and indeed is quite likely) that I'm just not grasping how the algorithm is supposed to work and am implementing it incorrectly. Or perhaps that I should be trying a completely different method altogether.
coords = pathToCoords($("#JP-01").attr("d"));
for (var i = 0; i < coords.length; i++) {
newCoords[i] = simplify(coords[i], 2);
}
newPath = coordsToPath(newCoords);
$("#JP-01").attr("d", newPath);
What I would want to produce is a simpler path that still retains the overall shape of the original, drawn with fewer points. The actual result is a distorted shape that shares little in common with the original.
As Paul pointed out in the comments, you haven't considered about l and v command in a path.
I made a snippet to show how to achieve your goal but it won't work in all the cases (I guess) and it still needs to be improved.
Kindly find the snippet and comments below.
$("#simplify-1").on("click", function(){
var coords;
var newCoords = [];
var newPath;
var coordsObject;
// get the coordinates from a given path
function pathToCoords(path) {
// save each path individually (.i.e islands are stored separately)
var data = path.match(/(?<=m).*?(?=z)/igs);
var coordsArray = [];
var objectArray = [];
var objectArrayA = [];
var objectArrayB = [];
var objectContainer = [];
// split each pair of coordinates into their own arrays
for (var i = 0; i < data.length; i++) {
// should remove anything between h or v and l instead?
data[i] = data[i].split(/[LlHhVv]/);
coordsArray[i] = [];
for (var j = 0; j < data[i].length; j++) {
coordsArray[i].push(data[i][j].split(",").map(Number));
}
}
// convert each pair of coordinates into an object of x and y
for (var i = 0; i < coordsArray.length; i++) {
objectArray[i] = [];
for (var j = 0; j < coordsArray[i].length; j++) {
objectArray[i].push({
x: coordsArray[i][j][0],
y: coordsArray[i][j][1]
});
}
// split each array of coordinates in half
var halfway = Math.floor(objectArray[i].length / 2);
objectArrayB[i] = JSON.parse(JSON.stringify(objectArray[i]));;
objectArrayA[i] = objectArrayB[i].splice(0, halfway);
}
objectContainer = [objectArrayA, objectArrayB];
return objectContainer;
}
// convert the coordinates back into a string for the path
function coordsToPath(objectContainer) {
var objectArray = [];
var coordsArray = [];
var data;
// recombine the two objectArrays
for (var i = 0; i < objectContainer[0].length; i++) {
objectArray[i] = objectContainer[0][i].concat(objectContainer[1][i])
}
for (var i = 0; i < objectArray.length; i++) {
coordsArray[i] = [];
// take the X and Y values from the objectArray and strip the unwanted information
for (var j = 0; j < objectArray[i].length; j++) {
if (j == 0) {
// add 'M' in front of the first entry
coordsArray[i].push("M" + Object.values(objectArray[i][j]));
} else if (j == objectArray[i].length - 1) {
// add 'z' to the end of the last entry
coordsArray[i].push("l" + Object.values(objectArray[i][j]) + "z");
} else {
// add 'l' in front of each coordinate pair
coordsArray[i].push("l" + Object.values(objectArray[i][j]));
}
}
coordsArray[i] = coordsArray[i].toString();
}
// put everything back into a single valid SVG path string
data = coordsArray.join("");
return data;
}
// -- simplify.js -- //
/*
(c) 2017, Vladimir Agafonkin
Simplify.js, a high-performance JS polyline simplification library
mourner.github.io/simplify-js
*/
(function() {
'use strict';
// to suit your point format, run search/replace for '.x' and '.y';
// for 3D version, see 3d branch (configurability would draw significant performance overhead)
// square distance between 2 points
function getSqDist(p1, p2) {
var dx = p1.x - p2.x,
dy = p1.y - p2.y;
return dx * dx + dy * dy;
}
// square distance from a point to a segment
function getSqSegDist(p, p1, p2) {
var x = p1.x,
y = p1.y,
dx = p2.x - x,
dy = p2.y - y;
if (dx !== 0 || dy !== 0) {
var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy);
if (t > 1) {
x = p2.x;
y = p2.y;
} else if (t > 0) {
x += dx * t;
y += dy * t;
}
}
dx = p.x - x;
dy = p.y - y;
return dx * dx + dy * dy;
}
// rest of the code doesn't care about point format
// basic distance-based simplification
function simplifyRadialDist(points, sqTolerance) {
var prevPoint = points[0],
newPoints = [prevPoint],
point;
for (var i = 1, len = points.length; i < len; i++) {
point = points[i];
if (getSqDist(point, prevPoint) > sqTolerance) {
newPoints.push(point);
prevPoint = point;
}
}
if (prevPoint !== point) newPoints.push(point);
return newPoints;
}
function simplifyDPStep(points, first, last, sqTolerance, simplified) {
var maxSqDist = sqTolerance,
index;
for (var i = first + 1; i < last; i++) {
var sqDist = getSqSegDist(points[i], points[first], points[last]);
if (sqDist > maxSqDist) {
index = i;
maxSqDist = sqDist;
}
}
if (maxSqDist > sqTolerance) {
if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified);
simplified.push(points[index]);
if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified);
}
}
// simplification using Ramer-Douglas-Peucker algorithm
function simplifyDouglasPeucker(points, sqTolerance) {
var last = points.length - 1;
var simplified = [points[0]];
simplifyDPStep(points, 0, last, sqTolerance, simplified);
simplified.push(points[last]);
return simplified;
}
// both algorithms combined for awesome performance
function simplify(points, tolerance, highestQuality) {
if (points.length <= 2) return points;
var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1;
points = highestQuality ? points : simplifyRadialDist(points, sqTolerance);
points = simplifyDouglasPeucker(points, sqTolerance);
return points;
}
// export as AMD module / Node module / browser or worker variable
if (typeof define === 'function' && define.amd) define(function() {
return simplify;
});
else if (typeof module !== 'undefined') {
module.exports = simplify;
module.exports.default = simplify;
} else if (typeof self !== 'undefined') self.simplify = simplify;
else window.simplify = simplify;
})();
// -- end simplify.js -- //
coords = pathToCoords($("#OriginalJP-01").attr("d"));
for (var i = 0; i < coords.length; i++) {
newCoords[i] = [];
for (var j = 0; j < coords[i].length; j++) {
newCoords[i][j] = simplify(coords[i][j], 1);
}
}
newPath = coordsToPath(newCoords);
$("#JP-01").attr("d", newPath);
});
$("#simplify-2").on("click", function(){
let d = $("#OriginalJP-01").attr("d");
let coordsArray = [];
let data = d.match(/(?<=m).*?(?=z)/igs);
// split each pair of coordinates into the array as an object {x, y}
for (var i = 0; i < data.length; i++) {
let ca = coordsArray[i] = [];
// split data[i] into each coordinate text
let matches = data[i].match(/((\w?-?\d+(\.\d+)?)(,-?\d+(\.\d+)?)?)/g);
for(let j=0;j<matches.length;j++){
let x, y,
text = matches[j],
// split with comma and convert it to a number
temp = text.split(",").map(v=>+v.replace(/^[^\-\d]/g,""));
switch(text[0]){
default:
case "L": // absolute
x = temp[0];
y = temp[1];
break;
case "l": // relative
x = ca[j-1].x + temp[0];
y = ca[j-1].y + temp[1];
break;
case "V": // absolute
x = ca[j-1].x;
y = temp[0];
break;
case "v": // relative
x = ca[j-1].x;
y = ca[j-1].y + temp[0];
break;
case "H": // absolute
x = temp[0];
y = ca[j-1].y;
break;
case "h": // relative
x = ca[j-1].x + temp[0];
y = ca[j-1].y;
break;
}
x = +x.toFixed(2);
y = +y.toFixed(2);
ca.push({x, y});
}
}
let mArray = [];
// calculate the slopes
for(let i=0;i<coordsArray.length;i++){
mArray[i] = [];
for(let j=0;j<coordsArray[i].length-1;j++){
let {x, y} = coordsArray[i][j], // current point's x and y
{x: nx, y: ny} = coordsArray[i][j+1], // next point's x and y
dy = (ny - y);
if(dy === 0) // to check if the denominator is legal or not
// in your case, it would not enter here
mArray[i].push(Infinity);
else
mArray[i].push((nx - x) / dy);
}
}
let abandonFactor = +$("#abandonFactor").val();
let newCoordsArray = [];
for(let i=0;i<mArray.length;i++){
let na = newCoordsArray[i] = [];
// calculate the abandonRate base on the amount of the original points
let abandonRate = coordsArray[i].length * abandonFactor;
for(let j=0;j<mArray[i].length-1;j++){
let m = mArray[i][j], // this slope
nm = mArray[i][j+1]; // next slope
let diffRate = Math.abs((m - nm) / m); // calculate the changes of the slope
// check if the diffRate is greater than abandonRate
// or the sign of m not equals the sign of nm
// you can try out removing the "sign check part" and see what would happen ;)
if(diffRate >= abandonRate || (Math.sign(m) !== Math.sign(nm))){
na.push(coordsArray[i][j]);
}
}
}
let newPath = [];
// create new path
for(let i=0;i<newCoordsArray.length;i++){
let temp = [];
for(let j=0;j<newCoordsArray[i].length;j++){
let {x, y} = newCoordsArray[i][j];
let p = `${x},${y}`;
temp.push(p);
}
newPath.push("M" + temp.join("L") + "z");
}
$("#JP-01").attr("d", newPath.join(""));
}).click();
$("#abandonFactor").on("change", function(){
$("#abandonFactor_text").text(`Abandon factor: ${this.value}`);
$("#simplify-2").click();
});
div {
width: 50%;
}
.original {
float: left;
}
.simplified {
float: right;
}
.map {
box-sizing: border-box;
width: 100%;
padding: 0.5rem;
text-shadow: 1px 1px white;
cursor: grab;
}
.land {
fill: lightgreen;
fill-opacity: 1;
stroke: white;
stroke-opacity: 1;
stroke-width: 0.5;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="original">
<svg id="OriginalMap" viewBox="324.55999755859375 0 126.44989013671875 111.65999603271484" class="map" xmlns="http://www.w3.org/2000/svg" xmlns:amcharts="http://amcharts.com/ammap">
<g>
<path id="OriginalJP-01" title="Hokkaido" class="land" d="
M344.04,71.29l2.71,-2.13l0.04,-0.59l-1.96,-3.17l-1.38,-0.99l-0.7,-1.16l0.68,-2.54l-0.27,-0.48l1.64,0.11l0.6,-0.42l0.21,-0.54l0.53,-0.21l2.75,2.66l1.93,0.87l1.13,1.28l2.48,-0.47l0.17,-0.42l1.02,-0.32l0.72,0.02l-0.14,1.17l3.04,1.39l2.2,-1.22l1.97,-2.15l0.99,-1.6l0.1,-2.35l-1.38,-2.76l0.54,-1.94L363,51.89l-0.45,-2.27l1.02,-2.1l1.47,-0.89l0.76,-0.05l2.03,-1.32l0.93,-1.89l0.41,-1.95l-0.35,-7.86l0.5,-0.32l1.64,-3.44l0.21,-2.86l0.38,-0.79l0.13,-1.6l-0.3,-3.27l-0.77,-3.84l-3.04,-7.32l-0.31,-1.16l0.07,-0.99l0.86,-1.27l0.79,-1.95l-0.41,-1.4l0.15,-1.28l0.75,0.77l0.13,0.52l0.39,0.16l1.76,-0.28l1.35,-0.94l0.55,-1.99L374.52,0l0.47,0.33l0.56,1.29l0.59,0.34l0.63,1.47l2.32,1.7l2.21,3.12l4.95,5.56l3.91,7.23l2.58,2.55l2.44,3.1l5.58,4.4l1.57,0.89l0.33,0.95l1.26,0.96l3.7,1.94l3.24,1.28l5.88,1.69l2.79,0.53l0.44,-0.31l0.29,0.77l-0.06,1.28l0.87,1.55l0.58,0.48l3.21,1.01l3.41,0.21l2.57,-0.32l2.28,-1.99l1.54,-1.92l2.18,-2.04l1.83,-1.26l0.66,-1.45l1.1,-1.16l0.78,-1.38l0.46,0.03l0.45,2.23l-1.21,2.49l-0.91,0.92l-0.6,2.4l-1.73,2.13l-0.94,2.12l0.1,0.83L436.06,48l0.22,1.06l1.35,2.58l1.49,1.97l1.52,5.23l1.49,1.96l-1.16,-0.53l-0.19,-0.53l-1.14,-0.22l-0.24,0.37l0.21,1.26l0.86,-0.67l0.47,0.4l-0.29,0.55l0.37,0.39l0.4,-0.28l2.55,0.62l2.09,-1.7l0.32,-0.6l1.11,-0.71l0.24,-0.5l3.28,0.2l-0.19,0.5l-1.17,0.91l-1.73,0.31l-1.87,1.03l-0.8,2.93l-0.77,-0.36l-1.24,-0.05l-2.71,0.51l-1.51,0.9l-1.26,-0.21l-0.62,0.6l-0.14,1.15l-1.6,2.15l-1.02,0.49l-1.9,-0.1l-0.9,-0.79l0.03,-0.53l0.33,-0.31l-0.55,-0.37l-0.73,0.1l-1.19,1.73l-0.02,0.41l1.15,1.13l-2.01,-0.12l-1.15,-0.35l-3.58,-0.02l-0.69,-0.15l-1.58,-1.27l-3.06,0.54l-2.43,1.18l-3.4,2.53l-5.27,5.27l-4.08,5.8l-1.53,3.31l-0.28,1.67l0.55,1.44l-0.82,3.88l-0.91,1.53l0,1.61l-3.7,-3.72l-4.85,-2.02l-8.09,-4.45l-2.38,-1.67l-1.84,-2.05l-3.21,-0.94l-2.21,-2.05l-1.82,-1.2l-1.83,-0.53l-2.38,-0.04l-3.17,1.04l-2.08,1.29l-2.68,2.28l-1.59,0.89l-2.12,2.45l-0.34,0.75l-1.07,-0.4l-0.33,-0.55l0.38,-0.29l0.59,0.64l0.12,-0.81l-1.35,-0.41l-0.87,-2.37l-0.79,-0.4l-1.07,-1.12l-0.12,-0.58l-1.27,-1.23l-1.24,-0.09l-1.25,0.53l-0.97,-0.59l-1.21,0.03l-1.68,1.81l-1.44,2.75l-0.71,2.55l0.28,1.94l2.32,1.2l2.74,2.35l0.75,0.14l1.37,-0.53l2.04,0.31l1.23,2.21l1.63,1.22l1.08,1.88l3.15,1.36l0.55,0.89l0.79,0.59l-0.61,0.61l-0.95,0.01l-1.1,1.3l-1.66,0.66l-0.86,-0.79l-2.78,-0.91l-0.93,0.16l-0.28,0.62l-0.41,0.1l-0.18,-0.61l0.68,-0.45l-0.2,-0.67l-0.59,-0.37l-0.86,0.08l-0.41,0.33l-0.43,1.68l-1.44,1.06l-1.29,0.1l-0.35,0.33l-0.31,3.94l-0.4,0.48l-0.94,0.03l-1.96,0.87l-0.9,1.89l-0.39,0.32l-1.02,-0.8l-1.14,0.22l-0.9,-0.71l-1.08,-2.72l-0.09,-0.86l0.41,-1.77l1.35,-3.03v-1.05l0.77,0.08l0.29,-0.59l0.31,-2.7l-0.4,-1.98l-1.9,-2.94l-0.67,-0.36l-1.3,-0.12L334.29,91l-0.85,-0.88l-1.14,-0.41l-0.39,-0.73l-0.19,-1.39l0.31,-1.12l0.94,-1.03l0.33,-0.95l0.03,-2.65l-0.49,-2.23l0.92,-1.45l1.12,-0.62l2.28,-0.06l0.61,-0.91l1.39,-0.73l0.85,-1.92l0.82,0.57l0.56,0.97l0.89,-0.23l0.09,-1.39l0.82,-0.84L344.04,71.29z
M358.76,9.86l-0.09,-1.23l1.28,-1.25l2.07,1.21l0.51,1.81l-1.81,1.49l-1.37,-1.07L358.76,9.86z
M326.88,91.03l-0.29,2.22l-0.39,0.63l-0.65,0.23l-0.02,0.36l-0.61,-0.54l0.06,-1.71l-0.42,-1.11l0.74,-1.09l1.91,-0.38l0.46,-0.52l0.03,0.64L326.88,91.03z
M357.23,4.25l-0.26,2.59l-0.39,0.13L355.7,4l0.22,-1.31l-0.61,-0.34l0.09,-0.73l0.65,0.85l0.66,-0.15l-0.02,-0.59L357.03,2l0.35,0.78L357.23,4.25z"/>
</g>
</svg> Original
</div>
<div class="simplified">
<svg id="Map" viewBox="324.55999755859375 0 126.44989013671875 111.65999603271484" class="map" xmlns="http://www.w3.org/2000/svg" xmlns:amcharts="http://amcharts.com/ammap">
<g>
<path id="JP-01" title="Hokkaido" class="land" d=""/>
</g>
</svg> Simplified
<button id="simplify-1">Your method</button>
<button id="simplify-2">New method</button>
<input type="range" min="0.0001" max="0.1" value="0.01" step="0.0001" class="slider" id="abandonFactor">
<div id="abandonFactor_text">Abandon factor: 0.01</div>
</div>

JavaScript - How to find x,y position of element by key in a linear array of elements that are displayed as a square/matrix?

I have this array of values:
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
Visually represented as a matrix:
a b c d
e f g h
i j k l
m n o p
What I want to do - if I'm given any key of this array and the length of the array, to calculate the row & column value [x,y].
0 (a) of 16 (array length) would be [0,0]
6 (g) of 16 (array length) would be [1,2]
13 (n) of 16 (array length) would be [3, 1]
etc.
I'm iterating the array values in a for(i = 0; i < array.length; i++) loop to display them as tiles in a container. I could calculate each value's [x,y] position in that loop inline, or use a function to do so - doesn't really matter.
I'm stuck ..
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
var size = 100 / Math.sqrt(array.length);
for(var i = 0; i < array.length; i++) {
tile = document.createElement('div');
tile.innerHTML = array[i] + ' [x,y]';
tile.style.width = size+'%';
tile.style.height = size+'%';
tile.style.float = 'left';
tile.style.background = 'rgb('+(50+i*5)+','+(150+i*5)+',200)';
document.getElementById('square').appendChild(tile);
}
<div id="square" style="width:200px;height:200px;border:1px solid;"></div>
Calculate the width (or height) in advance, then use i % width and Math.floor(i / width) to figure out the current x and y position. (Also, when you're assigning text, make sure to assign to textContent and not innerHTML, and try not to implicitly create global variables)
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
const width = Math.sqrt(array.length);
var size = 100 / width;
for(var i = 0; i < array.length; i++) {
const tile = document.createElement('div');
const x = i % width;
const y = Math.floor(i / width);
tile.textContent = `${array[i]} [${x},${y}]`;
tile.style.width = size+'%';
tile.style.height = size+'%';
tile.style.float = 'left';
tile.style.background = 'rgb('+(50+i*5)+','+(150+i*5)+',200)';
document.getElementById('square').appendChild(tile);
}
<div id="square" style="width:200px;height:200px;border:1px solid;"></div>
You have to define the maximum column first, in your case it's 4. As updated in code follows:
var maxCol = 4;
The for each increment of i use the calculation:
x = Math.floor(i / maxCol);
y = i % maxCol;
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
var size = 100 / Math.sqrt(array.length);
var maxCol = 4;
var x = 0;
var y = 0;
for(var i = 0; i < array.length; i++) {
tile = document.createElement('div');
x = Math.floor(i / maxCol);
y = i % maxCol;
tile.innerHTML = array[i] + ' ['+ x + ',' + y + ']';
tile.style.width = size+'%';
tile.style.height = size+'%';
tile.style.float = 'left';
tile.style.background = 'rgb('+(50+i*5)+','+(150+i*5)+',200)';
tile = document.getElementById('square').appendChild(tile);
}
<div id="square" style="width:200px;height:200px;border:1px solid;"></div>

How to select DOM element with jquery

I have a function in javascript that draws images on a random canvas
I select my img source using javascript default selector,then draw part this image on a desired canvas
I want to use jquery to select my img object, but when I replace var img =document ... with var img=$("#karajan"), but the function do not draw image on canvases
Also I've tried var img=$("#karajan").text() .... $("#karajan").val() .... $("#karajan").html() but none of them did not work
function drawImage() {
var img = document.getElementById("karajan");
var arr = getRandomArray();
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var dx = ((j == 0) ? 0 : j * 150 + j * 10);
var dy = ((i == 0) ? 0 : i * 150 + i * 10);
var k = i * 3 + j;
if (k > 7) continue;
getCanvas(arr[k] - 1).drawImage(img, j * 150, i * 150, 150, 150, 0, 0, 150, 150);
}
}
}
You can just use $("#karajan").get(0). or $("#karajan")[0].

Categories

Resources