How to draw a p5.js circle over an HTML image - javascript

I am loading an image into my web app using standard JS and HTML It just just a simple map and my goal is to draw on it using p5.js.
<div id="map">
<img src="Assets/MENA.jpg" class="image" width="1500" height="750">
</div>
function conflictMapMENA() {
this.name="MENA conflict map";
this.id="conflict-map"
this.draw = function() {
var map = document.createElement('img')
map.src = 'Assets/MENA.jpg'
gallery.selectVisual(map);
fill(255, 0, 0);
ellipse(30, 30, 10);
}
}
Inside this.draw = function(){}, I am invoking p5.js library's ellipse() and fill() functions to draw a red circle. This is what it looks like:
But when I try to adjust the coordinates to move the circle over the map, the circles go under it. Is there a way for me to have these two things cooperate without me having to draw the circle in pure JS?

Do you need the image to be in your actual HTML? If not, you can use the loadImage() and image() functions in p5.js:
let myImage;
function setup() {
createCanvas(400, 400);
myImage = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Domestic_Cat_Demonstrating_Dilated_Slit_Pupils.jpg/220px-Domestic_Cat_Demonstrating_Dilated_Slit_Pupils.jpg");
}
function draw() {
image(myImage, 0, 0, width, height);
ellipse(width / 2, height / 2, 100, 100);
}
If you do need your image in your actual HTML, then you can use a combination of CSS and the parent() function to make the image overlap with your sketch:
<body>
<div id="my-canvas"
style="position:absolute;"></div>
<img style="width: 400px; height: 400px;"
src="path/to/image.png" />
<script src="sketch.js"></script>
</body>
function setup() {
const canvas = createCanvas(400, 400);
canvas.parent('my-canvas');
}
function draw() {
ellipse(width / 2, height / 2, 100, 100);
}

Just checked your doubt the background is overlapping the circle because of the depth u can give the depth of the circle greater than the backgroung

Related

How to move ellipse filled with an image to mask similar background?

I am a super early user of coding from Italy.
I came up with an idea to promote a company logo on their website and I almost reached the goal so I am sharing this problem.
The idea is to obtain a sort of clipping mask effect when the mouse/cursor move on the image
I've made so far a code that does the work with a still ellipse.
When I set the position parameters of the ellipse as mouseX and mouseY the effect does not work if not just a bit of a glitch at the start.
How can I make it work as intended?
Here you can find the link of what I have now:
https://editor.p5js.org/francesco.ficini.designer/full/FLBuhggW-
Here the code:
let img;
let imgbg2;
let maskImage;
function preload() {
img = loadImage("NeroP.jpg");
imgbg2 = loadImage("RossoP.jpg");
}
function setup() {
createCanvas(400, 225);
img.mask(img);
}
function draw() {
background(imgbg2, 0, 0);
//Immages
image(imgbg2, 0, 0);
image(img,0,0);
// Ellipse Mask
maskImage = createGraphics(400, 225);
maskImage.ellipse(200, 100, 50, 50);
imgbg2.mask(maskImage);
image(imgbg2, 0, 0);
}
The thing about the p5.Image.mask function is that it modifies the image that is being masked. Which means that any pixels that are cleared by the mask are gone for good. So if you want to dynamically change the mask you will need to make a copy of the original and re-apply the modified mask any time it changes.
Additionally you will want to avoid creating images and graphics objects in your draw() function because this can result in excessive memory allocation. Instead create a single set of graphics/images and re-use them.
let img;
let imgbg2;
let maskImage;
let maskResult;
function preload() {
img = loadImage("https://www.paulwheeler.us/files/NeroP.jpeg");
imgbg2 = loadImage("https://www.paulwheeler.us/files/RossoP.jpeg");
}
function setup() {
createCanvas(400, 225);
// Create graphics and image buffers in setup
maskImage = createGraphics(imgbg2.width, imgbg2.height);
maskResult = createImage(imgbg2.width, imgbg2.height);
}
function mouseMoved() {
if (maskResult) {
maskImage.clear();
// Ellipse
maskImage.ellipse(mouseX, mouseY, 50, 50);
// Copy the original imgbg2 to the maskResult image
maskResult.copy(
imgbg2,
0, 0, imgbg2.width, imgbg2.height,
0, 0, imgbg2.width, imgbg2.height
);
// apply the mask to maskResult
maskResult.mask(maskImage);
}
}
function draw() {
//Immagini
image(img, 0, 0);
// draw the masked version of the image
image(maskResult, 0, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

Create a image-mask with p5js

Im trying to figure out if its possible to have a blank canvas and then place a image and have it masked by a random shape? That or use a png as mask.
Thank you
M
Yup it is possible and quite trivial with the mask() function on the p5.Image class (it's too bad they don't list this class member functions on the main page of the reference but if you use the search box you'll find these types of things).
Given the image:
And the mask PNG:
You can render the masked image like so:
let img;
let mask;
function preload() {
img = loadImage('https://www.paulwheeler.us/files/windows-95-desktop-background.jpg');
mask = loadImage('https://www.paulwheeler.us/files/Vase-Illusion.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
img.mask(mask);
noLoop();
}
function draw() {
image(img, 0, 0, height * (img.width / img.height), height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

How to Render a Single p5.js Sketch to Multiple Divs

I am trying to use a single p5 sketch in multiple divs.
Currently using below code below. I have tried using a class selector but it seems to only work with a parent method(doesn't work with getElementById for example.) As another workaround, I could not make this p5 sketch the background element in the body selector either. Thanks for the help!
let theShader;
function preload() {
theShader = loadShader('shader.vert', 'shader.frag');
}
function setup() {
pixelDensity(1);
let myCanvas = createCanvas(windowWidth, windowHeight, WEBGL);
myCanvas.parent('container1');
}
function draw() {
shader(theShader);
theShader.setUniform("u_resolution", [width, height]);
theShader.setUniform("u_time", millis() / 1000.0);
theShader.setUniform("u_mouse", [mouseX, map(mouseY, 0, height, height, 0)]);
rect(0.0, 0.0, 1.0, 1.0);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
Not sure if it works like that. But you could try to create a canvas element instead of a div element. At the end of the day, a p5 sketch is also a canvas element.
And then you should be able to grab the new canvas:
let newCanvasCtx = newCanvas.getContext('2d');
and then call drawImage and pass in the p5 canvas:
newCanvasCtx.drawImage(p5Canvas, 0, 0);

P5 SVG imageMode

I load my mapbox-Link like this and it works:
var mapimg;
function preload () {
mapimg = loadImage('mapbox-LINK');
}
function setup() {
createCanvas(1024,720);
translate(width /2, height / 2);
imageMode (CENTER);
image(mapimg, 0,0);
}
But when I change craeteCanvas() to craeteCanvas( , , SVG) it jumps away and behaves strange. I'm using zenozeng to render the .svg Canvas.
I think it is the imageMode(CENTER) that doesnt work in this enviroment. How can I center my Image again?
You are translating your canvas to center translate(width /2, height / 2); then drawing the image. If you want the image centered, just keep the canvas on its original (0,0), and default imageMode(CORNER)
var mapimg;
function preload () {
mapimg = loadImage('https://api.mapbox.com/styles/v1/foliran/cjnrcb1pm1vbw2rqkbw3o5uog/static/10.4209538,51.1657564,5/1024x720?access_token=pk.eyJ1IjoiZm9saXJhbiIsImEiOiJjam5yZXA0Z2gwNnlmM2twcDJrNnlxdHJkIn0.vSpVuibxadIaVGb4JiPn_w');
}
function setup() {
createCanvas(1024,720,SVG);
// translate(width /2, height / 2); //no need to translate
// imageMode (CORNER); //no need to imageMode, as it's default
image(mapimg, 0,9);
}
I'm not familiar with p5.js-svg but be careful with all the different implications of rendering using the p5.js canvas vs using this svg mode.

HTML5 Canvas: How to make a loading spinner by rotating the image in degrees?

I am making a loading spinner with html5 canvas. I have my graphic on the canvas but when i rotate it the image rotates off the canvas. How do I tell it to spin the graphic on its center point?
<!DOCTYPE html>
<html>
<head>
<title>Canvas test</title>
<script type="text/javascript">
window.onload = function() {
var drawingCanvas = document.getElementById('myDrawing');
// Check the element is in the DOM and the browser supports canvas
if(drawingCanvas && drawingCanvas.getContext) {
// Initaliase a 2-dimensional drawing context
var context = drawingCanvas.getContext('2d');
//Load the image object in JS, then apply to canvas onload
var myImage = new Image();
myImage.onload = function() {
context.drawImage(myImage, 0, 0, 27, 27);
}
myImage.src = "img/loading.png";
context.rotate(45);
}
}
</script>
</head>
<body>
<canvas id="myDrawing" width="27" height="27">
</canvas>
</body>
</html>
Here is the complete working example:)
<!DOCTYPE html>
<html>
<head>
<title>Canvas Cog</title>
<script type="text/javascript">
var cog = new Image();
function init() {
cog.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABK1JREFUeNqMVt1ZGzkUvVfS4IW1l8GO82w6IBXE7mCpAFMB+Pt4Z6iApALcAe4AU0HoAJfg7BPYHinnXmmciX+y0YdmJHnQ0bk/R5cvh5cUyFPwRD4EChgEvGWMB36R3+JaiTkmD5gOs8yNb25uLlerFf1pM2yIGA82TEY7xow1oj4GBU6S6yywPNG4JwDH+XGv0Whs7ndN8n97mmPsLCSYgy7ImPQE/pFDyAF+7L0fgTNFUDBcLal90taD1doQ/T6NT9DnW8zkT+jJuQVYukG3hifCVk/L3JOxMBa8VVlSp9MhHKLaB+zpNo1fdgEpmByuMqUAV5viOQLwXNax9KBAFNEEpN1pUwnQmvl6aTza6zNjrCKaymeyOdYAMgfg18iG4T/qw+AC94zvpzDjcwqOXo3VGH26H0xMZ7jPxgT0R2zUi4BYt6bAfEbJvJFZKA4ODgZ5nhcJLE9mk35X21vWC/TXKmiwr2xszoQd/PQv3t/QCzY2twpqBpb5FKOp+hCgzWaTWq0W1Xx0ij5An9WC5VtiLMwvNBrVaSGMvQk5jHQVPN7sb0HzAtE+QJrNgrcUNEARieWCut0ugR0tl8sKcJ5Ahc3jRviPK8ZGTaaBwGKyT+gTiwM4a3Jrba6MbeVXo5F4kp9shn29ndUYC9vLirGDXzRhrYhD8DME5Hkg22df5rDYS/RXmVIsaP/Q/SXs600YnifTjbeSWliEdTYb3QyTqYfdDKTL4B1KS6tVqf6SgGq3P9BvZGpvNIrPCgVKZlGlCDQDxJiCjVppCab05DJHzb+b1Gm36X80cVjLuzozexs0f6IgRkA5XRhzIixRL1+IzhwdHVHrn1Y9oXe1i10aKT6bGGhg1CKK+cT0zCGCs0oXTIogybJMw/779//o48duMvnO9rzLn+Kz8wgS5Shqo4njpCoOQA5Ajb8adHh4SMvVghaLhYb/HsBip88krNVISSEigOlhjmi0LziNhr6wOsgO9C1339vbGznnNAU2AM9Svk235cqKieKGkldAf7DGvTrjnjJnzyQoMu0ZTuZgUqvmlYR+f39XIE4uqCX1E/rDZpCYmKwOOmivAfYK9KF1AM7EdG4uAMLAOjmQideQXOJQkyUisqYiFRhtSFbxCxj8do0T30dmTvLhC+an0MZZVBHX09tBTG4qFigZEJEChjTIEwtRik81Qa7uOQU0IrYAe7FRjqYw6SlYjgAyN1GmHsFIGPfVnxzFuFITKEkfYK+oWZ5qKlIkcZ7UE92oXBmeIgIxtAO5UtSHqo9uiLW+sme5ejSIRASeAFR4LYy8MMzL1aq3EYWzJF28BgMEzGYpBkrMKelgl+P6uTcVY8NjLYyYPwMTCcufSaouH6al9xNJcjC82vDb9uVZKbrWIumNO+waVsu1TCC+Wxcg6xaSpsZSYM2wLO9/U8qZWH+wztQnsfAxV/E3MIKZVf1FsmJVV8mamhEmxZ0X7sSsABsGv1tZJGejmptU7FBUDYzPAXQBwFEEl+9+stFEroJEci2ELwIMmZuWoSTE9DYYcWVCjlJrZWMpeBhlAEqBiulPE84S3ixU5gSTwGGOdyEVNJXxA8nPevshwABHktBS1YoQ+QAAAABJRU5ErkJggg=='; // Set source path
setInterval(draw,10);
}
var rotation = 0;
function draw(){
var ctx = document.getElementById('myCanvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.save();
ctx.clearRect(0,0,27,27);
ctx.translate(13.5,13.5); // to get it in the origin
rotation +=1;
ctx.rotate(rotation*Math.PI/64); //rotate in origin
ctx.translate(-13.5,-13.5); //put it back
ctx.drawImage(cog,0,0);
ctx.restore();
}
init();
</script>
</head>
<body>
<canvas width="27" height="27" id="myCanvas"></canvas>
</body>
</html>
rotate turns the canvas(?) around your current position, which is 0, 0 to start. you need to "move" to your desired center point, which you can accomplish with
context.translate(x,y);
after you move your reference point, you want to center your image over that point. you can do this by calling
context.drawImage(myImage, -(27/2), -(27/2), 27, 27);
this tells the browser to start drawing the image from above and to the left of your current reference point, by have the size of the image, whereas before you were starting at your reference point and drawing entirely below and to the right (all directions relative to the rotation of the canvas).
since your canvas is the size of your image, your call to translate will use the same measurement, (27/2), for x and y coordinates.
so, to put it all together
// initialization:
context.translate(27/2, 27/2);
// onload:
context.rotate(Math.PI * 45 / 180);
context.drawImage(myImage, -(27/2), -(27/2), 27, 27);
edit: also, rotation units are radians, so you'll need to translate degrees to radians in your code.
edits for rearranging stuff.
For anyone else looking into something like this, you might want to look at this script which does exactly what was originally being requested:
http://projects.nickstakenburg.com/spinners/
You can find the github source here:
https://github.com/staaky/spinners
He uses rotate, while keeping a cache of rectangles which slowly fade out, the older they are.
I find another way to do html loading spinner. You can use sprite sheet animation. This approach can work both by html5 canvas or normal html/javascript/css. Here is a simple way implemented by html/javascript/css.
It uses sprite sheet image as background. It create a Javascript timer to change the background image position to control the sprite sheet animation. The example code is below. You can also check the result here: http://jmsliu.com/1769/html-ajax-loading-spinner.html
<html>
<head><title></title></head>
<body>
<div class="spinner-bg">
<div id="spinner"></div>
</div>
<style>
.spinner-bg
{
width:44px;
height:41px;
background: #000000;
}
#spinner
{
width: 44px;
height: 41px;
background:url(./preloadericon.png) no-repeat;
}
</style>
<script>
var currentbgx = 0;
var circle = document.getElementById("spinner");
var circleTimer = setInterval(playAnimation, 100);
function playAnimation() {
if (circle != null) {
circle.style.backgroundPosition = currentbgx + "px 0";
}
currentbgx -= 44; //one frame width, there are 5 frame
//start from 0, end at 176, it depends on the png frame length
if (currentbgx < -176) {
currentbgx = 0;
}
}
</script>
</body>

Categories

Resources