<script>
// (B) IMAGES + CANVAS
var iBack = new Image(),
iMark = "long text",
canvas = document.getElementById("demo"),
ctx = canvas.getContext("2d");
// (C) WATERMARK
function cmark () {
// (C1) ADD BACKGROUND IMAGE
canvas.width = iBack.naturalWidth;
canvas.height = iBack.naturalHeight;
ctx.drawImage(iBack, 100, 100, iBack.naturalWidth, iBack.naturalHeight);
// (C2) ADD WATERMARK
ctx.font = "bold 24px Arial";
ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
ctx.fillText(iMark, 10, 100);
ctx.fillText("width:" + ctx.measureText(iMark).width, 100, 50);
/* (C3) DOWNLOAD (IF YOU WANT)
let anchor = document.createElement("a");
anchor.href = canvas.toDataURL("image/png");
anchor.download = "marked.png";
anchor.click();
anchor.remove();*/
}
// (D) GO - PROCEED ONLY WHEN IMAGES ARE LOADED
iBack.onload = cmark;
iBack.src = "image.jpg";
</script>
When I write long text, it takes it out of the picture. I don't want it to spill out of the picture. How can I fix the canvas text overflowing the image? Can you help me?
You can draw only one line of text at a time with filltext(), so you need to split you text into several parts when it's too long. You can use measureText(iMark)to measure the length of you text, :
if (measureText(iMark)>100) {
let temp1 = iMark.slice(0,iMark.length/2);
let temp2 = iMark.slice(iMark.length/2,iMark.length);
ctx.fillText(temp1, 10, 100);
ctx.fillText(temp1, 10, 200);
}
Related
I am attempting to make a dynamic canvas where when the user types text, the canvas rerenders for the text so the canvas width (and height) is the same as the text. I followed some guide that essentially said to create a script like this
Codesandbox.com Live Link: https://codesandbox.io/s/tender-sound-zk5x6h?file=/src/App.js
function ResizeCanvas(textInput) {
const canvas3 = canvasRef.current;
const canvasContext = canvas3.getContext("2d");
canvasContext.font = "40 40px arial";
canvasContext.fillStyle = "red";
canvasContext.textAlign = "left";
canvasContext.fillText(textInput, 0, canvas3.height - 1);
canvas3.width = canvasContext.measureText(textInput).width;
canvas3.style.width = canvas3.width + "px";
canvasContext.font = "40 40px arial";
canvasContext.fillStyle = "red";
canvasContext.textAlign = "left";
canvasContext.fillText(textInput, 0, canvas3.height - 1);
}
However, the bottom text is cut off. I noticed when I add a paddingBottom: "20px" to the canvas element, it doesnt show the rest of the text and increasing the height does not change anything.
How come I cannot see the full p, q letters?
I can really use some help, my goal is to add few lines to the canvas in different places, it means to use the function drawText few times, for some reason if I don't use drawText inside the onload of drawImage the text does not rendering I am really stuck and can use some help, my main target it to make website that can edit pictures and make memes (e.g.: https://imgflip.com/memegenerator)and adding text line is what i am getting stuck on because I don't understand how to render new text line while save the old one, every time i start new line its like the image rendering all over again and start from the beginning.
// Function to load image on the canvas
function drawImg(url) {
gCurrLineIdx = getCurrLineIdx();
let currLine = gMeme.lines[gCurrLineIdx];
const img = new Image();
img.src = url;
img.onload = () => {
gCtx.drawImage(img, 0, 0, gElCanvas.width, gElCanvas.height);
//If you dont call drawText the text does not render to the canvas
drawText(currLine.txt, currLine.size, currLine.fontColor, currLine.strokeColor, currLine.align, currLine.font, gElCanvas.width / 2, currLine.y);
};
}
// Function to add text on the canvas
function drawText(text = '', fontSize = 20, fontColor = 'white', strokeColor = 'black', align = 'center', font = "ariel", x = gElCanvas.width / 2, y = 20) {
gCtx.strokeStyle = strokeColor;
gCtx.fillStyle = fontColor;
gCtx.font = `${fontSize}px ${font}`;
gCtx.textAlign = align;
gCtx.fillText(text, x, y);
gCtx.strokeText(text, x, y);
}
//Function to add new text line on the canvas.
function onAddTextLine() {
let textInput = document.getElementById('text-input');
textInput.value = '';
addTextLine();
gCurrLineIdx = getCurrLineIdx();
var currLine = gMeme.lines[gCurrLineIdx];
drawText(currLine.txt, currLine.size, currLine.fontColor, currLine.strokeColor, currLine.align, currLine.font, gElCanvas.width / 2, currLine.y);
}
The question I see here is:
how to render new text line while save the old one
Looks like in your code you are drawing things independently, below is a different approach the class Meme has a few functions to add text and image but every time anything change the entire canvas is cleared (clearRect) and every element is re-drawn, the magic is in the this.draw(), that is the call to the common function that does all the drawing.
To keep my sample small I hard-coded many of the things you had as parameters, it should be easy for you to reintroduce them if you need
class Meme {
constructor(ctx, width, height) {
this.ctx = ctx;
this.ctx.font = '80px Arial';
this.ctx.fillStyle = "blue"
this.ctx.textAlign = "center"
this.width = width;
this.height = height;
}
addHeadText(text) {
this.htext = text;
this.draw();
}
addFootText(text) {
this.ftext = text;
this.draw();
}
addImage(image_src) {
this.image = new Image();
this.image.src = image_src;
this.image.onload = () => {
this.draw()
};
}
draw() {
this.ctx.beginPath();
this.ctx.clearRect(0, 0, this.width, this.height)
if (this.image) {
this.ctx.drawImage(this.image, 0, 0, this.width, this.height);
}
if (this.htext) {
this.ctx.textBaseline = "top";
this.ctx.fillText(this.htext, this.width / 2, 0);
}
if (this.ftext) {
this.ctx.textBaseline = "bottom";
this.ctx.fillText(this.ftext, this.width / 2, this.height);
}
this.ctx.closePath();
}
}
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
meme = new Meme(ctx, canvas.width, canvas.height)
meme.addHeadText("Hello");
meme.addFootText("World");
meme.addImage("http://i.stack.imgur.com/UFBxY.png");
document.getElementById('htext').onkeyup = (event) => {
meme.addHeadText(event.srcElement.value);
};
document.getElementById('ftext').onkeyup = (event) => {
meme.addFootText(event.srcElement.value);
};
Head Text:<input type="text" id="htext" name="ftext" style="width: 140px;" value="Hello"><br>
Foot Text:<input type="text" id="ftext" name="ftext" style="width: 140px;" value="World"><br>
<canvas id="c" width=280 height=380 style="border:2px solid red;"></canvas>
I want to create a canvas element and put an image inside.
Before that I want to drawn anything in canvas em get back the image and put in my div
like this
//CREATE A CANVAS ELEMENT
$("#palco").html("<canvas width='"+largura+"' height='"+altura+"' id='canvas_zoom' >");
var canvas = document.getElementById('canvas_zoom');
var ctx = canvas.getContext('2d');
//CREAT AND DRAWN AN IMAGE
var img = new Image();
img.src = src_img;
ctx.beginPath();
ctx.drawImage(img, 0, 0);
//DRAW WHATEVER I WANT
//GER POSITONS LINES Y
$("#recortar_selecoes").find(".changeliney").each(function () {
ctx.fillStyle = "rgba(255, 11, 211, 0.40)";//cor do preenchimento
ctx.fillRect((parseInt($(this).val()) - 15), 0, 15, altura);//background
})
//GER POSITONS LINES X
$("#recortar_selecoes").find(".changelinex").each(function () {
ctx.fillStyle = "rgba(21, 252, 255, 0.40)";//cor do preenchimento
ctx.fillRect(0, (parseInt($(this).val()) - 15), largura, 15);//background
})
ctx.closePath();
//NOW HERE I WANT TO APPEND AN IMAGE IN DIV ID #palco
$("#palco").html("???????????????")
what should I do in "???????????"
Thank you guys
I got it
var dataURL = canvas.toDataURL();
$("#palco").html("<image width='"+largura+"' height='"+altura+"' id='zoom' src='"+dataURL+"' >");
I want to develop extension for magento which help to create custom t-shirt but i don't know how to do it.I want to provide functionality like this site http://www.inkpixi.com/item/ATV+Repair/A252/329/item.htmlDead link
here you enter the name and then name automatically insert to image .i want to provide this exactly but didn't get right matter
You can do it so simply with canvas
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 200;
document.body.appendChild(canvas);
function sendToCanvas( ob ){
var img = new Image();
img.addEventListener('load', function(){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.font = ob.fontWeight+' '+ob.fontSize+' '+ob.fontFamily;
ctx.textAlign = 'center';
ctx.fillStyle = ob.color;
ctx.fillText(ob.text, canvas.width/2, canvas.height/2.5);
});
img.src = ob.image;
}
// Defaults
var cvsObj = {
text : "stackoverflow",
image : "http://i.imgur.com/hqayV16.jpg",
fontFamily : "Arial",
fontWeight : "bold",
fontSize : "90%",
color : "rgba(244, 128, 36, 0.7)"
};
sendToCanvas( cvsObj ); // Send default data on init
document.getElementById("text").addEventListener("input", function(){
cvsObj.text = this.value; // Modify cvsObj text
sendToCanvas( cvsObj ); // Send custom data on input
});
Text: <input id="text" type="text"><br>
Right click and Save as :) !
I am trying to use toDataURL in Html5 Canvas to export an image to a PNG file in a new window.
Here's my JS code (I think you guys need to see it all to check if there's something wrong)
var oCtx;
var oCanvas;
var img;
var oImg;
function updateClicked() {
oCanvas.width = oCanvas.width;
oCtx.drawImage(img,0,0);
oCtx.font = "normal 23px arial"; // different font
oCtx.textBaseline = "top"; // text baseline at the top
oCtx.fillStyle = "#666";
oCtx.fillText(document.getElementById("attentionde").value, 255, 365);
oCtx.font = "bold 28px arial"; // different font
oCtx.fillStyle = "red";
oCtx.fillText(document.getElementById("nofacture").value, 172, 226);
}
// setup our test canvas
// and a simple drawing function
window.onload = function() {
oCanvas = document.getElementById("thecanvas");
oCtx = oCanvas.getContext("2d");
var iWidth = oCanvas.width;
var iHeight = oCanvas.height;
img=new Image();
img.src="Fond_Facture_Medio.jpg"; //My background image source
//BACKGROUND-IMAGE//
img.onload = function(){
oCtx.drawImage(img,0,0);
};
var dataUrl = oCanvas.toDataURL();
var button = document.getElementById("thebutton");
button.onclick =function() {
window.open(dataUrl, "toDataURL() image", "width=1275, height=1650");
}
}
When I click on my button (id="thebutton")...it does open a new window with a PNG file in it, but the png is blank...Seems like it does not get the images drawn in the Canvas for a unknown reason.
I tried adding this code right before the var dataUrl = oCanvas.toDataURL(); line :
oCtx.fillStyle = "rgba(0, 0, 255, .5)";
oCtx.fillRect(25, 25, 125, 125);
Just to test if I was drawing a shape, it would save it through the dataURL process.
When I tested it, by clicking on the "thebutton" button, it opened a new window, and voila! I was able to see and save the canvas image with a light-blue rectangle in it...but no backgroud-image, and no text...nothing else. I really don't understand what's wrong. Thank you!
Move this line
var dataUrl = oCanvas.toDataURL();
inside the button.onclick handler.
At the moment you create the data URL, neither the window element nor any img element fired its load event, so nothing has been drawn.