html 自动包裹内容,HTML5画布:自动字体大小绘制包裹旋转的文本

您不必查找字体大小以使其合适。根据当前的转换规模,字体将平滑地放大和缩小。

你要做的就是measureText找到它textWidth,从context.font属性得到pointSize那么如果你有width,你需要适应,然后找出最小的width/textWidth和height/pointSize的盒子height,你有规模你需要渲染字体。

作为功能

var scale2FitCurrentFont = function(ctx, text, width, height){

var points, fontWidth;

points = Number(ctx.font.split("px")[0]); // get current point size

points += points * 0.2; // As point size does not include hanging tails and

// other top and bottom extras add 20% to the height

// to accommodate the extra bits

var fontWidth = ctx.measureText(text).width;

// get the max scale that will allow the text to fi the current font

return Math.min(width/fontWidth, height/points);

}

的参数是

CTX是当前上下文提请

文本文本绘制

宽度宽度使文字符合

高度高度与文本适合

返回规模以适应宽度和高度中的文本。

该演示将所有内容整合在一起,并绘制随机框,并用随机文本填充问题。它使字体选择和点大小与字体缩放分开,所以你可以看到它可以适用于任何字体和任何点的大小。

var demo = function(){

/** fullScreenCanvas.js begin **/

var canvas = (function(){

var canvas = document.getElementById("canv");

if(canvas !== null){

document.body.removeChild(canvas);

}

// creates a blank image with 2d context

canvas = document.createElement("canvas");

canvas.id = "canv";

canvas.width = window.innerWidth;

canvas.height = window.innerHeight;

canvas.style.position = "absolute";

canvas.style.top = "0px";

canvas.style.left = "0px";

canvas.style.zIndex = 1000;

canvas.ctx = canvas.getContext("2d");

document.body.appendChild(canvas);

return canvas;

})();

var ctx = canvas.ctx;

/** fullScreenCanvas.js end **/

/** FrameUpdate.js begin **/

var w = canvas.width;

var h = canvas.height;

var cw = w/2;

var ch = h/2;

var PI2 = Math.PI * 2; // 360 to save typing

var PIh = Math.PI/2; // 90

// draws a rounded rectangle path

function roundedRect(ctx,x, y, w, h, r){

ctx.beginPath();

ctx.arc(x + r, y + r, r, PIh * 2, PIh * 3);

ctx.arc(x + w - r, y + r, r, PIh * 3, PI2);

ctx.arc(x + w - r, y + h - r, r, 0, PIh);

ctx.arc(x + r, y + h - r, r, PIh, PIh * 2);

ctx.closePath();

}

// random words

var question = "Suppose that there is a text to be drawn inside a rotated bounding rectangle (not aligned to normal axes x-y), and that text can be also rotated, given the max width of the bounding box, how to select the best font size to use to draw a wrapped text inside that bounding box in html5 canvas and javascript? I know that method: measureText() can measure dimensions of give font size, but I need the inverse of that: using a known width to get the problem font size. thanks.";

question = question.split(" ");

var getRandomWords= function(){

var wordCount, firstWord, s, i, text;

wordCount = Math.floor(rand(4)+1);

firstWord = Math.floor(rand(question.length - wordCount));

text = "";

s = "";

for(i = 0; i < wordCount; i++){

text += s + question[i + firstWord];

s = " ";

}

return text;

}

// fonts to use?? Not sure if these are all safe for all OS's

var fonts = "Arial,Arial Black,Verdanna,Comic Sans MS,Courier New,Lucida Console,Times New Roman".split(",");

// creates a random font with random points size in pixels

var setRandomFont = function(ctx){

var size, font;

size = Math.floor(rand(10, 40));

font = fonts[Math.floor(rand(fonts.length))];

ctx.font = size + "px " + font;

}

var scale2FitCurrentFont = function(ctx, text, width, height){

var points, fontWidth;

var points = Number(ctx.font.split("px")[0]); // get current point size

points += points * 0.2;

var fontWidth = ctx.measureText(text).width;

// get the max scale that will allow the text to fi the current font

return Math.min(width/fontWidth, height/points);

}

var rand = function(min, max){

if(max === undefined){

max = min;

min = 0;

}

return Math.random() * (max - min)+min;

}

var randomBox = function(ctx){

"use strict";

var width, height, rot, dist, x, y, xx, yy,cx, cy, text, fontScale;

// get random box

width = rand(40, 400);

height = rand(10, width * 0.4);

rot = rand(-PIh,PIh);

dist = Math.sqrt(width * width + height * height)

x = rand(0, ctx.canvas.width - dist);

y = rand(0, ctx.canvas.height - dist);

xx = Math.cos(rot);

yy = Math.sin(rot);

ctx.fillStyle = "white";

ctx.strokeStyle = "black";

ctx.lineWidth = 2;

// rotate the box

ctx.setTransform(xx, yy, -yy, xx, x, y);

// draw the box

roundedRect(ctx, 0, 0, width, height, Math.min(width/3, height/3));

ctx.fill();

ctx.stroke();

// get some random text

text = getRandomWords();

// get the scale that will fit the font

fontScale = scale2FitCurrentFont(ctx, text, width - textMarginLeftRigth * 2, height - textMarginTopBottom * 2);

// get center of rotated box

cx = x + width/2 * xx + height/2 * -yy;

cy = y + width/2 * yy + height/2 * xx;

// scale the transform

xx *= fontScale;

yy *= fontScale;

// set the font transformation to fit the box

ctx.setTransform(xx, yy, -yy, xx, cx, cy);

// set up the font render

ctx.fillStyle = "Black";

ctx.textAlign = "center";

ctx.textBaseline = "middle"

// draw the text to fit the box

ctx.fillText(text, 0, 0);

}

var textMarginLeftRigth = 8; // margin for fitted text in pixels

var textMarginTopBottom = 4; // margin for fitted text in pixels

var drawBoxEveryFrame = 60; // frames between drawing new box

var countDown = 1;

// update function will try 60fps but setting will slow this down.

function update(){

// restore transform

ctx.setTransform(1, 0, 0, 1, 0, 0);

// fade clears the screen

ctx.fillStyle = "white"

ctx.globalAlpha = 1/ (drawBoxEveryFrame * 1.5);

ctx.fillRect(0, 0, w, h);

// reset the alpha

ctx.globalAlpha = 1;

// count frames

countDown -= 1;

if(countDown <= 0){ // if frame count 0 the draw another text box

countDown = drawBoxEveryFrame;

setRandomFont(ctx);

randomBox(ctx);

}

if(!STOP){ // do until told to stop.

requestAnimationFrame(update);

}else{

STOP = false;

}

}

update();

}

// demo code to restart on resize

var STOP = false; // flag to tell demo app to stop

function resizeEvent(){

var waitForStopped = function(){

if(!STOP){ // wait for stop to return to false

demo();

return;

}

setTimeout(waitForStopped,200);

}

STOP = true;

setTimeout(waitForStopped,100);

}

window.addEventListener("resize",resizeEvent);

demo();

/** FrameUpdate.js end **/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值