【问题标题】:Preserve image ratio while uploading上传时保留图像比例
【发布时间】:2018-11-28 19:28:23
【问题描述】:

当我将图像上传到 konva.js 时,有没有办法保持图像比例。基本上,我使用的是带有 Vue 扩展的 konva,我需要有上传背景图片这样的方法。我已经根据用户设备设置了画布大小,我可以将上传的图像大小设置为画布尺寸,但它不会保存它的比例。

我认为的一种方法是,我可以通过编写函数来确定图像可以实现的最大高度或宽度(在特定情况下选择更合适的)然后按比例调整它的大小,但我没有看到这个答案优雅且没有错误,所以我想我会在做之前问一下。

【问题讨论】:

    标签: javascript canvas vue.js konvajs


    【解决方案1】:

    您需要自己处理图像缩放,但这并不困难。

    正如您所确定的,您需要一个函数来设置图像的比例以覆盖视口,同时保持纵横比。

    所需的数学运算是计算视口宽度与图像宽度的比率,高度也是如此。然后比较两个比率并使用较大的。

    除非视口和图像完全相同的宽高比,否则您将发现在选择300x500按钮时可以在SN-P中看到的一些图像被剪切。

    下面的 sn-p 显示了代表视口的粉红色矩形。尺寸按钮更改视口比例,宽度 x 高度按钮调用不同的图像。使用组合中的按钮,您可以看到拟合功能的工作原理。

    实验 1:开始时,反复点击“加宽”按钮,看看图像顶部和底部的部分是如何被裁剪到视口之外的。

    实验2:开始时,反复点击'narrower',观察类似的效果。

    /*
    function to caluclate and return appropriate scale to fill one rect with another whilst preserving aspect ratio
    */
    var autoScale = function(container, imgEle){
    
    var rW = container.width() / imgEle.width;
    var rH = container.height() / imgEle.height;
    
    var scale = (rW < rH ? rH : rW);
    return {x: scale, y: scale};
    }
    
    // from here on the code is about making the demo.
    
    var sz = '600x600';
    var miniMag = 0.3333
    
    // Set up the canvas / stage
    var div = $('#container');
    
    var stage = new Konva.Stage({container: 'container', width: div.width(), height: div.height()});
    var layer = new Konva.Layer({draggable: false});
    stage.add(layer)
    stage.scale({x: miniMag, y: miniMag});
    var pic = new Konva.Image({ x: 300, y: 300});
    layer.add(pic);
    var rect = new Konva.Rect({x: 300, y: 300, width : div.width(), height: div.height(), stroke: 'magenta'})
    layer.add(rect)
    stage.draw()
    
    // load an image
    var imageObj = new Image();
    imageObj.onload = function(){
    
      pic.image(imageObj);  
      pic.scale(autoScale(rect, imageObj));
      pic.x(rect.x() + ((rect.width() -  (pic.width() * pic.scaleX()) )/2)) 
      pic.y(rect.y() + ((rect.height() -  (pic.height() * pic.scaleY()) )/2)) 
      layer.draw();
    
    }
    
    // if we click a change-size button then change the viewport indicator
    $('#narrower').data('change', {x:-10, y:   0});
    $('#wider').data('change',  {x: 10, y:   0});
    $('#shorter').data('change', {x:  0, y: -10});
    $('#taller').data('change',  {x:  0, y:  10});
    $('.btn').on('click', function(e){
    
      var diff = $(this).data('change');  
      rect.width(rect.width() + diff.x)
      rect.height(rect.height() + diff.y)
      pic.scale(autoScale(rect, imageObj));
      pic.x(rect.x() + ((rect.width() -  (pic.width() * pic.scaleX()) )/2)) 
      pic.y(rect.y() + ((rect.height() -  (pic.height() * pic.scaleY()) )/2)) 
      layer.draw();
    
    })
    
    // If we click an image selection button change the image
    $('.imgsel').on('click', function(e){
    
    imageObj.src = "https://via.placeholder.com/" + $(this).attr('sz');
    
    })
    
    // Kick off with a 600 x 600 image
    $('.imgsel600').trigger('click');
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.min.js"></script>
    <div>
    <button id='narrower' class='btn'>Narrower</button>
    <button id='wider' class='btn'>Wider</button>
    <button id='shorter' class='btn'>Shorter</button>
    <button id='taller' class='btn'>Taller</button>
    <button class='imgsel' sz='300x300'>300 x 300</button>
    <button class='imgsel' sz='300x500'>300 x 500</button>
    <button class='imgsel' sz='500x300'>500 x 300</button>
    <button class='imgsel imgsel600' sz='600x600'>600 x 600</button>
    </div>
    <div id='container' style="position: absolute; z-index: -1; display: inline-block; left: 0px; top: 0px; width: 300px; height: 300px; background-color: silver;"></div>

    【讨论】:

    • 我的处理方式大致相同,但非常感谢您的参与。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 2013-11-14
    相关资源
    最近更新 更多