You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas图像底部宽度收窄适配折叠杯的技术问询

解决折叠杯图像适配的底部收窄变形问题

我看了你的代码,发现你之前尝试用垂直切片来贴合折叠杯的轮廓,但核心逻辑没抓对——我们需要的是元素图的水平宽度随高度逐渐收窄,匹配杯子从顶到底的收缩形状,而不是调整垂直偏移。下面是调整后的完整方案,能完美实现你要的效果:

修改后的代码

canvas2(getFullElementImage);
function canvas2(getFullElementImage) {
    var canvas = document.getElementById("finalCanvas");
    var ctx = canvas.getContext("2d");
    var productImg = new Image();
    productImg.onload = function () {
        var iw = productImg.width;
        var ih = productImg.height;
        canvas.width = iw;
        canvas.height = ih;
        // 先绘制折叠杯底图
        ctx.drawImage(productImg, 0, 0, iw, ih);
        loadUpperImage();
    };
    productImg.src = "https://res.cloudinary.com/faizykhan1212/image/upload/v1550583008/folded_cup_1.png";

    function loadUpperImage() {
        var img = new Image();
        img.src = getFullElementImage;
        img.onload = function () {
            var elemWidth = img.width;
            var elemHeight = img.height;
            
            // 折叠杯的关键适配参数(根据实际杯子图调整)
            var cupTopWidth = 190;    // 杯子顶部的有效宽度
            var cupBottomWidth = 120; // 杯子底部的有效宽度
            var cupHeight = 574;      // 杯子需要覆盖的高度
            var xOffset = 160;        // 元素图相对于杯子的X偏移
            var yOffset = 110;        // 元素图相对于杯子的Y偏移

            // 计算宽度收缩的比例系数
            var widthShrinkRate = (cupBottomWidth - cupTopWidth) / cupHeight;

            // 逐行绘制元素图的切片,实现底部收窄
            for (var y = 0; y < cupHeight; y += 1) {
                // 计算当前高度对应的宽度:从顶部宽度线性收缩到底部宽度
                var currentWidth = cupTopWidth + widthShrinkRate * y;
                // 计算元素图对应的水平切片比例
                var sliceScale = currentWidth / cupTopWidth;
                // 计算元素图中要截取的宽度
                var elemSliceWidth = elemWidth * sliceScale;
                // 计算元素图截取的起始X位置(居中对齐)
                var elemStartX = (elemWidth - elemSliceWidth) / 2;

                // 绘制当前行的切片
                ctx.drawImage(
                    img,
                    elemStartX, y * (elemHeight / cupHeight), elemSliceWidth, elemHeight / cupHeight,
                    xOffset + (cupTopWidth - currentWidth) / 2, yOffset + y, currentWidth, 1
                );
            }
        };
    }
};

关键逻辑解释

  • 参数化适配:我把杯子的顶部宽度、底部宽度、高度都做成了可调整的参数,你可以根据实际杯子的像素尺寸微调这些值,适配更精准。
  • 线性宽度收缩:通过widthShrinkRate计算每一行的宽度变化,让元素图从顶部的满宽,线性收缩到底部的窄宽,完美贴合折叠杯的侧边轮廓。
  • 居中对齐切片:每次绘制切片时,计算元素图的居中截取位置,保证图案不会偏移,始终在杯子的中心区域。
  • 逐行绘制替代垂直切片:原来的垂直切片逻辑是固定宽度调整Y偏移,现在改成逐行绘制,调整每一行的宽度,这样能精准控制高度方向的收缩效果。

如果你想要更贴合杯子的弧形轮廓,可以把线性收缩换成曲线计算(比如二次贝塞尔曲线),只需要修改currentWidth的计算方式即可,比如:

// 用二次曲线实现弧形收缩(示例,可调整控制点)
var curveFactor = (y / cupHeight) ** 2;
var currentWidth = cupTopWidth - (cupTopWidth - cupBottomWidth) * curveFactor;

内容的提问来源于stack exchange,提问作者R1222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:54:23