I am following a tutorial from Dev.Opera about HTML5 Painting application and trying to improve it by adding a text tool that prompts user of what text they wanted to input after clicking on coordinate.
E.g. User clicked on coordinate 100,200 , a prompt will ask what text they wanted to show and after user entered the text, it should draw it on canvas.
I knew my browser support canvas fillText and strokeText function, because when I load this web the text shows.
On the tutorial I follow, Dev.Opera creates a temp canvas on the real canvas so that images (shapes and text) are supposedly drawn to temp canvas and then transferred to real canvas by img_update() method.
// This function draws the #imageTemp canvas on top of #imageView,
// after which #imageTemp is cleared. This function is called each time when the
// user completes a drawing operation.
function img_update () {
contexto.drawImage(canvas, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
}
I tried to do fillText on context like this:
context.fillText(textVar, x, y);
img_update();
and this does not draw the text, while:
contexto.fillText(textVar, x, y);
draws it perfectly.
I had expand the program to draw circle, polyline, and fills and all of them works perfectly on the context without having to draw them at contexto.
How can I force the text to be drawn at context and then transfer it using img_update()?
maybe fill style is set so that you do not see the text?
Related
I want to draw a line on a picture while having an ellipse following the mouse at the mouse position. I have developed the following code, the ellipse always draw on the picture.
function setup() {
createCanvas(400, 400);
}
function draw() {
//background(220);
line(pmouseX, pmouseY, mouseX, mouseY);
fill(255, 0, 0);
ellipse(mouseX, mouseY, 7, 7);
}
You can see that the ellipse is always draw on the picture. How can I remove the ellipse after it shows once?
I am expecting a line is drawn on the picture while an ellipse is shown at the mouse position. The ellipse should not draw on the image, I only follow the mouse location, however, the line will draw on the picture.
I think I understand now what you want.
If you uncomment the background instruction, you will erase the lines drawn so far. If you comment the background the lines will remain, but also the ellipses.
So, for that you need the instruction cursor() that allows you to use a custom mouse cursor.
So, what I would suggest is: Create an image file that contains an ellipse and the background is transparent.
Specify that you want a cursor from a file, by doing
cursor("myCursorImage.png")
Take a look at the reference of the cursor that I provided in a link to see the different parameters you can pass to cursor()
I have seen several solutions on this issue but have not found one yet that works for my situation.
I have a chart being made with chart.js which uses canvas to display. I have a function that is supposed to clear the canvas so that I can then redraw the chart with different x variables. The function works initially but as soon as I start to hover on my cleared canvas the old contents reappear. More specifically it seems to reappear if I am hovering over on of the previous data points.
Here is the function:
function empty(){
canvas = document.getElementById("loansChart");
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
}
EDIT
If a canvas contained items that had hover initiated function items, do those items still exist (just invisible) in the canvas?
You should use the chart.js functions for updating and clearing charts rather than the ones for the html canvas.
The docs are quite straightforward. https://www.chartjs.org/docs/latest/developers/updates.html
I am having a problem with drawing circles on a canvas. When I draw a circle on my canvas it works fine, but if I draw a square afterwards, the color of my circle changes to the same color as the square.
This has been troubling me for a while now. Here is a jsbin project to demonstrate what I am talking about:
https://jsbin.com/bajezudayi/edit?html,js,output
On this canvas you can draw circles and squares (note the check box at the top to switch shapes).
I have tried changing the color variable in the drawCircle to a set value instead of being a function argument but the problem persists.
function drawCircle(x,y,rad,col,ctx){
// This function draws a circle on a canvas
ctx.save();
ctx.translate(x,y);
ctx.beginPath();
ctx.arc(0,0,rad,0,2*Math.PI,false);
ctx.fillStyle='red'; // rather than =col
ctx.fill();
ctx.restore();
}
If I apply an animation loop to my canvas, even weirder effects start to happen because of this issue.
Any ideas why this is happening?
Thank you.
Edit:
Here is the full project I am currently working on:
http://adam-day-com.stackstaging.com/orbital/index.html
Try checking the 'show vector field' box and add some planets. The function to draw the vector field (called in an animation loop) draws a series of thin boxes and it messes up the circle colors.
I added ctx.beginPath() and ctx.closePath() and things seem to working fine. Is this what you wanted? https://jsbin.com/ribiyodoru/edit?html,js,output
I am trying to achieve grass like bend on a straight line created by using Cubic bezier curve.I have created a straight line using Bezier curve and now i want to bend it from top.But the problem I am facing is I am not able to do it dynamically.The moment I use mousemove for creating the bend,series of curves appear giving the canvas a paint like look which is somthing I dont want.I just want a single curved line.My question is how do I clear the previous lines that have been drawn and restore the latest bended curve??
My CODE:here is my code if you want to have a look at it
Create two canvases stacked on top of each other:
The first one containing the static content, the other only the dynamic content.
This way you will only need to be concerned about clearing the area the grass was drawn in (and this is much faster too as there is no need to redraw static all the time).
Place the two canvases inside a div which have position set to relative, then place the canvases using position set to absolute.
Now you can make a function to draw the static content (you will need to redraw it if the browser window gets resized etc.).
Record the area the grass is drawn within and clear only this (for each grass) in the next frame.
If this last is too complicated, just use a simple clear on the "dynamic" canvas:
ctxDyn.clear(0, 0, canvasDyn.width, canvasDyn.height);
This will also preserve transparency of this canvas, or "layer" if you like.
Use requestAnimationFrame to do the actual animation.
var isPlaying = true;
function animate() {
ctxDyn.clear(0, 0, canvasDyn.width, canvasDyn.height);
drawGrass(); //function to draw the actual grass
if (isPlaying) requestAnimationFrame(animate);
}
animate(); // start
The isPlaying is a flag you can toggle with a button on screen or something similar, to be able to stop the animation. See the link for requestAnimationFrame on how to make this cross-browser as this is still a "young" implementation.
dynCtx and dynCanvas can of course be called what you want.
You need to erase the current contents of the canvas before redrawing your updated "grass". This would involve redrawing everything else that is "static" on the canvas. For example:
function redraw() {
// Erase the current contents
ctx.fillStyle = 'white';
ctx.fill(0, 0, canvas.width, canvas.height);
// Draw the stuff that does not change from frame to frame
drawStaticContent();
// Draw the dynamic content
drawGrass();
}
In your mousemove event, update your grass curve information, then 'redraw'.
I would like to export my canvas onto a PDF and only render the elements added to the canvas. For example:
I have this canvas, with a background-image set to it.
http://i49.tinypic.com/n7lv.png
This is my result when I render it to PDF (using Bytescout library)
http://i50.tinypic.com/346ud7m.png
This is how I want it to end up as:
http://i50.tinypic.com/2q1s9hv.png
Meaning, I want it to end up with no rounded corners, without the background image. The canvas is done using the fabric framework. My idea is to get all the elements added to the canvas, except background image, then render the PDF from there. Any guidelines? Is that the way to go?
You simply redraw the entire scene, omitting the parts you don't want to write to a PDF.
If you don't feel like keeping track of everything to redraw, then create a second, in-memory canvas (document.createElement('canvas')) and do every drawing operation to that canvas instead of your normal one, then draw that canvas onto your normal one as the user edits instead of drawing directly onto your normal canvas.
The old way:
// First you round the corners permanently by making a clipping region:
ctx.roundedRect(etc)
ctx.clip();
//then a user draws something onto normal canvas, like an image
ctx.drawImage(myImage, 0, 0);
The new way:
// make a hidden canvas:
var hiddenCanvas = document.createElement('canvas');
var hCtx = hiddenCanvas.getContext('2d');
// First you round the corners permanently by making a clipping region:
ctx.roundedRect(etc)
ctx.clip();
//then a user draws something onto HIDDEN canvas, like an image
// This image never gets its corners cut
hCtx.drawImage(myImage, 0, 0);
// Then you draw the hidden canvas onto your normal one:
ctx.drawImage(hiddenCanvas, 0, 0);
When its time to print, you use your hidden canvas, which does not have a background image and does not have clipped corners.