Removing mouse controls from Javascript code - javascript

I have a large piece of code that draws feather-looking designs controlled by the mouse. This is using mouse pressed and mouseX, mouseY.
I would like the code to run and draw the feathers without the mouse being involved (ie. opening the canvas and having feathers automatically draw on the screen).
The full code is below:
var points = [];
var painting = false;
var strokeNumber = 0;
var scl = 6;
var cols, rows;
var inc = 0.1;
var zOff = 0;
var particles = [];
var flowField = [];
var saturation = [];
function setup() {
createCanvas(windowWidth, windowHeight);
// createCanvas(400, 400);
pixelDensity(5);
background(0);
cols = floor(width / scl);
rows = floor(height / scl);
flowField = Array(cols * rows);
saturation = Array(width * height).fill(0);
greateForceField();
}
function mousePressed() {
painting = true;
strokeNumber++;
}
function mouseReleased() {
painting = false;
}
function updateForceField(){
var v = createVector(mouseX, mouseY);
var vPrev = createVector(pmouseX, pmouseY);
v.sub(vPrev);
v.setMag(1);
var i = floor(mouseX / scl);
var j = floor(mouseY / scl);
var index = i * rows + j;
flowField[index] = v;
}
function showForceField(){
for(var i = 0; i < cols; i++){
for(var j = 0; j < rows; j++){
var index = i * rows + j;
var v = flowField[index];
stroke(0,50);
strokeWeight(1);
push();
translate(i * scl, j * scl);
rotate(v.heading());
line(0,0,scl,0);
pop();
}
}
}
function greateForceField(){
var xOff = 0;
for(var i = 0; i < cols; i++){
var yOff = 0;
for(var j = 0; j < rows; j++){
yOff += inc;
var angle = noise(xOff, yOff, zOff) * TWO_PI;
var v = p5.Vector.fromAngle(angle);
v.setMag(.1);
var index = i * rows + j;
flowField[index] = v;
}
xOff += inc;
}
// zOff += inc * 0.1;
}
function draw() {
// background(255);
// showForceField();
if(painting){
updateForceField();
var idx = mouseY * width + mouseX;
if(saturation[idx] < 10){
var r = 1+sqrt(sq(mouseX-pmouseX)+sq(mouseY-pmouseY));
for(var a = 0; a < 100; a++){
var particle = new Particle(mouseX+random()*r*cos(random(TWO_PI)), mouseY+random()*r*sin(random(TWO_PI)));
particles.push(particle);
}
saturation[idx] ++;
}
}
particles.filter(particle => particle.spread > 0).map(particle => {
particle.update();
particle.show();
// particle.edges();
particle.follow();
})
particles.map((particle, idx) => {
if(particle.spread <= 0){
particles.splice(idx,1);
}
});
}
function Particle(x,y){
this.pos = createVector(x,y);
// this.color = color(245, 225, 50);
// this.color = color(145, 225, 192);
this.color = color(255);
this.spread = 127;
this.spreadInc = this.spread/100;
this.prevPos = this.pos.copy();
this.vel = p5.Vector.random2D();
this.acc = createVector(0,0);
this.maxSpeed = 2;
this.update = function(){
this.spread -= this.spreadInc;
this.vel.add(this.acc);
this.vel.limit(this.maxSpeed);
this.pos.add(this.vel);
this.acc.mult(0);
}
this.applyForce = function(force){
this.acc.add(force);
}
this.follow = function(){
var i = floor(this.pos.x / scl);
var j = floor(this.pos.y / scl);
var index = i * rows + j;
var force = flowField[index];
this.applyForce(force);
}
this.show = function(){
stroke(red(this.color),green(this.color),blue(this.color),this.spread);
strokeWeight(.3*this.spread/127);
// point(this.pos.x, this.pos.y);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.updatePrev();
}
this.updatePrev = function(){
this.prevPos = this.pos.copy();
}
this.edges = function(){
if(this.pos.x > width) {
this.pos.x = 0;
this.updatePrev();
}
if(this.pos.x < 0){
this.pos.x = width;
this.updatePrev();
}
if(this.pos.y > height){
this.pos.y = 0;
this.updatePrev();
}
if(this.pos.y < 0) {
this.pos.y = height;
this.updatePrev();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

Use 4 variables current_x, current_y, prev_x and prev_y instead of mosueX, mouseY, pmouseX and pmouseY.
var current_x=0, current_y=0, prev_x=0, prev_y=0;
function updateForceField(){
var v = createVector(current_x, current_y);
var vPrev = createVector(prev_x, prev_y);
v.sub(vPrev);
v.setMag(1);
var i = floor(current_x / scl);
var j = floor(current_y / scl);
var index = i * rows + j;
flowField[index] = v;
}
Instead of the state painting use a time interval. The time between 2 frames can be get from the built-in variable deltaTime (in milliseconds). Set the x and y positions by random values. e.g.:
var interval = 200; // 200 milliseconds
var sum_time = 0;
function draw() {
sum_time += deltaTime;
if(sum_time > interval){
sum_time = 0;
current_x = Math.floor(random(width));
current_y = Math.floor(random(height));
updateForceField();
prev_x = current_x;
prev_y = current_y;
var idx = current_y * width + current_x;
if(saturation[idx] < 10){
var r = 1+sqrt(sq(current_x-prev_x)+sq(current_y-prev_y));
for(var a = 0; a < 100; a++){
var particle = new Particle(current_x+random()*r*cos(random(TWO_PI)), current_y+random()*r*sin(random(TWO_PI)));
particles.push(particle);
}
saturation[idx] ++;
}
}
// [...]
}
See the example:
var points = [];
var painting = false;
var strokeNumber = 0;
var scl = 6;
var cols, rows;
var inc = 0.1;
var zOff = 0;
var particles = [];
var flowField = [];
var saturation = [];
function setup() {
//createCanvas(windowWidth, windowHeight);
createCanvas(500, 200);
pixelDensity(5);
background(0);
cols = floor(width / scl);
rows = floor(height / scl);
flowField = Array(cols * rows);
saturation = Array(width * height).fill(0);
greateForceField();
}
function mousePressed() {
painting = true;
strokeNumber++;
}
function mouseReleased() {
painting = false;
}
var current_x=0, current_y=0, prev_x=0, prev_y=0;
function updateForceField(){
var v = createVector(current_x, current_y);
var vPrev = createVector(prev_x, prev_y);
v.sub(vPrev);
v.setMag(1);
var i = floor(current_x / scl);
var j = floor(current_y / scl);
var index = i * rows + j;
flowField[index] = v;
}
function showForceField(){
for(var i = 0; i < cols; i++){
for(var j = 0; j < rows; j++){
var index = i * rows + j;
var v = flowField[index];
stroke(0,50);
strokeWeight(1);
push();
translate(i * scl, j * scl);
rotate(v.heading());
line(0,0,scl,0);
pop();
}
}
}
function greateForceField(){
var xOff = 0;
for(var i = 0; i < cols; i++){
var yOff = 0;
for(var j = 0; j < rows; j++){
yOff += inc;
var angle = noise(xOff, yOff, zOff) * TWO_PI;
var v = p5.Vector.fromAngle(angle);
v.setMag(.1);
var index = i * rows + j;
flowField[index] = v;
}
xOff += inc;
}
// zOff += inc * 0.1;
}
var interval = 200; // 200 milliseconds
var sum_time = 0;
function draw() {
// background(255);
// showForceField();
sum_time += deltaTime;
if(sum_time > interval){
sum_time = 0;
current_x = Math.floor(random(width));
current_y = Math.floor(random(height));
updateForceField();
prev_x = current_x;
prev_y = current_y;
var idx = current_y * width + current_x;
if(saturation[idx] < 10){
var r = 1+sqrt(sq(current_x-prev_x)+sq(current_y-prev_y));
for(var a = 0; a < 100; a++){
var particle = new Particle(current_x+random()*r*cos(random(TWO_PI)), current_y+random()*r*sin(random(TWO_PI)));
particles.push(particle);
}
saturation[idx] ++;
}
}
particles.filter(particle => particle.spread > 0).map(particle => {
particle.update();
particle.show();
// particle.edges();
particle.follow();
})
particles.map((particle, idx) => {
if(particle.spread <= 0){
particles.splice(idx,1);
}
});
}
function Particle(x,y){
this.pos = createVector(x,y);
// this.color = color(245, 225, 50);
// this.color = color(145, 225, 192);
this.color = color(255);
this.spread = 127;
this.spreadInc = this.spread/100;
this.prevPos = this.pos.copy();
this.vel = p5.Vector.random2D();
this.acc = createVector(0,0);
this.maxSpeed = 2;
this.update = function(){
this.spread -= this.spreadInc;
this.vel.add(this.acc);
this.vel.limit(this.maxSpeed);
this.pos.add(this.vel);
this.acc.mult(0);
}
this.applyForce = function(force){
this.acc.add(force);
}
this.follow = function(){
var i = floor(this.pos.x / scl);
var j = floor(this.pos.y / scl);
var index = i * rows + j;
var force = flowField[index];
this.applyForce(force);
}
this.show = function(){
stroke(red(this.color),green(this.color),blue(this.color),this.spread);
strokeWeight(.3*this.spread/127);
// point(this.pos.x, this.pos.y);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.updatePrev();
}
this.updatePrev = function(){
this.prevPos = this.pos.copy();
}
this.edges = function(){
if(this.pos.x > width) {
this.pos.x = 0;
this.updatePrev();
}
if(this.pos.x < 0){
this.pos.x = width;
this.updatePrev();
}
if(this.pos.y > height){
this.pos.y = 0;
this.updatePrev();
}
if(this.pos.y < 0) {
this.pos.y = height;
this.updatePrev();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

Related

Need help optimizing my Javascript for canvas rendering

I've written this quick script for random moving lines for the background for my portfolio. It works smoothly alone but when I start working with other CSS animations and stuff, there's a frame drop at the beginning (later it runs smooth). At least on my PC, struggles on low-end PC.
Some tips to optimize it would be helpful.
Here's my code:
/*Random Line Render Script aka Mini Browser Crasher */
/*XD Can't Revise This Script. Rofl Drains Memory. May crash low-end pc :V */
var c = document.getElementById("graph");
var dimension = [document.documentElement.clientWidth, document.documentElement.clientHeight];
c.width = dimension[0];
var ctx = c.getContext("2d");
var ctx2 = c.getContext("2d");
var posx = [100, 200, 150, 100, 0];
var posy = [100, 200, 300, 100, -100];
var posx2 = [600, 400, 200, 600];
var posy2 = [500, 200, 100, 150, 500, 500];
var posx3 = [];
var posy3 = [];
/*Generate random values for array( random starting point ) */
for (var i = 0; i < 2; i++) {
posx2.push(500 + Math.round(Math.random() * 700));
posy2.push(Math.round(Math.random() * 900));
}
for (var i = 0; i < 5; i++) {
posx3.push(1000 + Math.round(Math.random() * 300));
posy3.push(0 + Math.round(Math.random() * 1000));
}
var posx_len = posx.length;
var posx2_len = posx2.length;
var posx3_len = posx3.length;
var xa, ya;
var opa = 1;
var amount = 0.01;
var sinang = 0;
var distance1 = 0;
var distance2 = 0;
document.body.addEventListener('mousemove', (function(event) {
xa = event.clientX;
ya = event.clientY;
}));
/*Render Lines */
function draw() {
ctx.clearRect(0, 0, 10000, 10000);
ctx.beginPath();
ctx.moveTo(posx[0], posy[0]);
for (var i = 0; i < posx_len; i++) {
ctx.lineTo(posx[i], posy[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx[i], posy[i], 5, 0, 2 * Math.PI, false);
}
if (opa > 1) {
amount = -0.01 * Math.random();
}
if (opa < 0) {
amount = 0.01 * Math.random();
}
opa = opa + amount;
ctx.moveTo(posx2[0], posy2[0]);
for (var i = 0; i < posx2_len; i++) {
ctx.lineTo(posx2[i], posy2[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx2[i], posy2[i], 5, 0, 2 * Math.PI, false);
}
ctx.moveTo(posx3[0], posy3[0]);
for (var i = 0; i < posx3_len; i++) {
ctx.lineTo(posx3[i], posy3[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx3[i], posy3[i], 5, 0, 2 * Math.PI, false);
}
sinang = sinang + 0.01;
/*Frame Render Ends here*/
/*Calculation for next frame*/
for (var i = 0; i < posx_len; i++) {
posx[i] = posx[i] + (Math.cos(sinang) * i) / 2; /* Sin curve for smooth value transition. Smooth assss Butter */
posy[i] = posy[i] + (Math.cos(sinang) * i) / 2;
/* Can't believe Distance Formula is useful ahaha */
distance1 = Math.sqrt(Math.pow((posx[i] - xa), 2) + Math.pow((posy[i] - ya), 2));
if (distance1 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(xa, ya);
}
for (var j = 0; j < posx2_len; j++) {
distance12 = Math.sqrt(Math.pow((posx[i] - posx2[j]), 2) + Math.pow((posy[i] - posy2[j]), 2));
if (distance12 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(posx2[j], posy2[j]);
}
}
for (var j = 0; j < posx3_len; j++) {
distance13 = Math.sqrt(Math.pow((posx[i] - posx3[j]), 2) + Math.pow((posy[i] - posy3[j]), 2));
if (distance13 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx[posx.length - 1] = posx[0];
posy[posy.length - 1] = posy[0];
/*Repeat Above Steps. Should have done this in Multi-dimensional array. Ugh I feel sad now*/
for (var i = 0; i < posx2_len; i++) {
posx2[i] = posx2[i] + (Math.sin(sinang) * i) / 2;
posy2[i] = posy2[i] - (Math.sin(sinang) * i) / 2;
distance2 = Math.sqrt(Math.pow((posx2[i] - xa), 2) + Math.pow((posy2[i] - ya), 2));
if (distance2 <= 500) {
ctx.moveTo(posx2[i], posy2[i]);
ctx.lineTo(xa, ya);
}
for (var j = 0; j < posx3_len; j++) {
distance22 = Math.sqrt(Math.pow((posx2[i] - posx3[j]), 2) + Math.pow((posy2[i] - posy3[j]), 2));
if (distance22 <= 500) {
ctx.moveTo(posx2[i], posy2[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx2[posx2.length - 1] = posx2[0];
posy2[posy2.length - 1] = posy2[0];
for (var i = 0; i < posx3_len; i++) {
posx3[i] = posx3[i] - (Math.sin(sinang) * i) / 1.2;
posy3[i] = posy3[i] - (Math.sin(sinang) * i) / 1.2;
distance2 = Math.sqrt(Math.pow((posx3[i] - xa), 2) + Math.pow((posy3[i] - ya), 2));
if (distance2 <= 500) {
ctx.moveTo(posx3[i], posy3[i]);
ctx.lineTo(xa, ya);
}
}
posx3[posx3.length - 1] = posx3[0];
posy3[posy3.length - 1] = posy3[0];
ctx.restore();
ctx.stroke();
window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);
body {
background: #1f1f1f;
}
<canvas height="1080px" width="1100px" id="graph">
</canvas>
So, what I've done is used square colliders instead of circular(distance formula) and it has faster runtime now. (not much but still)
<html>
<head>
</head>
<style>
body{
background: #1f1f1f;
}
canvas{
}
</style>
<body >
<canvas height="1080px" width="1100px" id="graph">
</canvas>
</body>
<script>
/*Random Line Render Script aka Mini Browser Crasher */
/*XD Can't Revise This Script. Rofl Drains Memory. May crash low-end pc :V */
var c = document.getElementById("graph");
var dimension = [document.documentElement.clientWidth, document.documentElement.clientHeight];
c.width = dimension[0];
var ctx = c.getContext("2d");
var posx = [100,200,150,100,0];
var posy = [100,200,300,100,-100];
var posx2 = [600,400,200,600];
var posy2 = [500,200,100,150,500,500];
var posx3 = [];
var posy3 = [];
/*Generate random values for array( random starting point ) */
for(var i=0; i<2;i++){
posx2.push(500+Math.round(Math.random()*700));
posy2.push(Math.round(Math.random()*900));
}
for(var i=0; i<5;i++){
posx3.push(1000+Math.round(Math.random()*300));
posy3.push(0+Math.round(Math.random()*1000));
}
var posx_len = posx.length;
var posx2_len = posx2.length;
var posx3_len = posx3.length;
var xa,ya;
var opa =1;
var amount = 0.01;
var sinang = 0;
var distance1 = 0;
var distance2 = 0;
var t1, t2;
document.body.addEventListener('mousemove', (function (event) {
xa = event.clientX;
ya = event.clientY;
}));
/*Render Lines */
function draw(){
t1 =performance.now();
ctx.clearRect(0, 0, 1920,1080);
ctx.beginPath();
ctx.moveTo(posx[0], posy[0]);
for(var i= 0; i<posx_len;i++){
ctx.lineTo(posx[i], posy[i]);
ctx.arc(posx[i],posy[i], 5, 0, 2 * Math.PI, false);
}
if(opa>1){
amount = -0.01*Math.random();
}
if(opa<0){
amount =0.01*Math.random();
}
opa =opa +amount;
ctx.moveTo(posx2[0], posy2[0]);
for(var i = 0; i<posx2_len;i++){
ctx.lineTo(posx2[i], posy2[i]);
ctx.arc(posx2[i],posy2[i], 5, 0, 2 * Math.PI, false);
}
ctx.moveTo(posx3[0], posy3[0]);
for(var i = 0; i<posx3_len;i++){
ctx.lineTo(posx3[i], posy3[i]);
ctx.arc(posx3[i],posy3[i], 5, 0, 2 * Math.PI, false);
}
sinang = sinang+0.01;
/*Frame Render Ends here*/
/*Calculation for next frame*/
for(var i = 0;i<posx_len;i++){
posx[i] = posx[i]+ (Math.cos(sinang)*i)/2;/* Sin curve for smooth value transition. Smooth assss Butter */
posy[i] = posy[i]+ (Math.cos(sinang)*i)/2;
/* Can't believe Distance Formula is useful ahaha */
if(Math.abs(posx[i]-xa)<500 && Math.abs(posy[i]-ya)<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(xa, ya);
}
for(var j = 0;j<posx2_len;j++){
if(Math.abs(posx[i]-posx2[j])<500 && Math.abs(posy[i]-posy2[j])<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(posx2[j], posy2[j]);
}
}
for(var j = 0;j<posx3_len;j++){
if(Math.abs(posx[i]-posx3[j])<500 && Math.abs(posy[i]-posy3[j])<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx[posx.length-1]=posx[0];
posy[posy.length-1] = posy[0];
/*Repeat Above Steps. Should have done this in Multi-dimensional array. Ugh I feel sad now*/
for(var i = 0;i<posx2_len;i++){
posx2[i] = posx2[i]+ (Math.sin(sinang)*i)/2;
posy2[i] = posy2[i]-(Math.sin(sinang)*i)/2;
if(Math.abs(posx2[i]-xa)<500 && Math.abs(posy2[i]-ya)<500){
ctx.moveTo(posx2[i],posy2[i]);
ctx.lineTo(xa, ya);
}
for(var j = 0;j<posx3_len;j++){
if(Math.abs(posx2[i]-posx3[j])<500 && Math.abs(posy2[i]-posy3[j])<500){
ctx.moveTo(posx2[i],posy2[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx2[posx2.length-1]=posx2[0];
posy2[posy2.length-1] = posy2[0];
for(var i = 0;i<posx3_len;i++){
posx3[i] = posx3[i]- (Math.sin(sinang)*i)/1.2;
posy3[i] = posy3[i]-(Math.sin(sinang)*i)/1.2;
if(Math.abs(posx3[i]-xa)<500 && Math.abs(posy3[i]-ya)<500){
ctx.moveTo(posx3[i],posy3[i]);
ctx.lineTo(xa, ya);
}
}
posx3[posx3.length-1]=posx3[0];
posy3[posy3.length-1] = posy3[0];
ctx.restore();
ctx.strokeStyle = 'rgba(255,255,255,'+opa+')';
ctx.stroke();
window.requestAnimationFrame(draw);
t2=performance.now();
console.log(t2-t1);
}
window.requestAnimationFrame(draw);
</script>
</html>

p5.js within html not working (Using instantiation)

Im trying to implement this p5.js code within a html/css flexbox and it isn't working. I know that it needs p. before many of the lines of code, but I am not sure where. Ive done it in the past and it has worked, but not on this scale. Can anyone help?
var phase, speed, maxCircleSize, numRows, numCols, numStrands, colorA, colorB;
var sketch4 = function (p) {
p.setup = function() {
p.createCanvas(500, 500);
p.noStroke();
phase = 0;
speed = 0.03;
maxCircleSize = 20;
numRows = 10;
numCols = 16;
numStrands = 2;
colorA = p.color(253, 174, 120);
colorB = p.color(226, 129, 161);
}
draw = function() {
p.background(4, 58, 74);
phase = frameCount * speed;
for (var strand = 0; strand < numStrands; strand += 1) {
var strandPhase = phase + map(strand, 0, numStrands, 0, TWO_PI);
for (var col = 0; col < numCols; col += 1) {
var colOffset = map(col, 0, numCols, 0, TWO_PI);
var x = map(col, 0, numCols, 50, width - 50);
for (var row = 0; row < numRows; row += 1) {
var y = height / 2 + row * 10 + sin(strandPhase + colOffset) * 50;
var sizeOffset =
(cos(strandPhase - row / numRows + colOffset) + 1) * 0.5;
var circleSize = sizeOffset * maxCircleSize;
p.fill(p.lerpColor(colorA, colorB, row / numRows));
p.ellipse(x, y, circleSize, circleSize);
}
}
}
}
};
let node4 = document.createElement('div');
window.document.getElementById('p5-3').appendChild(node4);
new p5(sketch4, node4);
Here is an example of one that works fine:
var sketch3 = function(p) {
p.setup = function() {
p.createCanvas(100, 100, p.WEBGL);
};
p.draw = function() {
p.background("#A9927D");
p.rotateZ(p.frameCount * 0.01);
p.rotateX(p.frameCount * 0.01);
p.rotateY(p.frameCount * 0.01);
p.normalMaterial()
p.cone(25, 25);
};
};
let node3 = document.createElement('div');
window.document.getElementById('p5-3').appendChild(node3);
new p5(sketch3, node3);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<div id="p5-3"></div>
So many little things missing, but mainly p. everywhere.
var phase, speed, maxCircleSize, numRows, numCols, numStrands, colorA, colorB;
var sketch4 = function (p) {
p.setup = function() {
p.createCanvas(500, 500);
p.noStroke();
phase = 0;
speed = 0.03;
maxCircleSize = 20;
numRows = 10;
numCols = 16;
numStrands = 2;
colorA = p.color(253, 174, 120);
colorB = p.color(226, 129, 161);
};
p.draw = function() { // [HERE]
p.background(4, 58, 74);
phase = p.frameCount * speed; // [HERE]
for (var strand = 0; strand < numStrands; strand += 1) {
var strandPhase = phase + p.map(strand, 0, numStrands, 0, p.TWO_PI); // [HERE]
for (var col = 0; col < numCols; col += 1) {
var colOffset = p.map(col, 0, numCols, 0, p.TWO_PI); // [HERE]
var x = p.map(col, 0, numCols, 50, p.width - 50); // [HERE]
for (var row = 0; row < numRows; row += 1) {
var y = p.height / 4 + row * 10 + p.sin(strandPhase + colOffset) * 50; // [HERE]
var sizeOffset =
(p.cos(strandPhase - row / numRows + colOffset) + 1) * 0.5; // [HERE]
var circleSize = sizeOffset * maxCircleSize;
p.fill(p.lerpColor(colorA, colorB, row / numRows));
p.ellipse(x, y, circleSize, circleSize);
}
}
}
};
};
let node4 = document.createElement('div');
window.document.getElementById('p5-3').appendChild(node4);
new p5(sketch4, node4);
body {
background-color:#e9e9e9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<div id="p5-3"></div>
Or using the with statement for less Psss.
var phase, speed, maxCircleSize, numRows, numCols, numStrands, colorA, colorB;
var sketch4 = function (p) {
with(p) { // [HERE]
p.setup = function() {
createCanvas(500, 500);
noStroke();
phase = 0;
speed = 0.03;
maxCircleSize = 20;
numRows = 10;
numCols = 16;
numStrands = 2;
colorA = p.color(253, 174, 120);
colorB = p.color(226, 129, 161);
};
p.draw = function() {
background(4, 58, 74);
phase = frameCount * speed;
for (var strand = 0; strand < numStrands; strand += 1) {
var strandPhase = phase + map(strand, 0, numStrands, 0, TWO_PI);
for (var col = 0; col < numCols; col += 1) {
var colOffset = map(col, 0, numCols, 0, TWO_PI);
var x = map(col, 0, numCols, 50, width - 50);
for (var row = 0; row < numRows; row += 1) {
var y = height / 4 + row * 10 + sin(strandPhase + colOffset) * 50;
var sizeOffset =
(cos(strandPhase - row / numRows + colOffset) + 1) * 0.5;
var circleSize = sizeOffset * maxCircleSize;
fill(lerpColor(colorA, colorB, row / numRows));
ellipse(x, y, circleSize, circleSize);
}
}
}
};
}
};
let node4 = document.createElement('div');
window.document.getElementById('p5-3').appendChild(node4);
new p5(sketch4, node4);
body {
background-color:#e9e9e9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<div id="p5-3"></div>

Fix particle system errors in processing

I'm trying to set up a feather-looking particle system in processing. I am trying to base it off of some code I found on OpenProcessing. When I copy and paste the code into processing (using Java) I get an error saying "expecting SEMI, found 'points'.
I figured this was maybe because the code uses var and not int indicating that this would be Javascript code instead. So I switched the processing mode to p5.js, and it runs but the browser that opens is just a blank white screen.
Any help on getting this to run would be appreciated! Thanks!
The code is below:
var points = [];
var painting = false;
var strokeNumber = 0;
var scl = 6;
var cols, rows;
var inc = 0.1;
var zOff = 0;
var particles = [];
var flowField = [];
var saturation = [];
function setup() {
createCanvas(windowWidth, windowHeight);
// createCanvas(400, 400);
background(0);
pixelDensity(5);
cols = floor(width / scl);
rows = floor(height / scl);
flowField = Array(cols * rows);
saturation = Array(width * height).fill(0);
greateForceField();
}
function mousePressed() {
painting = true;
strokeNumber++;
}
function mouseReleased() {
painting = false;
}
function updateForceField(){
var v = createVector(mouseX, mouseY);
var vPrev = createVector(pmouseX, pmouseY);
v.sub(vPrev);
v.setMag(1);
var i = floor(mouseX / scl);
var j = floor(mouseY / scl);
var index = i * rows + j;
flowField[index] = v;
}
function showForceField(){
for(var i = 0; i < cols; i++){
for(var j = 0; j < rows; j++){
var index = i * rows + j;
var v = flowField[index];
stroke(0,50);
strokeWeight(1);
push();
translate(i * scl, j * scl);
rotate(v.heading());
line(0,0,scl,0);
pop();
}
}
}
function greateForceField(){
var xOff = 0;
for(var i = 0; i < cols; i++){
var yOff = 0;
for(var j = 0; j < rows; j++){
yOff += inc;
var angle = noise(xOff, yOff, zOff) * TWO_PI;
var v = p5.Vector.fromAngle(angle);
v.setMag(.1);
var index = i * rows + j;
flowField[index] = v;
}
xOff += inc;
}
// zOff += inc * 0.1;
}
function draw() {
// background(255);
// showForceField();
if(painting){
updateForceField();
var idx = mouseY * width + mouseX;
if(saturation[idx] < 10){
var r = 1+sqrt(sq(mouseX-pmouseX)+sq(mouseY-pmouseY));
for(var a = 0; a < 100; a++){
var particle = new Particle(mouseX+random()*r*cos(random(TWO_PI)), mouseY+random()*r*sin(random(TWO_PI)));
particles.push(particle);
}
saturation[idx] ++;
}
}
particles.filter(particle => particle.spread > 0).map(particle => {
particle.update();
particle.show();
// particle.edges();
particle.follow();
})
particles.map((particle, idx) => {
if(particle.spread <= 0){
particles.splice(idx,1);
}
});
}
function Particle(x,y){
this.pos = createVector(x,y);
// this.color = color(245, 225, 50);
// this.color = color(145, 225, 192);
this.color = color(255);
this.spread = 127;
this.spreadInc = this.spread/100;
this.prevPos = this.pos.copy();
this.vel = p5.Vector.random2D();
this.acc = createVector(0,0);
this.maxSpeed = 2;
this.update = function(){
this.spread -= this.spreadInc;
this.vel.add(this.acc);
this.vel.limit(this.maxSpeed);
this.pos.add(this.vel);
this.acc.mult(0);
}
this.applyForce = function(force){
this.acc.add(force);
}
this.follow = function(){
var i = floor(this.pos.x / scl);
var j = floor(this.pos.y / scl);
var index = i * rows + j;
var force = flowField[index];
this.applyForce(force);
}
this.show = function(){
stroke(red(this.color),green(this.color),blue(this.color),this.spread);
strokeWeight(.3*this.spread/127);
// point(this.pos.x, this.pos.y);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.updatePrev();
}
this.updatePrev = function(){
this.prevPos = this.pos.copy();
}
this.edges = function(){
if(this.pos.x > width) {
this.pos.x = 0;
this.updatePrev();
}
if(this.pos.x < 0){
this.pos.x = width;
this.updatePrev();
}
if(this.pos.y > height){
this.pos.y = 0;
this.updatePrev();
}
if(this.pos.y < 0) {
this.pos.y = height;
this.updatePrev();
}
}
}
This looks like javascript waaay more than java. I'm not exactly a buff in these matters, but... are you trying to run javascript as java?
If you are using the Processing IDE, look in the upper right corner. Do you see the word "Java" ?
Like this:
If this is the case, you might want to consider installing p5.js :
Click here and choose "Add mode":
Now search for p5.js and install it:
Now your code will compile. I'm not saying it'll work, though, but your current problem will be behind you. Have fun!

graphs in canvas html5 [duplicate]

I'm new to html5 and trying to display an array of code in a graph. It works for a line graph but for some reason unknown to me not for an exponential one. this my code.
My question is, is there a fault in the code that would break the graph?(i'm sure there's a metric ton of mistakes in the code).
I also got a lot of my code here.
thanks in advance for any help I receive.
<canvas id="graph5" width="400" height="300"></canvas>
function generateTestData5() // generates the array
{
var data = [];
for(var i=0; i<300; i++){
var sensfi = ((document.getElementById("f5").value)*(document.getElementById("xPos5").value)*(document.getElementById("f5").value))/((i*i*document.getElementById("sDI5").value)/(document.getElementById("rI5").value));
data[i] = sensfi;
}
return data;
}
var graph;
var xPadding = 40;
var yPadding = 40;
function getMaxY5() {
var data = generateTestData5();
var max = 0;
for(var i = 0; i < data.length; i ++) {
if(data[i] > max) {
max = data[i];
}
}
max += 10 - max % 10;
return max;
}
function getXPixel5(val) {
var data = generateTestData5();
return ((graph.width() - 20) / data.length) * val + (20 * 1.5);
}
function getYPixel5(val) {
var data = generateTestData5();
return graph.height() - (((graph.height() - 20) / getMaxY5()) * val) - 20;
}
function draw5(){
var data = generateTestData5();
graph = $('#graph5');
var c = graph[0].getContext('2d');
c.lineWidth = 2;
c.strokeStyle = '#333';
c.font = 'italic 8pt sans-serif';
c.textAlign = "center";
c.beginPath();
c.moveTo(xPadding, 0);
c.lineTo(xPadding, graph.height() - yPadding);
c.lineTo(graph.width(), graph.height() - yPadding);
c.stroke();
var x = 0;
for(var i = 0; i < data.length + 1; i ++) {
if(x==30) {
c.fillText(i, getXPixel5(i), graph.height() - yPadding + 20);
x=0;}
else {
x++;
}
}
c.textAlign = "right";
c.textBaseline = "middle";
for(var i = 0; i < getMaxY5(); i += getMaxY5()/10) {
c.fillText(i, xPadding-10, getYPixel5(i));
}
c.strokeStyle = '#f00';
c.beginPath();
c.moveTo(getXPixel5(0)+10, getYPixel5(data[0])-20);
for(var i = 1; i < data.length + 1; i ++) {
c.lineTo(getXPixel5(i)+10, getYPixel5(data[i])-20);
}
c.stroke();
//c.clearRect(0,0,graph.width(),graph.height());
}
I had to change width() and height() to width and height a few times (they are simple properties), start the test data at 1 because otherwise the first value is always +infinity", and store data and max instead of generating them multiple times, but now it seems to work.
var data; /* KEEP DATA AS A GLOBAL VARIABLE INSTEAD OF GENERATING IT AGAIN EACH TIME */
var graph;
var xPadding = 40;
var yPadding = 40;
function generateTestData5() // generates the array
{
var data = [];
for(var i=1; i<=300; i++){
var sensfi = ((document.getElementById("f5").value)*(document.getElementById("xPos5").value)*(document.getElementById("f5").value))/((i*i*document.getElementById("sDI5").value)/(document.getElementById("rI5").value));
data[i-1] = sensfi;
}
return data;
}
function getMaxY5() {
var max = 0;
for(var i = 0; i < data.length; i ++) {
if(data[i] > max) {
max = data[i];
}
}
max += 10 - max % 10;
return max;
}
function getXPixel5(val) {
return ((graph.width - 20) / data.length) * val + (20 * 1.5);
}
function getYPixel5(val) {
return graph.height - (((graph.height - 20) / getMaxY5()) * val) - 20;
}
function draw5(){
data = generateTestData5(); /* USE THE GLOBAL VARIABLE */
var max = getMaxY5(); /* STORE MAX INSTEAD OF CHECKING IT MULTIPLE TIMES */
graph = document.getElementById("graph5");
var c = graph.getContext('2d');
c.lineWidth = 2;
c.strokeStyle = '#333';
c.font = 'italic 8pt sans-serif';
c.textAlign = "center";
c.beginPath();
c.moveTo(xPadding, 0);
c.lineTo(xPadding, graph.height - yPadding);
c.lineTo(graph.width, graph.height - yPadding);
c.stroke();
var x = 0;
for(var i = 0; i < data.length + 1; i ++) {
if(x==30) {
c.fillText(i, getXPixel5(i), graph.height - yPadding + 20);
x=0;}
else {
x++;
}
}
c.textAlign = "right";
c.textBaseline = "middle";
for(var i = 0; i < max; i += max/10) {
c.fillText(i, xPadding-10, getYPixel5(i));
}
c.strokeStyle = '#f00';
c.beginPath();
c.moveTo(getXPixel5(0)+10, getYPixel5(data[0])-20);
for(var i = 1; i < data.length + 1; i ++) {
c.lineTo(getXPixel5(i)+10, getYPixel5(data[i])-20);
}
c.stroke();
//c.clearRect(0,0,graph.width,graph.height);
}
draw5();
<form>
<input name="f5" id="f5" value=8>
<input name="xpos5" id="xPos5" value=100>
<input name="sDI5" id="sDI5" value=6.4>
<input name="rI5" id="rI5" value=1280>
</form>
<canvas id="graph5" width="400" height="300"></canvas>

How to stop line colouring over transparent canvas?

I need some expert help. When I make canvas background transparent the line colors the whole canvas (shown in code below).
How do I stop/fix this? I want the line stay as a single line that doesn't color the canvas.
Math.clamp = function(x, min, max) {
return x < min ? min : (x > max ? max : x);
};
// canvas settings
var viewWidth = window.innerWidth,
viewHeight = window.innerHeight,
drawingCanvas = document.getElementById("drawing_canvas"),
ctx,
timeStep = (10 / 100),
time = 0;
var lineTension = 0.067,
lineDamping = 0.068,
waveSpreadFactor = 0.1;
var previousMousePosition = {
x: 0,
y: 0
},
currentMousePosition = {
x: 0,
y: 0
},
actualMousePosition = {
x: 0,
y: 0
};
var line,
lineSegmentCount = 64,
lineMaxForce = 32,
lineStrokeGradient;
var audioCtx,
nodeCount = 64,
oscillatorNodes = [],
gainNodes = [];
var segmentsPerNode = lineSegmentCount / nodeCount;
function initGui() {
}
function goBananas() {
lineTension = 0.2;
line.anchors[Math.floor(Math.random() * line.anchors.length)].
vel = lineMaxForce;
}
function resetLine() {
line.reset();
for (var i = 0; i < nodeCount; i++) {
oscillatorNodes[i].detune.value = 100;
gainNodes[i].gain.value = 0;
}
lineTension = 0.0025;
lineDamping = 0.05;
waveSpreadFactor = 0.1;
}
function initDrawingCanvas() {
drawingCanvas.width = viewWidth;
drawingCanvas.height = viewHeight;
window.addEventListener('resize', resizeHandler);
window.addEventListener('mousemove', mouseMoveHandler);
setInterval(updateMousePosition, (1000 / 30));
ctx = drawingCanvas.getContext('2d');
ctx.lineWidth = 5;
line = new Line(0, viewHeight * 0.5, viewWidth, lineSegmentCount);
// line.anchors[0].vel = viewHeight * 0.25;
lineStrokeGradient = ctx.createLinearGradient(0, 0, 0, viewHeight);
lineStrokeGradient.addColorStop(0, '#0ff');
}
function initWebAudio() {
audioCtx = new(window.AudioContext || window.webkitAudioContext)();
for (var i = 0; i < nodeCount; i++) {
var oscillatorNode = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillatorNode.connect(gainNode);
gainNode.connect(audioCtx.destination);
gainNode.gain.value = 0;
oscillatorNode.type = 'saw';
oscillatorNode.detune.value = 200;
oscillatorNode.frequency.value = 1200 * (i / 60);
oscillatorNode.start();
oscillatorNodes[i] = oscillatorNode;
gainNodes[i] = gainNode;
}
}
function resizeHandler() {
drawingCanvas.width = viewWidth = window.innerWidth;
drawingCanvas.height = viewHeight = window.innerHeight;
if (ctx) {
ctx.lineWidth = 4;
line.resize(viewWidth, viewHeight * 0.5);
}
}
function mouseMoveHandler(event) {
actualMousePosition.x = Math.floor(event.clientX);
actualMousePosition.y = Math.floor(event.clientY);
}
function updateMousePosition() {
previousMousePosition.x = currentMousePosition.x;
previousMousePosition.y = currentMousePosition.y;
currentMousePosition.x = actualMousePosition.x;
currentMousePosition.y = actualMousePosition.y;
}
function update() {
var px = Math.min(previousMousePosition.x, currentMousePosition.x),
py = Math.min(previousMousePosition.y, currentMousePosition.y),
pw = Math.max(1, Math.abs(previousMousePosition.x - currentMousePosition.x)),
ph = Math.max(1, Math.abs(previousMousePosition.y - currentMousePosition.y)),
force = Math.clamp(currentMousePosition.y -
previousMousePosition.y, -lineMaxForce, lineMaxForce);
var pixels = ctx.getImageData(px, py, pw, ph),
data = pixels.data;
for (var i = 0; i < data.length; i += 3) {
var r = data[i + 0],
g = data[i + 1],
b = data[i + 2],
x = (i % ph) + px;
if (r + g + b > 0) {
line.ripple(x, force);
}
}
line.update();
for (var j = 0; j < gainNodes.length; j++) {
var anchor = line.anchors[j * segmentsPerNode],
gain = Math.clamp(Math.abs(anchor.vel) / viewHeight * 0.5, 0, 3),
detune = Math.clamp(anchor.pos / viewHeight * 100, 0, 300);
gainNodes[j].gain.value = gain;
oscillatorNodes[j].detune.value = detune;
}
}
function draw() {
ctx.strokeStyle = lineStrokeGradient;
line.draw();
}
window.onload = function() {
initDrawingCanvas();
initWebAudio();
initGui();
requestAnimationFrame(loop);
};
function loop() {
update();
draw();
time += timeStep;
requestAnimationFrame(loop);
}
Line = function(x, y, length, segments) {
this.x = x;
this.y = y;
this.length = length;
this.segments = segments;
this.segmentLength = this.length / this.segments;
this.anchors = [];
for (var i = 0; i <= this.segments; i++) {
this.anchors[i] = {
target: this.y,
pos: this.y,
vel: 0,
update: function() {
var dy = this.pos - this.target,
acc = -lineTension * dy - lineDamping * this.vel;
this.pos += this.vel;
this.vel += acc;
},
reset: function() {
this.pos = this.target;
this.vel = 0;
}
};
}
};
Line.prototype = {
resize: function(length, targetY) {
this.length = length;
this.segmentLength = this.length / this.segments;
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].target = targetY;
}
},
reset: function() {
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].reset();
}
},
ripple: function(origin, amplitude) {
var i = Math.floor((origin - this.x) / this.segmentLength);
if (i >= 0 && i <= this.segments) {
this.anchors[i].vel = amplitude;
}
},
update: function() {
var lDeltas = [],
rDeltas = [],
i;
for (i = 0; i <= this.segments; i++) {
this.anchors[i].update();
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
lDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i - 1].pos);
this.anchors[i - 1].vel += lDeltas[i];
}
if (i < this.segments) {
rDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i + 1].pos);
this.anchors[i + 1].vel += rDeltas[i];
}
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
this.anchors[i - 1].pos += lDeltas[i];
}
if (i < this.segments) {
this.anchors[i + 1].pos += rDeltas[i];
}
}
},
draw: function() {
ctx.beginPath();
for (var i = 0; i <= this.segments; i++) {
ctx.lineTo(
this.x + this.segmentLength * i,
this.anchors[i].pos
);
}
ctx.stroke();
}
};
From the code you posted, the problem seems to be a missing
ctx.clearRect(0, 0, viewWidth, viewHeight)
at the beginning of your "draw" function.
See a working example here

Categories