I have tried several ways but nothing is working, I want to put the contents of one javascript file into the other, the code I tried is:
for (k = 0; k < js_array2; k++) {
p[k]=Math.random();
if(p[k]<0.5){
$.getScript('/path/to/imported/script.js')
} else {
//Some code
}
The code in the script I want to include is:
var c = document.getElementById("canvas[" + k + "]");
document.getElementById("shape[" + k + "]").innerHTML = "Square";
var ctx = c.getContext("2d");
var width = c.width;
var height = c.height;
//ctx.strokeRect(0, 0, 120, 120);
var n = hour2[k];
var z = 0;
var m = minute2[k];
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
var x = 0 + (i - 1) * width / n;
var y = 0 + (j - 1) * height / n;
ctx.beginPath();
ctx.rect(x, y, width / n, height / n);
ctx.fillStyle = "cyan"
if (z < m) {
ctx.fillRect(x, y, width / n, height / n);
z = z + 1;
}
ctx.stroke();
}
}
I have tried several other ways too but this was the only one without errors but unfortunately no output.
In modern JavaScript it would look something like this:
export something from a file
export c = //whatever
import it dynamically from another file
if(some_condition){
{c} = await import('/path/to/imported/script.js')
// do whatever with c
}
Read more on exports on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
Read more about imports on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports
What you can do is create a function out of the second file, then check to see if K exists
and the corresponding canvas exists on the page and run it for the other pages.
So for example this would be script.js:
function createSquare(k){
var c = document.getElementById("canvas[" + k + "]");
document.getElementById("shape[" + k + "]").innerHTML = "Square";
var ctx = c.getContext("2d");
var width = c.width;
var height = c.height;
//ctx.strokeRect(0, 0, 120, 120);
var n = hour2[k];
var z = 0;
var m = minute2[k];
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
var x = 0 + (i - 1) * width / n;
var y = 0 + (j - 1) * height / n;
ctx.beginPath();
ctx.rect(x, y, width / n, height / n);
ctx.fillStyle = "cyan"
if (z < m) {
ctx.fillRect(x, y, width / n, height / n);
z = z + 1;
}
ctx.stroke();
}
}
}
if(typeof k != "undefined" && document.getElementById("canvas[" + k + "]") != null){
createSquare(k);
}
Then to include it:
$.getScript('/path/to/imported/script.js',function(){
createSquare(k);
});
Related
I want to achieve something like an infinite drag like the one in Konva js Can anyone help me with this. I try varius things but non of them were ok. Im new in p5js and javascript. Please for any hints. Only this element prevents me from completing the entire project.
var grid;
var current_img;
var BgCat1 = [];
var layerOne;
let show_grid = false;
There may be a more elegant solution, but here I draw an extra cell on each side of the grid to handle the wraparound, so a 12x12 grid with 10x10 visible. See it run here: https://editor.p5js.org/rednoyz/full/uJCADfZXv
let dim = 10, sz;
let xoff = 0, yoff = 0;
function setup() {
createCanvas(400, 400);
sz = width/ dim;
}
function mouseDragged() {
xoff += mouseX - pmouseX;
yoff += mouseY - pmouseY;
}
function draw() {
background(255);
for (let i = 0; i < dim+2; i++) {
for (let j = 0; j < dim+2; j++) {
let x = ((xoff + j * sz) % (width+sz)) - sz;
if (x < -sz) x += width+sz;
let y = ((yoff + i * sz) % (height+sz)) - sz;
if (y < -sz) y += height+sz;
rect(x, y, sz, sz);
text(i * 10 + j, x + sz/2, y + sz/2);
}
}
}
I have been trying to implement Bradley Adaptive thresholding. I know there is a python code in one of the stack overflow questions. But i am struggling to implement the same in JS by following that. Can anyone please help me? So far my code is:
function computeAdaptiveThreshold (imagetest,imageWidth,imageHeight,callback)
{
var size = imageWidth*imageHeight*4;
var s = imageWidth/8;
var s2=s>>1;
var t=0.15;
var it=1.0-t;
var i,j,diff,x1,y1,x2,y2,ind1,ind2,ind3;
var sum=0;
var ind=0;
var integralImg = [];
var canvas = document.createElement('canvas');
var bin = canvas.getContext('2d').createImageData(imageWidth, imageHeight);
for(i=0;i<imageWidth;i++)
{
sum = 0;
for(j=0;j<imageHeight;j++)
{
index = i *imageHeight + j;
sum += imagetest.data[index];
if(i== 0)
{
integralImg[index] = sum;
}
else
{
//index = (i-1) * height + j;
integralImg[index] = integralImg[(i-1) * imageHeight + j] + sum;
}
}
}
x1=0;
for(i=1;i<imageWidth;++i)
{
sum=0;
ind=i;
ind3=ind-s2;
if(i>s)
{
x1=i-s;
}
diff=i-x1;
for(j=0;j<imageHeight;++j)
{
sum+=imagetest.data[ind];// & 0xFF;
integralImg[ind] = integralImg[(ind-1)]+sum;
ind+=imageWidth;
if(i<s2)continue;
if(j<s2)continue;
y1=(j<s ? 0 : j-s);
ind1=y1*imageWidth;
ind2=j*imageWidth;
if (((imagetest.data[ind3])*(diff * (j - y1))) < ((integralImg[(ind2 + i)] - integralImg[(ind1 + i)] - integralImg[(ind2 + x1)] + integralImg[(ind1 + x1)])*it)) {
bin.data[ind3] = 0;
} else {
bin.data[ind3] = 255;
}
ind3 += imageWidth;
}
}
y1 = 0;
for( j = 0; j < imageHeight; ++j )
{
i = 0;
y2 =imageHeight- 1;
if( j <imageHeight- s2 )
{
i = imageWidth - s2;
y2 = j + s2;
}
ind = j * imageWidth + i;
if( j > s2 ) y1 = j - s2;
ind1 = y1 * imageWidth;
ind2 = y2 * imageWidth;
diff = y2 - y1;
for( ; i < imageWidth; ++i, ++ind )
{
x1 = ( i < s2 ? 0 : i - s2);
x2 = i + s2;
// check the border
if (x2 >= imageWidth) x2 = imageWidth - 1;
if (((imagetest.data[ind])*((x2 - x1) * diff)) < ((integralImg[(ind2 + x2)] - integralImg[(ind1 + x2)] - integralImg[(ind2 + x1)] + integralImg[(ind1 + x1)])*it)) {
bin.data[ind] = 0;
} else {
bin.data[ind] = 255;
}
}
}
callback(bin);`
I am getting very bad images. I should say i cannot call it as a image.
I think your first effort should be to refactor your code : it will be much easier to handle the index.
Then you'll see that you have issues with your indexes : an image -even a gray one- is an RGBA Array, meaning 4 bytes = 32 bits per pixel.
You could handle this by doing a conversion RGBA-> b&W image, then thresholding, then doing b&w -> RGBA back.
...Or handle the RGBA components as you go. Notice that here you only want to output black or white, so you can create an Int32 view on the array, and write at once R,G,B,A for each pixels.
So some code (working here : http://jsfiddle.net/gamealchemist/3zuopz19/8/ ) :
function computeAdaptiveThreshold(sourceImageData, ratio, callback) {
var integral = buildIntegral_Gray(sourceImageData);
var width = sourceImageData.width;
var height = sourceImageData.height;
var s = width >> 4; // in fact it's s/2, but since we never use s...
var sourceData = sourceImageData.data;
var result = createImageData(width, height);
var resultData = result.data;
var resultData32 = new Uint32Array(resultData.buffer);
var x = 0,
y = 0,
lineIndex = 0;
for (y = 0; y < height; y++, lineIndex += width) {
for (x = 0; x < width; x++) {
var value = sourceData[(lineIndex + x) << 2];
var x1 = Math.max(x - s, 0);
var y1 = Math.max(y - s, 0);
var x2 = Math.min(x + s, width - 1);
var y2 = Math.min(y + s, height - 1);
var area = (x2 - x1 + 1) * (y2 - y1 + 1);
var localIntegral = getIntegralAt(integral, width, x1, y1, x2, y2);
if (value * area > localIntegral * ratio) {
resultData32[lineIndex + x] = 0xFFFFFFFF;
} else {
resultData32[lineIndex + x] = 0xFF000000;
}
}
}
return result;
}
function createImageData(width, height) {
var canvas = document.createElement('canvas');
return canvas.getContext('2d').createImageData(width, height);
}
function buildIntegral_Gray(sourceImageData) {
var sourceData = sourceImageData.data;
var width = sourceImageData.width;
var height = sourceImageData.height;
// should it be Int64 Array ??
// Sure for big images
var integral = new Int32Array(width * height)
// ... for loop
var x = 0,
y = 0,
lineIndex = 0,
sum = 0;
for (x = 0; x < width; x++) {
sum += sourceData[x << 2];
integral[x] = sum;
}
for (y = 1, lineIndex = width; y < height; y++, lineIndex += width) {
sum = 0;
for (x = 0; x < width; x++) {
sum += sourceData[(lineIndex + x) << 2];
integral[lineIndex + x] = integral[lineIndex - width + x] + sum;
}
}
return integral;
}
function getIntegralAt(integral, width, x1, y1, x2, y2) {
var result = integral[x2 + y2 * width];
if (y1 > 0) {
result -= integral[x2 + (y1 - 1) * width];
if (x1 > 0) {
result += integral[(x1 - 1) + (y1 - 1) * width];
}
}
if (x1 > 0) {
result -= integral[(x1 - 1) + (y2) * width];
}
return result;
}
I want an array looking like this:
[
[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0],
]
My first approach was to get the circumference
var steps = 100;
var coord = [];
var x,y;
for (var i = 0; i < steps; i++) {
var phase = 2 * Math.PI * i / steps;
x = Math.round(cenx + range * Math.cos(phase));
y = Math.round(ceny + range * Math.sin(phase))
if(x>=0 && y >=0){
coord.push([x,y]);
}
}
and with the resulting coords i could have juggled around to get the circular area. but i doubt that would be performant.
So my second approach would be to check every entry of the array whether it has a certain distance (i.e. radius) to the center of my circle. but for huge maps that wouldnt be performant either. perhaps checking only in a reasonable frame would be wiser.
but im certain there is a better approach for this problem.
im needing this for a fog of war implementation.
Your second suggested approach of testing each point in the array will be simple to implement, and can be optimized to just one subtract, one multiply and one test per element in the inner loop.
The basic test is ((x - centerX) * (x - centerX)) + ((y - centerY) * (y - centerY)) > radiusSq, but since ((y - centerY) * (y - centerY)) will be constant for a given row you can move that outside the loop.
Given that you have to visit each element in the array and set it anyway (meaning your algorithm will always be O(n2) on the circle radius), the test is a negligible cost:
// circle generation code:
function makeCircle(centerX, centerY, radius, a, arrayWidth, arrayHeight)
{
var x, y, d, yDiff, threshold, radiusSq;
radius = (radius * 2) + 1;
radiusSq = (radius * radius) / 4;
for(y = 0; y < arrayHeight; y++)
{
yDiff = y - centerY;
threshold = radiusSq - (yDiff * yDiff);
for(x = 0; x < arrayWidth; x++)
{
d = x - centerX;
a[y][x] = ((d * d) > threshold) ? 0 : 1;
}
}
}
// test code:
var width = 7;
var dim = (width * 2) + 1;
var array = new Array(dim);
for(row = 0; row < dim; row++)
array[row] = new Array(dim);
makeCircle(width, width, width, array, dim, dim);
for(var y = 0, s = ""; y < dim; y++)
{
for(var x = 0; x < dim; x++)
{
s += array[y][x];
}
s += "<br>";
}
document.body.innerHTML += s + "<br>";
I would use the mid-point circle algorithm and see the array as a bitmap.
I did this JavaScript implementation a while back, modified here to use an array as target source for the "pixel". Just note that a circle will produce odd widths and heights as the distance is always from a single center point and we can only use integer values in this case.
Tip: For speed improvements you could use typed array instead of a regular one (shown below).
Example
Make sure to use integer values as input, the code will clip values outside the "bitmap"/array -
var width = 7, height = 7,
array = new Uint8Array(width * height);
// "draw" circle into array
circle(3, 3, 3);
renderDOM();
// circle example 2
width = height = 17;
array = new Uint8Array(width * height);
circle(8, 8, 8);
renderDOM();
function circle(xc, yc, r) {
if (r < 1) return;
var x = r, y = 0, // for Bresenham / mid-point circle
cd = 0,
xoff = 0,
yoff = r,
b = -r,
p0, p1, w0, w1;
while (xoff <= yoff) {
p0 = xc - xoff;
p1 = xc - yoff;
w0 = xoff + xoff;
w1 = yoff + yoff;
hl(p0, yc - yoff, yc + yoff, w0); // fill a "line"
hl(p1, yc - xoff, yc + xoff, w1);
if ((b += xoff+++xoff) >= 0) {
b -= --yoff + yoff;
}
}
// for fill
function hl(x, y1, y2, w) {
w++;
var xw = 0;
while (w--) {
xw = x + w;
setPixel(xw, y1);
setPixel(xw, y2);
}
}
function setPixel(x, y) {
if (x < width && y < height && x >= 0 && y >= 0)
array[y * width + x] = 1;
}
}
function renderDOM() {
for(var i = 0, str = ""; i < array.length; i++) {
if (i > 0 && !(i % width)) str += "<br>";
str += array[i];
}
document.body.innerHTML += str + "<br><br>";
}
body {font:18px monospace}
For an odd-sized array (2r+1 x 2r+1),
for (row= 0; row < 2 * r + 1; row++)
{
f= (row + 1) * (row - 2 * r - 1) + r * r + r;
for (col= 0; col < 2 * r + 1; f+= 2 * (col - r) + 1; col++)
{
array[row][col]= f >= 0;
}
}
I'm creating an algorithm that will blur the border of a canvas(image). Before applying the blur effect, I am creating an array filtered that includes all pixel values that needs to be blurred.
I've created an example with a 10×10px image.
function compute(w, h, bW) {
w *= 4;
var ignored = [];
for (y = bW; y < (h - bW); y++) {
for (x = 0; x < (w - (bW * 4 * 2)); x++) {
ignored.push(w * y + x + bW * 4);
}
}
console.log(ignored);
function range(limit) {
return Array.apply(null, Array(limit)).map(function(_, i) {
return i;
})
}
Array.prototype.diff = function(array) {
return this.filter(function(elem) {
return array.indexOf(elem) === -1;
})
}
var filtered = range(w * h).diff(ignored);
console.log(filtered);
return filtered;
}
compute(10, 10, 2);
//////////////////////////////////////////////////////////////////
// Below is just to display the numbers that are being filtered //
// Here, the size is 100 x 100 px with 10px border width //
//////////////////////////////////////////////////////////////////
var pixels = compute(100, 100, 10);
var c = document.getElementsByTagName('canvas')[0];
var ctx = c.getContext('2d');
var imgD = ctx.createImageData(100, 100);
for (var i = 0; i < imgD.data.length; i += 4) {
if (pixels.indexOf(i) > 0) {
imgD.data[i + 0] = 0;
imgD.data[i + 1] = 0;
imgD.data[i + 2] = 0;
imgD.data[i + 3] = 255;
} else {
imgD.data[i + 0] = 255;
imgD.data[i + 1] = 0;
imgD.data[i + 2] = 0;
imgD.data[i + 3] = 255;
}
}
ctx.putImageData(imgD, 10, 10);
<canvas></canvas>
The array filtered contains all the numbers that has the background color and ignored contains all the numbers that has the background color and in the image.
My question is:
How do I change my code so that the array filtered will have the numbers with background color and and not ?
An Example on a bit high resolution(65×65px):
FIDDLEJS : http://jsfiddle.net/t14gr6pL/2/
Explanation:
It depends on the width of your triangles (the second color). In the 64*64 example, this width is 7.
Let's assume that this width (tw) is calculate like this (you can change) :
var tw = (2 * bW) - 1;
So your code would be:
function compute(w, h, bW) {
var filtered = [];
var WIDTH_MULTIPLICATOR = 4;
var bH = bW;
w *= WIDTH_MULTIPLICATOR;
bW *= WIDTH_MULTIPLICATOR;
var triangleWidth = (2 * bW) - 1;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
if (
// Borders
(Math.min(x, w - x) < bW) ||
(Math.min(y, h - y) < bH) ||
// Adding "Triangles"
(Math.min(x, w - x) < bW + triangleWidth - Math.max(0, Math.min(y, h - y) - bH) * WIDTH_MULTIPLICATOR)
) {
filtered.push(w * y + x);
}
}
}
return filtered;
}
How can I draw around 50000 particles in a browser and then just stop, I know how to create unending animations of particles, but how can I create one that once its done drawing the particles it just stops.
Edit
So essintially I want to time the drawing of the particles, however when i attack a timer, it doesnt get the change because the animation doesnt stop.
var scene = new Scene(),
particles = [],
len = 40000,
height = document.body.offsetHeight,
width = document.body.offsetWidth;
function Particle() {
this.x = 0;
this.y = 0;
this.size = 0;
this.depth = 0;
this.vy = 0;
}
Particle.prototype = {
constructor: Particle,
update: function (width, height) {
if (this.y > height) {
this.y = 1 - this.size;
}
this.y += this.vy;
}
};
for (var i = 0; i < len; i++) {
var particle = new Particle();
particle.x = Math.random() * width;
particle.y = Math.random() * height;
particle.depth = Math.random() * 10 | 0;
particle.size = (particle.depth + 1) / 8;
particle.vy = (particle.depth * .25) + 1 / Math.random();
particles.push(particle);
}
function falling_particles(scene) {
for (var i = 0, l = particles.length; i < l; i++) {
var particle = particles[i];
for (var w = 0; w < particle.size; w++) {
for (var h = 0; h < particle.size; h++) {
var pData = (~~(particle.x + w) + (~~(particle.y + h) * scene.width)) * 4;
scene.idata.data[pData] = 255;
scene.idata.data[pData + 1] = 255;
scene.idata.data[pData + 2] = 255;
scene.idata.data[pData + 3] = 255;
}
}
particle.update(scene.width, scene.height);
}
return scene.idata;
}
scene.setup(document.getElementById('canvas'), falling_particles, width, height, !0);
scene.animate();
window.onresize = function () {
height = scene.height = scene.canvas.height = document.body.offsetHeight;
width = scene.width = scene.canvas.width = document.body.offsetWidth;
};
link here: http://jsfiddle.net/MdSP4/
I'm not sure, what exactly you want to do, but if you add
setTimeout(function(){
scene.paused = true;
},1000);
Then all the drawing will stop after a second.