I'm currently doing a project regarding p5.js and I need to do the following:
Input: given image and rectangle;
Algorithm: move the image inside the rectangle. By saying moving, I mean when the mouse is clicked, move the whole image to match the size of the rectangle by showing only portion of the image (size of the rectangle).
Output: dragging image inside the rectangle.
Update: When I import an image with React input form, it does not change the current image in P5 even I call the p5.redraw() function.
My current code is moving the image, but I need an image to be inside the rectangle and show only part of the image that is this size of the rectangle. The code is written in React:
const [selectedFile, setSelectedFile] = useState();
let backgroundImage;
let dragging = false; // Is the object being dragged?
let rollover = false; // Is the mouse over the ellipse?
let x, y, w, h; // Location and size
let offsetX, offsetY; // Mouseclick offset
const setup = (p5, parentRef) => {
p5.createCanvas(1000, 500).parent(parentRef);
// Starting location
x = 350;
y = 50;
const url =
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/640px-Image_created_with_a_mobile_phone.png";
backgroundImage = p5.loadImage(url);
// Dimensions
w = 700;
h = 700;
};
const draw = (p5) => {
p5.background(233);
if (
p5.mouseX > x &&
p5.mouseX < x + w &&
p5.mouseY > y &&
p5.mouseY < y + h
) {
rollover = true;
} else {
rollover = false;
}
// Adjust location if being dragged
if (dragging) {
x = p5.mouseX + offsetX;
y = p5.mouseY + offsetY;
}
if (selectedFile != null) {
const url = URL.createObjectURL(selectedFile);
backgroundImage = p5.loadImage(url);
// p5.image(backgroundImage, x, y, w, h);
// p5.redraw();
// backgroundImage = p5.loadImage(url, () => {
// p5.image(backgroundImage, x, y, w, h);
// p5.redraw();
// });
} else {
}
p5.image(backgroundImage, x, y);
drawMaskOverlay(p5);
};
const drawMaskOverlay = (p5) => {
p5.fill(255);
p5.noStroke();
p5.beginShape();
// CW
p5.vertex(0, 0);
p5.vertex(p5.width, 0);
p5.vertex(p5.width, p5.height);
p5.vertex(0, p5.height);
// cutout contour CCW
p5.beginContour();
p5.vertex(400, 100);
p5.vertex(400, 400);
p5.vertex(600, 400);
p5.vertex(600, 100);
p5.endContour();
p5.endShape();
};
const mousePressed = (p5) => {
if (
p5.mouseX > x &&
p5.mouseX < x + w &&
p5.mouseY > y &&
p5.mouseY < y + h
) {
dragging = true;
offsetX = x - p5.mouseX;
offsetY = y - p5.mouseY;
}
};
const mouseReleased = (p5) => {
// Quit dragging
dragging = false;
};
to display it, I use the following code:
return (
<div className="App">
<div>
<h1>Select an image</h1>
<input
type="file"
name="file"
id="file"
// onChange={(e) => setSelectedFile(e.target.files[0])}
onChange={(e) => setSelectedFile(e.target.files[0])}
/>
<Sketch
// preload={preload}
setup={setup}
draw={draw}
mouseReleased={mouseReleased}
mousePressed={mousePressed}
/>
</div>
</div>
);
I use react-p5 library.
You can see and test the code in StackBlitz.