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

.NET Core中Konva.js与HTML5 Canvas的跨设备图片变形问题

问题:Konva.js Canvas图片变形与清晰度问题

在.NET Core项目中使用Konva.js操作HTML5 Canvas时,Logo放置到Canvas上出现严重变形,移动端问题比桌面端更突出:

移动端表现

  • Logo初始放置到Canvas时存在轻微变形
  • 保存图片后变形程度大幅加剧,内容显示异常

桌面端表现

  • Logo初始放置到Canvas时存在轻微变形
  • 保存图片后内容可见,但清晰度未达预期

期望实现效果

  • 任意设备下,将任意尺寸的图片添加到Canvas后,保存时能与Canvas完美融合,无变形
  • 桌面端图片显示清晰
  • 任意设备上传的图片,在其他设备上均能完美显示

相关实现代码

JavaScript代码

$(document).ready(function () {
    debugger
    var x = 0;
    var y = 0;
    var objectOrgin = "";
    var stepname = $('.step-name').val();
    var productId = $('.product-id').val();
    var position = $('.position').val();
    var searchUrl = stepname == "sponsorlogo" ? '/umbraco/surface/DYO/GetCoOrdinatesForSponsorLogoWithObjectOrgin' : '/umbraco/surface/DYO/GetCoOrdinatesForClubLogoWithObjectOrgin';
    $.ajax({
        url: searchUrl,
        method: 'GET',
        data: { productId: productId, position: position },
        async: false,
        success: function (response) {
            if (response != null) {
                x = response.X;
                y = response.Y;
                objectOrgin = response.ObjectOrgin.toLowerCase();
            }
        },
        error: function (error) {
            console.log('Error:', error);
        }
    });

    var img = document.getElementsByClassName("hidden-image")[0];
    img.src = item.Image;
    var ImgURL = localStorage.getItem('MyLogoImage');
    var ResizedImage = new Image();
    ResizedImage.src = ImgURL;

    ResizedImage.onload = function () {
        var width = 749;
        var height = 496;
        var max_width = 650;
        var max_height = 430;
        if (ResizedImage.width > ResizedImage.height) {
            if (ResizedImage.width > max_width) {
                ResizedImage.height = Math.round(ResizedImage.height * (max_width / ResizedImage.width));
                ResizedImage.width = max_width;
            }
        } else {
            if (ResizedImage.height > max_height) {
                ResizedImage.width = Math.round(ResizedImage.width * (max_height / ResizedImage.height));
                ResizedImage.height = max_height;
            }
        }

        var stage = new Konva.Stage({
            container: 'MyLogocontainer',
            width: width,
            height: height
        });

        var layer = new Konva.Layer();
        stage.add(layer);
        var value = 0.4776785714285714;
        var adultDimensions = null;
        var selectedIndex = $('.selected-index').val();

        if (selectedIndex == "" || selectedIndex == undefined || selectedIndex == "undefined") {
            adultDimensions = extractAdultSizeDimensions(item);
        }
        else {
            var index = parseInt(selectedIndex);
            adultDimensions = extractAdultSizeDimensions(clublogoData[index]);
        }

        var finalAdultHeight = adultDimensions.height * value;
        var finalAdultWidth = adultDimensions.width * value;
        var adjustedX = x * value;
        var adjustedY = y * value;

        switch (objectOrgin) {
            case 'top':
                adjustedX -= finalAdultWidth / 2;
                break;
            case 'bottom':
                adjustedX -= finalAdultWidth / 2;
                adjustedY -= finalAdultHeight;
                break;
            case 'left':
                adjustedY -= finalAdultHeight / 2;
                break;
            case 'right':
                adjustedX -= finalAdultWidth;
                adjustedY -= finalAdultHeight / 2;
                break;
            case 'center':
                adjustedX -= finalAdultWidth / 2;
                adjustedY -= finalAdultHeight / 2;
                break;
            default:
                adjustedX -= finalAdultWidth / 2;
                adjustedY -= finalAdultHeight / 2;
                break;
        }

        var darthVaderImg = new Konva.Image({
            image: ResizedImage,
            x: adjustedX,
            y: adjustedY,
            width: finalAdultWidth,
            height: finalAdultHeight
        });

        layer.add(darthVaderImg);
        layer.draw();

        function moveLogo(dx, dy) {
            var scale = stage.scaleX();
            adjustedX += dx * scale;
            adjustedY += dy * scale;
            darthVaderImg.setAttrs({
                x: adjustedX,
                y: adjustedY
            });
            layer.draw();
        }

        var rSaveButton = document.getElementById('rremoveallanchor');
        if (rSaveButton != undefined) {
            document.getElementById('rremoveallanchor').addEventListener('click', function () {
                saveResizedLogo();
            });
        }

        var rmoveUpBtn = document.getElementById('rmoveUpBtn');
        if (rmoveUpBtn) {
            document.getElementById('rmoveUpBtn').addEventListener('click', function () {
                moveLogo(0, -10);
            });
        }

        var rmoveDownBtn = document.getElementById('rmoveDownBtn');
        if (rmoveDownBtn) {
            document.getElementById('rmoveDownBtn').addEventListener('click', function () {
                moveLogo(0, 10);
            });
        }

        var rmoveLeftBtn = document.getElementById('rmoveLeftBtn');
        if (rmoveLeftBtn) {
            document.getElementById('rmoveLeftBtn').addEventListener('click', function () {
                moveLogo(-10, 0);
            });
        }

        var rmoveRightBtn = document.getElementById('rmoveRightBtn');
        if (rmoveRightBtn) {
            document.getElementById('rmoveRightBtn').addEventListener('click', function () {
                moveLogo(10, 0);
            });
        }

        function saveResizedLogo() {
            debugger
            var stage = document.querySelectorAll('canvas');
            var NewLogoImage = stage[1].toDataURL();
            localStorage.setItem("MyResizedLogo", NewLogoImage);
        }


        var saveButton = document.getElementById('removeallanchor');
        if (saveButton != undefined) {
            document.getElementById('removeallanchor').addEventListener('click', function () {
                saveResizedLogo();
            });
        }

        var moveUpBtn = document.getElementById('moveUpBtn');
        if (moveUpBtn) {
            document.getElementById('moveUpBtn').addEventListener('click', function () {
                moveLogo(0, -10);
            });
        }

        var moveDownBtn = document.getElementById('moveDownBtn');
        if (moveDownBtn) {
            document.getElementById('moveDownBtn').addEventListener('click', function () {
                moveLogo(0, 10);
            });
        }

        var moveLeftBtn = document.getElementById('moveLeftBtn');
        if (moveLeftBtn) {
            document.getElementById('moveLeftBtn').addEventListener('click', function () {
                moveLogo(-10, 0);
            });
        }

        var moveRightBtn = document.getElementById('moveRightBtn');
        if (moveRightBtn) {
            document.getElementById('moveRightBtn').addEventListener('click', function () {
                moveLogo(10, 0);
            });
        }

        function fitStageIntoParentContainer() {
            var container = document.querySelector('#CcanvasWrapper');
            var containerWidth = container.offsetWidth;
            var scale = containerWidth / width;
            stage.width(width * scale);
            stage.height(height * scale);
            stage.scale({ x: scale, y: scale });
            stage.draw();
        }
        fitStageIntoParentContainer();
        window.addEventListener('resize', fitStageIntoParentContainer);
    }
});

HTML代码

<div class="dyo_right">
     <div class="main_right_dyo right_creating_shirt">
         <div class="tshirt_sec">
             <img crossOrigin="Anonymous" id="canvasImg" src="@base64String" alt="" style="display:none" class="hidden-xs">
             <img crossOrigin="Anonymous" id="previousImgtest" alt="" style="display:none" class="hidden-xs" />
             <img crossOrigin="Anonymous" id="previousImg" alt="" style="display:none" class="hidden-xs" />

             <img id="numberImage" src="" alt="" style="display:none" class="hidden-xs" />
             <div id="CcanvasWrapper">
                 <canvas width="749" height="496" id="canvas1" style="z-index:1000;"></canvas>
                 <div id="MyLogocontainer" class="resize-img"></div>
             </div>
             <canvas id="canvas2" width="749" height="496" style="display:none"></canvas>
         </div>
     </div>
 </div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:15:55