【问题标题】:How scale all the points used to make lines/curves on a canvas?如何缩放用于在画布上制作线条/曲线的所有点?
【发布时间】:2013-10-11 03:15:31
【问题描述】:

我正在通过mousedownmousemove 事件记录在画布上绘制的所有点。当画布调整大小时(例如,如果它是 100w x 200h,而用户将其设为 200w x 400h),我想重绘所有这些点/线,但要以新的比例。这样做的正确方法是什么?

我目前正在使用如下代码,但无法正确绘制。它会画出奇怪的额外线条。

为了保存点,我在mousedownmousemove 中记录了点,并在mouseup 中将一行标记为完成。

在调整大小事件时调用:

//The new ratios
var wRatio = canvas.width / oldWidth;
var hRatio = canvas.height / oldHeight;

//We need to scale and draw all our points
for ( var i = 0, last = savedPoints.length - 1; i < last; i++ ) {
    var start = savedPoints[ i ];
    var end = savedPoints[ i + 1 ];

    //We're at a new line
    if ( start === "stopline" ) continue;

    //We're finishing a previous line
    else if ( end === "stopline" ) {
        i++;
        continue;
    }

    //Resize them
    start.x = start.x * wRatio;
    start.y = start.y * hRatio;
    end.x = end.x * wRatio;
    end.y = end.y * hRatio;

    //These lines don't make a difference
    //savedPoints[ i ] = start;
    //savedPoints[ i + 1 ] = end;

    //Start recording
    context.beginPath();

    //Move the "pen" to the point
    context.moveTo( start.x, start.y );

    //Make the connection of the "line" with our data (I draw the lines originally this way to make more "natural")
    context.quadraticCurveTo( start.x, start.y, end.x, end.y );

    //This doesn't work either
    //context.lineTo( start.x, start.y, end.x, end.y );

    //Draw the line
    context.stroke();
}

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    我认为您的问题是您通过startend 对象修改savedPoints[i]savedPoints[i+1],将比率应用于每个点。下一次迭代,i = i+1savedPoints[i] 将已经被修改一次。

        //The new ratios
        var wRatio = canvas.width / oldWidth;
        var hRatio = canvas.height / oldHeight;
    
        //We need to scale and draw all our points
        for ( var i = 0, last = savedPoints.length - 1; i < last; i++ ) {
            var start = savedPoints[ i ];
            var end = savedPoints[ i + 1 ];
            var endx, endy, startx, starty;
    
            //We're at a new line
            if ( start === "stopline" ) continue;
    
            //We're finishing a previous line
            else if ( end === "stopline" ) {
                i++;
                continue;
            }
    
            //Resize them
            startx = start.x * wRatio;
            starty = start.y * hRatio;
            endx = end.x * wRatio;
            endy = end.y * hRatio;
    
            //Start recording
            context.beginPath();
    
            //Move the "pen" to the point
            context.moveTo( startx, starty );
    
            //Make the connection of the "line" with our data (I draw the lines originally this way to make more "natural")
            context.quadraticCurveTo( startx, starty, endx, endy );
    
            //This doesn't work either
            //context.lineTo( startx, starty, end.x, end.y );
    
            //Draw the line
            context.stroke();
        }
    
        for ( var i = 0, last = savedPoints.length - 1; i < last; i++ ) {
            if (savedPoints[i] !== 'stopline') {
                savedPoints[i].x *= wRatio;
                savedPoints[i].y *= hRatio;
            }
        }
    

    【讨论】:

    • 谢谢,解决了画错问题!但现在我看到图像没有调整大小。我所做的只是改变 x/y,而不是它们之间的距离(所以如果我画一个 X,它总是保持相同的大小)。你知道怎么计算吗?
    • 您能否稍微修改一下您的答案,以便我将其标记为答案?它所需要的只是:在循环中,更改为 startX = start.x * wRatio 和 startY 相同(就像你对 endX/endY 所做的那样),然后在末尾放置一个循环以将比率保存回 savedPoints 数组。 (我发现它只有在第一个循环完成后保存比率才有效)
    • 添加了您要求的更改。它未经测试,但我相信它会正常工作。
    • 谢谢,只有两个小错误。您的 context.moveTo( start.x, start.y );context.quadraticCurveTo( start.x, start.y, endx, endy ); 使用的是 start.xstart.y 而不是 startXstartY 局部变量。你能改一下吗?
    猜你喜欢
    • 2021-01-09
    • 1970-01-01
    • 2023-04-03
    • 2021-10-30
    • 1970-01-01
    • 2014-07-19
    • 2013-03-06
    • 2013-07-07
    • 1970-01-01
    相关资源
    最近更新 更多