Javascript 如何在画布上创造不同的文字艺术设计?

Javascript 如何在画布上创造不同的文字艺术设计?,javascript,html,canvas,Javascript,Html,Canvas,我们正在尝试使用html5和画布创建文本艺术,如下图所示,但我们无法找到合适的参数来创建此类设计 这种文字艺术是否需要其他参数 提前感谢查看html5canvas网站,您可以在那里找到“工具包”,即文本、转换 textart的基础是平面文本。如果希望此平面文本呈波浪线,则必须使用变换来操纵文本,即通过在平面文本上应用贝塞尔曲线 看到这个JSFIDLE和这个线程了吗 html <table><TR><TH>Bezier Curve</TH><

我们正在尝试使用html5和画布创建文本艺术,如下图所示,但我们无法找到合适的参数来创建此类设计

  • 这种文字艺术是否需要其他参数

  • 提前感谢

    查看html5canvas网站,您可以在那里找到“工具包”,即文本、转换

    textart的基础是平面文本。如果希望此平面文本呈波浪线,则必须使用变换来操纵文本,即通过在平面文本上应用贝塞尔曲线

    看到这个JSFIDLE和这个线程了吗

    html

    <table><TR><TH>Bezier Curve</TH><TD>
        <input size="80" type="text" id="curve" name="curve" value="99.2,177.2,130.02,60.0,300.5,276.2,300.7,176.2">
        </TD></TR>
        <TR><TH>Text</TH><TD><input size="80" type="text" id="text" name="text" value="testing 1234567890"></TD></TR>
            <TR><TD colspan=2><div id="canvasDiv"></div></TD></TR>
        </table>
    
    贝塞尔曲线 正文 javascript

    var first = true;
    startIt();
    
    
    function startIt()
    {
        canvasDiv = document.getElementById('canvasDiv');
        canvasDiv.innerHTML = '<canvas id="layer0" width="300" height="300"></canvas>'; //for IE
        canvas = document.getElementById('layer0');
        ctx = canvas.getContext('2d');
        ctx.fillStyle = "black";
        ctx.font = "18px arial black";
        curve = document.getElementById('curve');
        curveText = document.getElementById('text');
        $(curve).keyup(function(e) {changeCurve();});
        $(curveText).keyup(function(e) {changeCurve();});
    
    
    
    
        if (first)
        {
            changeCurve();
            first = false;
        }
    
    }
    
    function changeCurve()
    {
    points = curve.value.split(',');  
        if (points.length == 8)
            drawStack();
    
    }
    
    function drawStack()
    {
        Ribbon = {maxChar: 50, startX: points[0], startY: points[1], 
                  control1X: points[2], control1Y: points[3], 
                  control2X: points[4], control2Y: points[5], 
                  endX: points[6], endY: points[7]};
    
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.save();
        ctx.beginPath();
    
        ctx.moveTo(Ribbon.startX,Ribbon.startY);
        ctx.bezierCurveTo(Ribbon.control1X,Ribbon.control1Y,
                       Ribbon.control2X,Ribbon.control2Y,
                       Ribbon.endX,Ribbon.endY);
    
        ctx.stroke();
        ctx.restore();
    
       FillRibbon(curveText.value,Ribbon); 
    }
    
    function FillRibbon(text,Ribbon)
    {
    
    var textCurve = [];
    var ribbon = text.substring(0,Ribbon.maxChar);
    var curveSample = 1000;
    
    
    xDist = 0;
    var i = 0;
    for (i = 0; i < curveSample; i++)
        {
            a = new bezier2(i/curveSample,Ribbon.startX,Ribbon.startY,Ribbon.control1X,Ribbon.control1Y,Ribbon.control2X,Ribbon.control2Y,Ribbon.endX,Ribbon.endY);
            b = new bezier2((i+1)/curveSample,Ribbon.startX,Ribbon.startY,Ribbon.control1X,Ribbon.control1Y,Ribbon.control2X,Ribbon.control2Y,Ribbon.endX,Ribbon.endY);
            c = new bezier(a,b);
            textCurve.push({bezier: a, curve: c.curve});
        }
    
    letterPadding = ctx.measureText(" ").width / 4; 
    w = ribbon.length;
    ww = Math.round(ctx.measureText(ribbon).width);
    
    
    totalPadding = (w-1) * letterPadding;
    totalLength = ww + totalPadding;
    p = 0;
    
    cDist = textCurve[curveSample-1].curve.cDist;
    
    z = (cDist / 2) - (totalLength / 2);
    
    for (i=0;i<curveSample;i++)
        {
            if (textCurve[i].curve.cDist >= z)
            {
                p = i;
                break;
            }
        }
    
    for (i = 0; i < w ; i++)
        {
            ctx.save();
            ctx.translate(textCurve[p].bezier.point.x,textCurve[p].bezier.point.y);
            ctx.rotate(textCurve[p].curve.rad);
            ctx.fillText(ribbon[i],0,0);
            ctx.restore();
    
            x1 = ctx.measureText(ribbon[i]).width + letterPadding ;
            x2 = 0; 
            for (j=p;j<curveSample;j++)
            {
            x2 = x2 + textCurve[j].curve.dist;
            if (x2 >= x1)
                {
                    p = j;
                    break;
                }
            }
    
    
    
    
        }
    } //end FillRibon
    
    function bezier(b1, b2)
    {
    //Final stage which takes p, p+1 and calculates the rotation, distance on the path and accumulates the total distance
    this.rad = Math.atan(b1.point.mY/b1.point.mX);
    this.b2 = b2;
    this.b1 = b1;
    dx = (b2.x - b1.x);
    dx2 = (b2.x - b1.x) * (b2.x - b1.x);
    this.dist = Math.sqrt( ((b2.x - b1.x) * (b2.x - b1.x)) + ((b2.y - b1.y) * (b2.y - b1.y)) );
    xDist = xDist + this.dist;
    this.curve = {rad: this.rad, dist: this.dist, cDist: xDist};
    }
    
    function bezierT(t,startX, startY,control1X,control1Y,control2X,control2Y,endX,endY)
    {
    //calculates the tangent line to a point in the curve; later used to calculate the degrees of rotation at this point.
    this.mx = (3*(1-t)*(1-t) * (control1X - startX)) + ((6 * (1-t) * t) * (control2X - control1X)) + (3 * t * t * (endX - control2X));
    this.my = (3*(1-t)*(1-t) * (control1Y - startY)) + ((6 * (1-t) * t) * (control2Y - control1Y)) + (3 * t * t * (endY - control2Y));
    }
    
    function bezier2(t,startX, startY,control1X,control1Y,control2X,control2Y,endX,endY)
    {
    //Quadratic bezier curve plotter
    this.Bezier1 = new bezier1(t,startX,startY,control1X,control1Y,control2X,control2Y);
    this.Bezier2 = new bezier1(t,control1X,control1Y,control2X,control2Y,endX,endY);
    this.x = ((1 - t) * this.Bezier1.x) + (t * this.Bezier2.x);
    this.y = ((1 - t) * this.Bezier1.y) + (t * this.Bezier2.y);
    this.slope = new bezierT(t,startX, startY,control1X,control1Y,control2X,control2Y,endX,endY);
    
    this.point = {t: t, x: this.x, y: this.y, mX: this.slope.mx, mY: this.slope.my};
    }
    function bezier1(t,startX, startY,control1X,control1Y,control2X,control2Y)
    {
    //linear bezier curve plotter; used recursivly in the quadratic bezier curve calculation
    this.x = (( 1 - t) * (1 - t) * startX) + (2 * (1 - t) * t * control1X) + (t * t * control2X);
    this.y = (( 1 - t) * (1 - t) * startY) + (2 * (1 - t) * t * control1Y) + (t * t * control2Y);
    
    }
    
    var first=true;
    startIt();
    函数startIt()
    {
    canvasDiv=document.getElementById('canvasDiv');
    canvasDiv.innerHTML='';//用于IE
    canvas=document.getElementById('layer0');
    ctx=canvas.getContext('2d');
    ctx.fillStyle=“黑色”;
    ctx.font=“18px arial黑色”;
    curve=document.getElementById('curve');
    curveText=document.getElementById('text');
    $(曲线).keyup(函数(e){changeCurve();});
    $(curveText).keyup(函数(e){changeCurve();});
    如果(第一)
    {
    改变曲线();
    第一个=假;
    }
    }
    函数变化曲线()
    {
    点=曲线.value.split(',');
    if(points.length==8)
    drawStack();
    }
    函数drawStack()
    {
    Ribbon={maxChar:50,startX:points[0],startY:points[1],
    control1X:点[2],control1Y:点[3],
    control2X:点[4],control2Y:点[5],
    endX:points[6],endY:points[7]};
    clearRect(0,0,canvas.width,canvas.height);
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(Ribbon.startX,Ribbon.startY);
    ctx.bezierCurveTo(Ribbon.control1X,Ribbon.control1Y,
    Ribbon.control2X,Ribbon.control2Y,
    Ribbon.endX,Ribbon.endY);
    ctx.stroke();
    ctx.restore();
    FillRibbon(curveText.value,Ribbon);
    }
    函数FillRibbon(文本,Ribbon)
    {
    var textCurve=[];
    var ribbon=text.substring(0,ribbon.maxChar);
    var曲线样本=1000;
    xDist=0;
    var i=0;
    对于(i=0;i

    另请参见此

    因为我喜欢绘画,所以我实现了您问题的两个概念文本艺术。
    即使看起来你不再在乎了,这也是为好奇的人准备的

    根本原因 为了达到上述效果,你需要利用一种基本上是2D的技术,虽然大大简化了,因为我们将保持左右边缘笔直

    本质上,它包括将一个正方形转换成不同的形状1

    蓝色方块代表绘制文本的图像,红色方块表示最终图像应如何“变形”。
    通过选择合适的
    1.   For X = 0 To Canvas.Width
    1.1     upperY = f_upper(x);
    1.2     lowerY = f_lower(x);
    1.3     Canvas.DrawImage(SrcCanvs, x, 0, 1, SrcCanvs.Height, x, upperY, 1, lowerY-upperY);