How to make rooftext effect and valley text effect in HTML5 (or Fabric.js)

后端 未结 2 726
迷失自我
迷失自我 2020-11-27 19:47

I am using below code:



        
相关标签:
2条回答
  • 2020-11-27 20:33

    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);
            }
            }
        }
    
    0 讨论(0)
  • 2020-11-27 20:35

    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:

    Valley

    Roof

    Roof inversed

    Bridge

    The roof is not super but I'll leave it to you to add scaling support as this is meant as an example.

    ONLINE DEMO HERE

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题