I am using p5.js for something and I need to have text inside rectangles appearing at the top of my canvas. I want this text to force the rect() around it to fit so that there is no empty space of the rectangle, it just wraps around the string.
Previously I tried giving the rectangle dimensions manually, though this worked poorly depending on the length of the string. I have looked at using HTML5's canvas 'measureText' and 'fillText' functions, though these work only for the html canvas, not the javascript canvas I have loaded a background image onto.
I want to have the coloured rectangle fit around the text, on the JS canvas as below.
JS background image canvas with rectangle
With the following code:
function word (x) {
this.wordX = x;
this.wordY = random(5,30);
this.display = function(){
fill('#4545f5');
rect(this.wordX,this.wordY,420,55);
fill('#ffffff');
textSize(25);
text("alphabet", this.wordX+5, this.wordY+10, 410, 55);
}
What can I use to make the box fit neatly around the text and still use the JS background canvas, or can I put an image from a file onto the HTML canvas?
Following is the setup() code for instantiation and canvas drawing:
function preload() {
BG = loadImage('images/background.PNG');
}
function setup() {
createCanvas(windowWidth,windowHeight);
word1 = new word(random(10,windowWidth-370));
}
function draw() {
image(BG, 0, 0, windowWidth, windowHeight);
word1.display();
}
This code demonstrates using measureText() on a canvas context created with createCanvas()
const element = createCanvas(300, 400);
const context = element.getContext('2d');
context.font = `22px sans-serif`;
console.log(context.measureText('hello world').width);
context.font = `22px cursive`;
console.log(context.measureText('hello world').width);
Related
I have a p5.js 3D sketch. I have to set its background image. I know that we can easily implement it with same background() function in a 2D sketch, but it is not possible in a 3D sketch.
I googled for some hacks and found that I can have a plane with the dimensions of the canvas at the back and then use texture() to set its background image like the below example.
var img;
function preload() {
img = loadImage("img.png");
}
function setup() {
createCanvas(600, 600, WEBGL);
}
function draw() {
background(220);
push();
texture(img);
plane(600, 600);
pop();
}
But the issue is - I have to use orbitControl() in my sketch. Due to this, the background (plane) also moves when I drag around. I want my background to be static (it should not move when I move other objects).
Finally, I resorted to css background-image property to set the background image of the canvas and remove background(255) in the draw() function. But due to this, the background (previous frames) were not overlapped when I dragged objects and were also visible.
How can I implement background image in this case?
My sketch is available at https://editor.p5js.org/praneetdixit1234/sketches/9pN4lA8KB
I think your CSS approach is good, just not sure why use cover on the size ...
Your image is 1365px wide but your canvas is only 600px, with cover most of it will be hidden, and the text will not be fully seen, but in the future if you change the image using cover might be fine.
Here is what I used
canvas {
display: block;
background-image: url("https://static.vecteezy.com/system/resources/previews/000/118/983/original/free-vector-cityscape.jpg");
background-size: contain;
background-repeat: no-repeat;
}
...and don't remove background, set the alpha background(0,0,0,0);
Here is the working sample:
https://editor.p5js.org/heldersepu/sketches/ll8txfcs0
I also added smooth() on my sample:
The difference is noticeable, read more about it here:
https://p5js.org/reference/#/p5/smooth
You should render your background and 3d objects to different image surfaces, and then combine them on the canvas.
Here's an example:
https://editor.p5js.org/space-haze/sketches/alWGuuXXe
var w = window.innerWidth;
var h = window.innerHeight;
function setup() {
// create the primary drawing surface
createCanvas(w, h);
// create a 3d off-screen surface
img3d = createGraphics(w,h,WEBGL);
}
function draw() {
// draw our background color/image to canvas
background(color('purple'));
// render our 3d objects to off-screen surface
let x = w/3;
img3d.fill(color('yellow'));
img3d.stroke(color('black'));
img3d.strokeWeight(2);
img3d.camera(x*2,x*2,x*2,0,0,0,0,1,0);
img3d.box(x);
// draw our off-screen surface to canvas
image(img3d,0,0);
}
I'm trying to put a image and text on background image using Canvas/jQuery, but i don't no how to do this. I need to do like this image http://static.catfly.com/quiz/which-friend-should-be-kidnapted-by-aliens/en/cover.jpg
I already tried and found some script for a blog but it's not complete script, it's only made a circle, anyone can help me please?
Here is my script below.
<body onload="displayImage()">
<script type="text/javascript">
//Global variables
var myImage = new Image(); // Create a new blank image.
// Load the image and display it.
function displayImage()
{
// Get the canvas element.
canvas = document.getElementById("myCanvas");
// Make sure you got it.
if (canvas.getContext)
{
// Specify 2d canvas type.
ctx = canvas.getContext("2d");
// When the image is loaded, draw it.
myImage.onload = function() {
// Load the image into the context.
ctx.drawImage(myImage, 0, 0);
// Get and modify the image data.
changeImage();
}
// Define the source of the image.
myImage.src = "https://pbs.twimg.com/profile_image/843519123711803393/pyYe9LFq_400x400.jpg";
}
}
function changeImage()
{
ctx.strokeStyle = "white";
ctx.lineWidth = "100";
ctx.beginPath();
ctx.arc(100, 100, 150, 0, Math.PI * 2, true);
ctx.closePath();
ctx.stroke();
}
</script>
<canvas id="myCanvas" width="200" height="200"></canvas>
</body>
One of the problems is that the canvas is only 200x200 and the line width of the circle is 100, and white, so when drawn it fills most of the canvas (it's also drawn slightly outside the canvas area in this case).
And, the image in question also has a load error which may be the primary cause here (onerror+onabort handlers should always be added).
Simply adjust down the line width, fix the image, and I would also recommend setting the canvas bigger (it can be set using the image size).
I know there's a similar question here, but neither the question nor the answer have any code.
What I want to do, is to port this functionality to a 100% Javascript solution. Right now I'm able to draw a rectangle on top of HTML content using PHP.
I scrape a website with CasperJS, take a snapshot, send the snapshot path back to PHP along with a json object that contains all the information necessary to draw a rectangle with GD libraries. That works, but now I want to port that functionality into Javascript.
The way I'm getting the rectangle information is using getBoundingClientRect() that returns an object with top,bottom,height, width, left,and right.
Is there any way to "draw" the HTML of the website to a canvas element, and then draw a Rectangle on that canvas element?
Or is there any way to draw a rectangle on top of the HTML using Javascript?
Hope my question is clear enough.
This is the function that I'm using to get the coordinates of the elements that I want to draw a Rectangle around.
function getListingRectangles() {
return Array.prototype.map.call(document.querySelectorAll('.box'), function(e) {
return e.getBoundingClientRect();
});
You can create a canvas element and place it on top of the HTML page:
//Position parameters used for drawing the rectangle
var x = 100;
var y = 150;
var width = 200;
var height = 150;
var canvas = document.createElement('canvas'); //Create a canvas element
//Set canvas width/height
canvas.style.width='100%';
canvas.style.height='100%';
//Set canvas drawing area width/height
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//Position canvas
canvas.style.position='absolute';
canvas.style.left=0;
canvas.style.top=0;
canvas.style.zIndex=100000;
canvas.style.pointerEvents='none'; //Make sure you can click 'through' the canvas
document.body.appendChild(canvas); //Append canvas to body element
var context = canvas.getContext('2d');
//Draw rectangle
context.rect(x, y, width, height);
context.fillStyle = 'yellow';
context.fill();
This code should add a yellow rectangle at [100, 150] pixels from the top left corner of the page.
I have a plugin that will fill text based on an image using the following:
function draw() {
//grab font to use
var fFamily = $(".activeText a .fontType-cont").val();
ctx.font = startFontSize + 'px ' + fFamily;
ctx.fillText(text, 10, 100);
ctx.globalCompositeOperation = 'source-in';
ctx.drawImage(img, 10, 20, 500, 100);
}
var canvas = document.getElementById(current),
ctx = canvas.getContext('2d'),
img = document.createElement('img');
//draw it
img.onload = draw;
img.src = $(".activeGColor").find('img').attr('src');
What happens is that the canvas will take that image, display it in the canvas and as the text gets bigger, you see it as the fill for the text. My issue is that, How can I make it so it does not look stretched or whatnot? Do I have an option to do so?
What are your ideas?
We need to see an example of whats going on here. Your question makes it sound like you have some sort of animation going on... that changes the font-size to a larger and larger size. The way things work by default, is that the text will render proportionally. However if your using any thing like ctx.scale() you obviously could throw that off. Also if your not clearing your canvas each frame, you could get more of a bleed effect, that you may be describing as stretching.
Hi there I have a simple question I can'[t seem to find the answer to on google. I'm trying to draw an image on a canvas. I originally used the "new" constructor ( ballPic = new Image(); ballPic.src = "ball.png" ) which worked when drawing on my canvas, but I needed to do some scaling and wasn't sure if I could attach a css id to the object. So I instead tried to use the image tag and did the rest in css.
However using a variable that way doenst seem to work with my canvas' drawing:
ballPic = '<img id="soccerBall">';
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.drawImage(BallPic, -25, -25);
Is this because assigning a variable like ballPic = is not the same as being the element itself like when using the constructor? How would I pass it other than attaching it to the document and using getElementbyID?
You can keep using the Image constructor and still scale the image. There's another method overload of the drawImage function:
From MDN:
The second variant of the drawImage() method adds two new parameters and lets us place scaled images on the canvas.
drawImage(image, x, y, width, height)
This adds the width and height parameters, which indicate the size to which to scale the image when drawing it onto the canvas.
I would recommend you check out that page, it has a lot of good information, like
Using data: urls
Handling image loading
Loading still frames from videos
Slicing
Examples gallore
Create an image, handle the onload event, in which you update the canvas size to the scaled size of the image, then drawImage with a scale.
var scale = 2 ;
var ballPic = new Image();
ballPic.onload = function drawImage() {
var c=document.getElementById("myCanvas");
c.width = ballPic.width * scale ;
c.height = ballPic.height * scale ;
var ctx=c.getContext("2d");
ctx.scale(scale, scale) ;
ctx.drawImage(ballPic, 0, 0);
};
ballPic.src =
'http://melinabeachturtlehatchery.files.wordpress.com/2010/07/turtle4.jpg';
the fiddle is here :
http://jsbin.com/etemox/1/edit