上传时保持图像比例

时间:2018-11-28 19:28:23

标签: javascript canvas vue.js konvajs

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

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

1 个答案:

答案 0 :(得分:1)

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

您已经确定,您需要一个函数来设置图像的比例以覆盖视口,同时保持宽高比。

所需的数学方法是计算视口宽度与图像宽度的比率,高度相同。然后比较两个比率并使用更大的比率。

除非视口和图像的长宽比完全相同,否则在选择300x500按钮时,您会发现某些图像已被裁剪,如摘录中所示。

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

实验1:在开始时,反复单击“更宽”按钮,然后查看图像顶部和底部的部分如何修剪到视口之外。

实验2:在开始时,反复单击“缩小”并观察到相似的效果。

/*
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>