Reputation: 896
I am using below code:
<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>
I need the text effect like below images,I have tried a lot to make this but i cannot.
Can anyone please help me out?
Also can we use active object from fabric.js with context?
Upvotes: 6
Views: 8378
Reputation: 149
Thanks,
Above answer helped me a lot. But while working in typescript. I've faced issue while passing the simple text image in 'drawImage' function.
So, below is the modified changes of the above code as per the typescript/angular.
Html:
<canvas #simpleText id="simpleText" width=220 height=80></canvas>
<canvas #myCanvas id="myCanvas" width=800 height=400></canvas>
Initialization:
@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);
}
Main Function:
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);
}
}
}
Upvotes: 0
Reputation:
Here is a modified version of the original code (the provided code in question has changed values compared to my original code.. .-) ) which can produce all these shapes just by playing around with the parameters:
The roof is not super but I'll leave it to you to add scaling support as this is meant as an example.
Initialization:
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';
Main function:
/// 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);
}
}
Upvotes: 29