如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果
Posted
技术标签:
【中文标题】如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果【英文标题】:How to make rooftext effect and valley text effect in HTML5 (or Fabric.js) 【发布时间】:2013-11-01 21:49:16 【问题描述】:我正在使用以下代码:
<script type='text/javascript'>//<![CDATA[
window.onload=function()
/// (c) Ken Fyrstenberg Nilsen, Abidas Software .com
/// License: CC-Attribute
var ctx = demo.getContext('2d'),
font = '64px impact',
w = demo.width,
h = demo.height,
curve,
offsetY,
bottom,
textHeight,
angleSteps = 255/h,
i = h,
y,
os = document.createElement('canvas'),
octx = os.getContext('2d');
os.width = w;
os.height = h;
octx.font = font;
octx.textBaseline = 'top';
octx.textAlign = 'center';
function renderBridgeText()
curve = parseInt(iCurve.value, 10);
offsetY = parseInt(iOffset.value, 10);
textHeight = parseInt(iHeight.value, 10);
bottom = parseInt(iBottom.value, 10);
vCurve.innerhtml = curve;
vOffset.innerHTML = offsetY;
vHeight.innerHTML = textHeight;
vBottom.innerHTML = bottom;
octx.clearRect(0, 0, w, h);
ctx.clearRect(0, 0, w, h);
octx.fillText(iText.value, w * 0.5, 0);
/// slide and dice
i = w;
while (i--)
y = bottom + curve * Math.sin(i / angleSteps * Math.PI /160);
ctx.drawImage(os, i, offsetY, 1, textHeight,i,offsetY, 1, y);
iCurve.onchange = iOffset.onchange = iHeight.onchange = iBottom.onchange = iText.onkeyup = renderBridgeText;
renderBridgeText()
//]]>
</script>
</head>
<body>
<canvas id=demo width=600 height=300></canvas>
<br>
<span>Curve:</span>
<input id="iCurve" type="range" min=0 max=200 value=110>
<span id="vCurve">110</span>
<br><span>OffsetY:</span>
<input id="iOffset" type="range" min=0 max=100 value=4>
<span id="vOffset">0</span>
<br><span>Text height:</span>
<input id="iHeight" type="range" min=0 max=200 value=64>
<span id="vHeight">64</span>
<br><span>Bottom:</span>
<input id="iBottom" type="range" min=0 max=200 value=200>
<span id="vBottom">200</span>
<br><span>Text:</span>
<input id="iText" type="text" value="BRIDGE TEXT">
</body>
我需要像下图这样的文字效果,我做了很多尝试,但我做不到。
谁能帮帮我?
我们还可以使用带有上下文的 fabric.js 中的活动对象吗?
【问题讨论】:
查看 3D 变换属性,使用 perspective-origin() 可能会得到这种效果。没时间展示 jsFiddle ;P 一些信息:24ways.org/2010/intro-to-css-3d-transforms @Ken-AbdiasSoftware 我只是要求一些指导如何将这些上下文属性与 fabric.js 的活动对象一起使用 @Ken-AbdiasSoftware 好的,我将为 fabric.js 添加另一个问题。感谢您的帮助 【参考方案1】:这是原始代码的修改版本(所提供的代码与我的原始代码相比已更改了值..-)),只需使用参数即可生成所有这些形状:
屋顶不是超级好,但我会把它留给你来添加缩放支持,因为这只是一个例子。
ONLINE DEMO HERE
初始化:
var ctx = demo.getContext('2d'), /// context
font = '64px impact', /// font
w = demo.width, /// cache canvas width and height
h = demo.height,
curve, /// radius
offsetY, /// offset for text
bottom, /// bottom of text
textHeight, /// text height (region of text)
isTri = false, /// is triangle shaped (roof)
dltY, /// delta for triangle
angleSteps = 180 / w, /// angle steps for curved text
i = w, /// "x" backwards
y, /// top of text
/// offscreen canvas that holds original text
os = document.createElement('canvas'),
octx = os.getContext('2d');
os.width = w;
os.height = h;
/// set font on off-screen canvas where we draw it
octx.font = font;
octx.textBaseline = 'top';
octx.textAlign = 'center';
主要功能:
/// render
function renderBridgeText()
/// demo stuff snipped (see link)
/// clear canvases
octx.clearRect(0, 0, w, h);
ctx.clearRect(0, 0, w, h);
/// draw text (text may change)
octx.fillText(iText.value.toUpperCase(), w * 0.5, 0);
/// slide and dice
dltY = curve / textHeight; /// calculate delta for roof/triangle
y = 0; /// reset y in case we do roof
i = w; /// init "x"
while (i--)
if (isTri)
/// bounce delta value mid-way for triangle
y += dltY;
if (i === (w * 0.5)|0) dltY = -dltY;
else
/// calc length based on radius+angle for curve
y = bottom - curve * Math.sin(i * angleSteps * Math.PI / 180);
/// draw a slice
ctx.drawImage(os, i, 0, 1, textHeight,
i, h * 0.5 - offsetY / textHeight * y, 1, y);
【讨论】:
很棒的答案。谢谢你帮助我.. :) :) 使用上面相同的属性你能告诉我如何将它们用于fabric.js的活动对象吗? @Rash 抱歉,我对织物不熟悉(您的问题也没有用 fabric.js 标记)。如果答案有帮助,请不要忘记投票/接受。 你是怎么想到这个的? ... 并将这个漂亮的效果与 FabricJS 一起使用:创建一个新的 Fabric.Image(myNativeCanvasWithCurvedText) 来显示您的拱形文本。【参考方案2】:谢谢,
以上答案对我帮助很大。 但是在使用打字稿时。我在“drawImage”函数中传递简单的文本图像时遇到了问题。
所以,下面是根据 typescript/angular 对上述代码的修改。
HTML:
<canvas #simpleText id="simpleText" width=220 height=80></canvas>
<canvas #myCanvas id="myCanvas" width=800 height=400></canvas>
初始化:
@ViewChild('myCanvas', static: false) myCanvas: ElementRef<HTMLCanvasElement>;
context: CanvasRenderingContext2D;
@ViewChild('simpleText', static: false) simpleText: ElementRef<HTMLCanvasElement>;
simpleTextContext: CanvasRenderingContext2D;
// default values
shapeConfigure:any=
w : null,
h : null,
curve: 10 ,
offsetY: 50,
bottom: 200,
textHeight: 64,
isTri : false,
angleSteps : 0
;
// canvas width height
shapeCanvas=
w: 800,
h: 400
iText:string = 'check text';
sampleImage = new Image();
dataURL:any='';
ngAfterViewInit(): void
this.context = this.myCanvas.nativeElement.getContext('2d');
var font = '60px impact';
this.simpleTextContext = this.simpleText.nativeElement.getContext('2d');
this.simpleText.nativeElement.height=60;
this.simpleText.nativeElement.width=400;
this.simpleTextContext.font = font;
this.simpleTextContext.textBaseline = 'top';
this.simpleTextContext.textAlign = 'left';
this.simpleTextContext.fillText(this.iText.toUpperCase(), 200* 0.5, 0);
this.dataURL = this.simpleText.nativeElement.toDataURL();
console.log(this.dataURL);
this.sampleImage.src = this.dataURL;
this.shapeConfigure=
w : this.myCanvas.nativeElement.width,
h : this.myCanvas.nativeElement.height,
curve: 10 ,
offsetY: 50,
bottom: 200,
textHeight: 64,
isTri : false,
angleSteps : 180 /this.shapeCanvas.w
this.renderBridgeText(false);
主要功能:
renderBridgeText(textChange)
var curve = parseInt(this.shapeConfigure.curve, 10);
var offsetY = parseInt(this.shapeConfigure.offsetY, 10);
var textHeight = parseInt(this.shapeConfigure.textHeight, 10);
var bottom = parseInt(this.shapeConfigure.bottom, 10);
var isTri = this.shapeConfigure.isTri;
this.context.clearRect(0, 0, this.shapeCanvas.w , this.shapeCanvas.h );
if(textChange)
this.simpleTextContext.clearRect(0, 0, this.shapeCanvas.w , this.shapeCanvas.h );
this.simpleTextContext.fillText(this.iText.toUpperCase(), 200* 0.5, 0);
this.dataURL = this.simpleText.nativeElement.toDataURL();
this.sampleImage.src = this.dataURL;
this.sampleImage.onload = () =>
/// slide and dice
var i:number = this.shapeCanvas.w;
var dltY:number = curve / textHeight;
var y = 0;
while (i--)
if (isTri)
y += dltY;
if (i === (this.shapeCanvas.w * 0.5))
dltY = -dltY;
else
y = bottom - curve * Math.sin(i * this.shapeConfigure.angleSteps * Math.PI / 180);
this.context.drawImage(this.sampleImage, i, 0, 1, textHeight, i, this.shapeCanvas.h * 0.5 - offsetY / textHeight * y, 1, y);
【讨论】:
以上是关于如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果的主要内容,如果未能解决你的问题,请参考以下文章
在 html5 中的 fabric.js 画布上一次删除多个对象
Html5 Canvas + fabric.js 的独立堆肥