Reputation: 396
I am new to Canvas, I am creating a website to increase text as I re-sizes rectangle.I tried so much but nothing works for me. Actually I want if I re size rectangle just by its width( stretch To Left /To Right), only text width should be increased not the fontsize. I have done with fontsize but finding difficulty in increasing isolated Text Height and Width. your suggestions are most welcome
function Box2() {
this.x = 0;
this.y = 0;
this.w = 1; // default width and height?
this.h = 1;
this.fill = '#CC0000';
this.Owntext = "";
this.fontsize = '20';
this.TextColor = '';
this.TextFontFamily = '';
this.Angle = 0;
this.ScaleHeight = 1;
this.ScaleWidth = 1;
}
// New methods on the Box class
Box2.prototype = {
// we used to have a solo draw function
// but now each box is responsible for its own drawing
// mainDraw() will call this with the normal canvas
// myDown will call this with the ghost canvas with 'black'
draw: function (context, optionalColor) {
if (context === gctx) {
context.fillStyle = 'black'; // always want black for the ghost canvas
} else {
context.fillStyle = this.fill;
}
// alert('Box2.prototype');
// We can skip the drawing of elements that have moved off the screen:
if (this.x > WIDTH || this.y > HEIGHT) return;
if (this.x + this.w < 0 || this.y + this.h < 0) return;
context.fillRect(this.x, this.y, this.w, this.h);
// draw selection
// this is a stroke along the box and also 8 new selection handles
if (mySel === this) {
context.strokeStyle = mySelColor;
context.lineWidth = mySelWidth;
context.strokeRect(this.x, this.y, this.w, this.h);
// draw the boxes
var half = mySelBoxSize / 2;
// 0 1 2
// 3 4
// 5 6 7
// top left, middle, right
selectionHandles[0].x = this.x - half;
selectionHandles[0].y = this.y - half;
selectionHandles[1].x = this.x + this.w / 2 - half;
selectionHandles[1].y = this.y - half;
selectionHandles[2].x = this.x + this.w - half;
selectionHandles[2].y = this.y - half;
//middle left
selectionHandles[3].x = this.x - half;
selectionHandles[3].y = this.y + this.h / 2 - half;
//middle right
selectionHandles[4].x = this.x + this.w - half;
selectionHandles[4].y = this.y + this.h / 2 - half;
//bottom left, middle, right
selectionHandles[6].x = this.x + this.w / 2 - half;
selectionHandles[6].y = this.y + this.h - half;
selectionHandles[5].x = this.x - half;
selectionHandles[5].y = this.y + this.h - half;
selectionHandles[7].x = this.x + this.w - half;
selectionHandles[7].y = this.y + this.h - half;
context.fillStyle = mySelBoxColor;
for (var i = 0; i < 8; i++) {
var cur = selectionHandles[i];
context.fillRect(cur.x, cur.y, mySelBoxSize, mySelBoxSize);
}
}
} // end draw
}
//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill,text,FontSize,TextColor,TextFontFamily,Angle,ScaleWidth,ScaleHeight) {
var rect = new Box2;
rect.x = x;
rect.y = y;
rect.w = w
rect.h = h;
rect.Owntext = text;
rect.FontSize = FontSize;
rect.TextColor = TextColor;
rect.TextFontFamily = TextFontFamily;
rect.Angle = Angle;
rect.ScaleWidth = ScaleWidth;
rect.ScaleHeight = ScaleHeight;
// alert(TextFontFamily);
// rect.fontsize = FontSize;
// alert(fill);
rect.fill = fill;
boxes2.push(rect);
invalidate();
}
var CanvasHeight = 0;
var CanvasWidth = 0;
// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas
function init2() {
// alert('init2')
dropdownTextFamily = document.getElementById('drpFontFamily');
dropdown = document.getElementById('drpTextColor');
Button = document.getElementById('Mybtn');
canvas = document.getElementById('canvas2');
HEIGHT = canvas.height;
WIDTH = canvas.width;
// CanvasHeight=
ctx = canvas.getContext('2d');
ghostcanvas = document.createElement('canvas');
ghostcanvas.height = HEIGHT;
ghostcanvas.width = WIDTH;
gctx = ghostcanvas.getContext('2d');
//fixes a problem where double clicking causes text to get selected on the canvas
canvas.onselectstart = function () { return false; }
// fixes mouse co-ordinate problems when there's a border or padding
// see getMouse for more detail
if (document.defaultView && document.defaultView.getComputedStyle) {
stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
}
// make mainDraw() fire every INTERVAL milliseconds
setInterval(mainDraw, INTERVAL);
// set our events. Up and down are for dragging,
// double click is for making new boxes
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
Button.onclick = myDblClickButton;
dropdown.onchange = ChangeTextColor;
dropdownTextFamily.onchange = ChangeTextFontFamily;
// lblCheck.onclick = myclick;
// textBox.onkeyup = myDblClick;
// canvas.ondblclick = myDblClick;
// alert('ethe');
canvas.onmousemove = myMove;
// set up the selection handle boxes
for (var i = 0; i < 8; i++) {
// alert();
var rect = new Box2;
selectionHandles.push(rect);//WATCHED ******* A New Reactangle Added To The Canvas
}
// add custom initialization here:
// add a large green rectangle
// addRect(260, 70, 60, 65, 'rgba(0,205,0,0.7)');
// add a green-blue rectangle
// addRect(240, 120, 40, 40, 'rgba(2,165,165,0.7)');
// add a smaller purple rectangle
// addRect(45, 60, 25, 25, 'rgba(150,150,250,0.7)');
// get a reference to the canvas element, and its context
var canvas2 = document.getElementById('canvas2');
var ctx1 = canvas2.getContext('2d');
// sets maximum line width, line height, and x /y coords for text
var maxWidth = canvas2.width - 10;
var lineHeight = 23;
var x_pos = (canvas2.width - maxWidth) / 2;
var y_pos = 15;
var DbClickCount=0;
// register onkeyup event for #text_cnv text field to add the text in canvas as it is typed
document.getElementById('textBox').onkeyup = function () {
// clearCanvas(canvas2); // clears the canvas
//alert(ctx1);
// mySel.Owntext = this.value;
//alert(mySel.w);
if (mySel == null) {
// alert('I am Here');
myDblClick();
var x = 10;
var y = 10;
// alert(x);
myDown1(x, y);
addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, mySel.w);
// addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// myDown1();
// mySel.x = 260;
// mySel.y = 100;
// myDown1(260,100);
// mySel.h = 50;
// mySel.w = 5;
// addTextCnv(ctx1, this.value, 260, 100, 50, 5);
//// addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, mySel.w);
}
else
{
// addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// alert(mySel.x);
// alert(mySel.y);
// alert(mySel.h);
// alert(mySel.w);
addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, lineHeight);
}
//alert(mySel.x);
//addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// mainDraw(this.value);
//alert(this.value);
//addTextCnv(ctx1, this.value, x_pos, y_pos, maxWidth, 23);
}
var text2 = "Sachdeva";
// document.write("<p>Fontsize: " + text2.fontsize(6) + "</p>");
// text2.fontsize(6);
//alert(mySel.Owntext);
// ctx1.font = 'italic 20px Calibri';
ctx1.font = '20pt Calibri';
//TextFontFamily
var text1 = "rajay";
// var text3 = "rajay1";
// addRect(260, 70, 60, 15, 'rgba(0,205,0,0.7)',text1);
// add a smaller purple rectangle
// alert('hi');
// addRect(45, 60, 25, 15, 'rgba(150,150,250,0.7)', text2);
//addRect(260, 85, 60, 65, 'rgba(0,205,0,0.7)', text3);
}
function myMove(e) {
ctx = canvas.getContext('2d');
if (isDrag) {
// alert('hi');
getMouse(e);
// alert(e.x);
// alert('drag');
mySel.x = mx - offsetx;
// alert(mySel.x);
mySel.y = my - offsety;
// something is changing position so we better invalidate the canvas!
invalidate();
} else if (isResizeDrag) {
// alert('hi');
// time ro resize!
getMouse(e);
var oldx = mySel.x;
var oldy = mySel.y;
var oldw = mySel.w;
var oldh = mySel.h;
//alert(mySel.h);
//alert(expectResize)
switch (expectResize) {
case 0:
// mySel.x = mx;
// mySel.y = my;
// mySel.w += oldx - mx;
// mySel.h += oldy - my;
// mySel.ScaleWidth = 2;
// mySel.ScaleHeight = 1;
// alert(mySel.w);
// mySel.FontSize = (mySel.h/2)+(mySel.w/4);
// alert(mySel.FontSize);
// alert(mySel.h);
// alert(mySel.w);
// alert(mySel.Angle);
// var clickAngle = getAngle(mySel.x, mySel.y, mx, my) - mySel.Angle;
//alert(clickAngle);
//var clickAngle = getAngle(cX + offX, cY + offY, event.clientX, event.clientY) - model.angle;
// mySel.Angle = (getAngle(mySel.x, mySel.y, mx, my) - clickAngle);
// alert(mySel.Angle);
// mySel.Angle = 45;
// alert(mySel.Angle);
// alert(mySel.h);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
// ctx.font = 'italic ' + (2 / 3) * mySel.h+'px' + ' Calibri';
// alert(ctx.font);
break;
case 1:
mySel.y = my;
mySel.h += oldy - my;
// alert(mySel.h);
if (mySel.FontSize>mySel.h){
mySel.FontSize = mySel.h;
}
else
{
// alert('Hi');
mySel.FontSize = mySel.FontSize;
}
// mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.scale(1, 2);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 2:
mySel.y = my;
mySel.w = mx - oldx;
mySel.h += oldy - my;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 3:
mySel.x = mx;
mySel.w += oldx - mx;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
break;
case 4:
mySel.w = mx - oldx;
// mySel.FontSize = mySel.FontSize;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
break;
case 5:
mySel.x = mx;
mySel.w += oldx - mx;
mySel.h = my - oldy;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 6:
//mySel.h = my - oldy;
//mySel.FontSize = mySel.h;
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 7:
mySel.w = mx - oldx;
mySel.h = my - oldy;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
}
// alert(mySel.FontSize);
invalidate();
}
getMouse(e);
// if there's a selection see if we grabbed one of the selection handles
if (mySel !== null && !isResizeDrag) {
for (var i = 0; i < 8; i++) {
// 0 1 2
// 3 4
// 5 6 7
var cur = selectionHandles[i];
// alert('Here');
// we dont need to use the ghost context because
// selection handles will always be rectangles
if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
my >= cur.y && my <= cur.y + mySelBoxSize) {
// we found one!
expectResize = i;
invalidate();
switch (i) {
case 0:
this.style.cursor = 'nw-resize';
break;
case 1:
this.style.cursor = 'n-resize';
break;
case 2:
this.style.cursor = 'ne-resize';
break;
case 3:
this.style.cursor = 'w-resize';
break;
case 4:
this.style.cursor = 'e-resize';
break;
case 5:
this.style.cursor = 'sw-resize';
break;
case 6:
this.style.cursor = 's-resize';
break;
case 7:
this.style.cursor = 'se-resize';
break;
}
return;
}
}
// not over a selection box, return to normal
isResizeDrag = false;
expectResize = -1;
this.style.cursor = 'auto';
}
}
Upvotes: 3
Views: 5906
Reputation: 19294
You need to perform some computation to have the bounding box of the text, then use scale on the context to have it match the rect you want to fill.
You get the width of a text by using measureText. Unfortunately, only the text width is provided, but the height value is always close from the fontSize.
var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
function drawTextInBox(txt, font, x, y, w, h, angle) {
angle = angle || 0;
var fontHeight = 20;
var hMargin = 4;
ctx.font = fontHeight + 'px ' + font;
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
var txtWidth = ctx.measureText(txt).width + 2 * hMargin;
ctx.save();
ctx.translate(x+w/2, y);
ctx.rotate(angle);
ctx.strokeRect(-w/2, 0, w, h);
ctx.scale(w / txtWidth, h / fontHeight);
ctx.translate(hMargin, 0)
ctx.fillText(txt, -txtWidth/2, 0);
ctx.restore();
}
drawTextInBox('This is a line', 'Arial', 2, 2, 60, 20);
drawTextInBox('Another line here', 'Arial', 2, 32, 160, 40, 0.1);
drawTextInBox('The Last line', 'Arial', 2, 82, 220, 90);
drawTextInBox('! Now with an angle !', 'Arial', 42, 190, 120, 30, -Math.PI/12);
<canvas width=400 height=300 id='cv'></canvas>
Upvotes: 6