Reputation: 181
I have been trying to make a paint app using p5.js recently, and I've used lines, but they do not produce a smooth curve if my cursor moves fast. Now, I am trying to use curveVertex to connect the points, and it does work, just that it sometimes randomly creates a loop (when my cursor moves fast).
Circled in red are the loops, and sometimes I get weird curves too (circled in green).
Code:
let shapes = [];
let trail = [];
let drawings = [];
let penStrokeSize = 10;
let penFill = "black";
let backdrop = "white";
let trailLength = 10;
let defaultColors = ["white", "black", "red", "green", "blue", "yellow", "orange", "purple", "pink"];
let lastMousePos = [0, 0];
let lastPressed = false;
function setup() {
// create a screen size canvas
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(backdrop);
putDrawings();
drawSquares();
drawTrail();
// set last mouse pos to current mouse x and mouse y
lastMousePos = [mouseX, mouseY];
lastPressed = mouseIsPressed;
}
function updateDrawings() {
if (lastPressed && mouseIsPressed) {
drawings[drawings.length - 1].push([mouseX, mouseY]);
} else if (mouseIsPressed) {
drawings.push([[mouseX, mouseY]]);
}
}
function putDrawings() {
updateDrawings();
// loop through each element of drawings, and draw a vertex through each of the points in the array
for (let i = 0; i < drawings.length; i++) {
noFill();
stroke(penFill);
strokeWeight(penStrokeSize);
beginShape();
for (let j = 0; j < drawings[i].length; j++) {
curveVertex(drawings[i][j][0], drawings[i][j][1]);
}
endShape();
fill(penFill);
strokeWeight(0);
}
}
function updateTrail() {
trail.push([mouseX, mouseY]);
if (trail.length > trailLength) {
trail.shift();
}
}
function drawTrail() {
updateTrail();
noFill();
stroke(penFill);
strokeWeight(penStrokeSize);
beginShape();
for (let i = 0; i < trail.length; i++) {
curveVertex(trail[i][0], trail[i][1]);
}
endShape();
fill(penFill);
strokeWeight(0);
}
// ignore this function
function drawShape() {
for (let i = 0; i < shapes.length; i++) {
const type = shapes[i].type;
switch (type) {
case "ellipse":
fill(shapes[i].color);
ellipse(shapes[i].x, shapes[i].y, shapes[i].width, shapes[i].height);
break;
case "rect":
fill(shapes[i].color);
rect(shapes[i].x, shapes[i].y, shapes[i].width, shapes[i].height);
break;
case "line":
stroke(shapes[i].color);
strokeWeight(shapes[i].strokeSize);
line(shapes[i].x1, shapes[i].y1, shapes[i].x2, shapes[i].y2);
strokeWeight(0);
break;
case "point":
stroke(shapes[i].color);
strokeWeight(shapes[i].strokeSize);
point(shapes[i].x, shapes[i].y);
strokeWeight(0);
break;
}
}
}
// ignore this function
function addShape(shape, props) {
switch (shape) {
case "ellipse":
shapes.push({
type: "ellipse",
x: props[0],
y: props[1],
width: props[2],
height: props[3],
color: props[4],
});
break;
case "rect":
shapes.push({
type: "rect",
x: props[0],
y: props[1],
width: props[2],
height: props[3],
color: props[4],
});
break;
case "line":
shapes.push({
type: "line",
x1: props[0],
y1: props[1],
x2: props[2],
y2: props[3],
color: props[4],
strokeSize: props[5],
});
break;
case "point":
shapes.push({
type: "point",
x: props[0],
y: props[1],
color: props[2],
});
break;
}
}
// create a function that draws 9 squares of size 7% of window height
function drawSquares() {
for (let i = 0; i < defaultColors.length; i++) {
if (defaultColors[i] === "white") {
stroke("black");
strokeWeight(2);
}
// create an array with the square's x and y coordinates and its width and height
let square = [i * windowHeight * 0.05 + windowWidth * 0.05, windowHeight * 0.9, windowHeight * 0.05, windowHeight * 0.05];
fill(defaultColors[i]);
// draw a square with the array square as its arguments
rect(square[0], square[1], square[2], square[3]);
// if the current mouse position is inside the current square and mouse is pressed and mouse button is left, change pen fill to the current color
if (mouseX > square[0] && mouseX < square[0] + square[2] && mouseY > square[1] && mouseY < square[1] + square[3] && mouseIsPressed && mouseButton === LEFT) {
penFill = defaultColors[i];
}
strokeWeight(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
Help is appreciated!
Upvotes: 2
Views: 321
Reputation: 62686
The curveVertex
method is drawing a spline (see here),where every 2nd and 3rd point in a series of 4 are being treated as control points. Just use plain old vertex
(doc).
beginShape();
for (let j = 0; j < drawings[i].length; j++) {
vertex(drawings[i][j][0], drawings[i][j][1]);
}
endShape();
Upvotes: 1