如何在HTML5(或Fabric.js)中制作屋顶文字效果和谷文字效果

时间:2013-10-23 14:36:45

标签: html5 canvas html5-canvas fabricjs

我正在使用以下代码:

<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>

我需要像下面的图像一样的文字效果,我已经尝试了很多,但我不能。

enter image description here

enter image description here

有人可以帮帮我吗?

我们也可以使用fabric.js中的活动对象和上下文吗?

2 个答案:

答案 0 :(得分:25)

以下是原始代码的修改版本(所提供的代码与我的原始代码相比已更改了值... .-)),只需通过使用参数即可生成所有这些形状:

Valley

Roof

Roof inversed

Bridge

屋顶不是超级但我会留给你添加缩放支持,因为这是一个例子。

<强> 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);
    }
}

答案 1 :(得分:0)

谢谢

以上回答对我有很大帮助。 但是在打字稿中工作。在'drawImage'函数中传递简单文本图像时遇到了问题。

因此,下面是根据打字稿/角度对上述代码进行的修改。

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);
        }
        }
    }