fabric.js 调整画布大小以适应屏幕

Posted

技术标签:

【中文标题】fabric.js 调整画布大小以适应屏幕【英文标题】:fabric.js resize canvas to fit screen 【发布时间】:2015-08-31 23:07:03 【问题描述】:

我目前正在使用 ionic 和 cordova 在移动设备(android 和 iPhone)上开发应用程序。我想编辑一张图片。我使用 fabric.js 库来做到这一点。 Fabric.js 将图像和其他项目转换为画布。然后我在画布上添加一些图像(贴纸)并将其导出为图像(dataURL)。所以画布的大小真的很重要,因为它是一个质量因素(基于小画布导出图像会导致质量很差)。画布大小约为 607*1080 像素(取决于拍摄照片的设备)。我想在不损失质量的情况下将其放入屏幕(如下所述,我无法在不损失质量的情况下调整画布大小)。

我尝试了 3 个想法,但没有一个奏效。

    调整画布大小:导致质量下降(导出的图像将具有画布大小) 调整视口:cordova 不允许更改移动设备上的视口。有一个解决方法,但它会破坏我的设计(非常小的导航栏,更小的菜单,......) 使用 CSS3 缩放属性 :它在桌面上就像一个魅力,但在移动设备上存在事件映射问题(我没有在 ios 上尝试,但问题发生在 android Webview 上)。事件映射未缩放。画布被缩小,但无法与画布元素交互。如果画布元素(贴纸)位于 x:100 y:100,当我将缩放属性设置为 0.5 时,该元素将位于 (50,50) 处,而不再位于 (100,100) 处。有没有办法根据android webview的缩放属性来纠正事件映射?

我不知道是否有其他方法可以做到这一点,但我被这个问题困扰了 3 天,我在论坛、fabricjs 文档和谷歌上花了很多时间,但我没有找到任何工作解决方案或其他可以帮助我的东西。

编辑:下面有 2 个可行的解决方案。检查我的答案以了解如何使用 css 做到这一点。

【问题讨论】:

我之前也遇到过类似的问题。我认为您应该将 fabric.js 计算复制到为事件完成的计算中..... 很多时候,用自己的方式编写代码比尝试使用打包库更好 我没有时间编写一个库来实现 fabris.js 中包含的所有功能。我使用了这个库的很多功能,从头开始重新创建所有内容会花费太多时间。 您可能会结束编写另一个库,然后决定与人们共享它。有人会对那个图书馆有疑问。 【参考方案1】:

1。使用 css 为画布设置正确的分辨率:

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = 800;
canvas.height = 600;

css:

/* media query 1 */
    #canvas
       width: 400px;
       height: 250px; 
    

/* media query 2 */
#canvas
       width: 200px;
       height: 120px; 
    

优点:

所有分辨率由画布宽度和高度(800/600)给出

缺点:

非常适合方形画布纵横比 (1:1),输出问题 对于需要计算 CSS 高度的奇怪纵横比 基于,

original height / original width * new width = new height;

这超出了我的 css 范围......

前段时间阅读有关 fabric.js 的 git 问题部分,其中技术 (css resize) 不推荐,因为速度慢且对象不正确 交易,这可能会改变我知道我测试过并且对象是 重新调整大小不正确(随机彩色像素,交易阴影仍然存在 在画布中,换句话说就是一团糟)

2。当您需要提交时,将您的画布重新调整为精确的尺寸(分辨率),然后生成图像

只需在窗口重新调整大小(响应式画布)时重新调整画布大小,当您需要导出到精确尺寸时,您需要将画布大小重新调整为精确的像素分辨率,或创建另一个隐藏的画布。

此示例适用于 1:1 比例画布(您需要将宽高比应用于画布和里面的对象):

$(window).resize(function ()
 if (canvas.width != $(".container").width()) 
            var scaleMultiplier = $(".container").width() / canvas.width;
            var objects = canvas.getObjects();
            for (var i in objects) 
                objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
                objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
                objects[i].left = objects[i].left * scaleMultiplier;
                objects[i].top = objects[i].top * scaleMultiplier;
                objects[i].setCoords();
            

            canvas.setWidth(canvas.getWidth() * scaleMultiplier);
            canvas.setHeight(canvas.getHeight() * scaleMultiplier);
            canvas.renderAll();
            canvas.calcOffset();
        
);

在提交导出画布数据时,将画布重新调整为所需的分辨率,瞧:

function GetCanvasAtResoution(newWidth)
  
    if (canvas.width != newWidth) 
                var scaleMultiplier = newWidth / canvas.width;
                var objects = canvas.getObjects();
                for (var i in objects) 
                    objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
                    objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
                    objects[i].left = objects[i].left * scaleMultiplier;
                    objects[i].top = objects[i].top * scaleMultiplier;
                    objects[i].setCoords();
                

                canvas.setWidth(canvas.getWidth() * scaleMultiplier);
                canvas.setHeight(canvas.getHeight() * scaleMultiplier);
                canvas.renderAll();
                canvas.calcOffset();
            
     return canvas.toDataURL();
   
   );

这不是什么大问题,然后 1:1 的口粮你也需要计算比例多人游戏的高度,易于理解的比例:http://andrew.hedges.name/experiments/aspect_ratio/

【讨论】:

感谢您的帮助。 css 裁剪图片,我的意思是如果我为画布设置宽度和高度,css 将裁剪画布。但第二个似乎是一个很好的解决方案。我还找到了另一种不复制画布的方法。我也会在这里解释,但非常感谢您的帮助。【参考方案2】:

我找到了一个无需复制画布即可做到这一点的技巧。此解决方案非常接近 css zoom 属性,但事件处理正确。

这是一个将画布显示一半大小的示例:

-webkit-transform : scale(0.5);
-webkit-transform-origin : 0 0;

【讨论】:

这是一个天才,而且是一种享受。我在 js 中使用这个技巧进行了缩放,改变了画布容器的比例 这个技巧看起来不错,但问题是当你添加对象时,它们的控件也会缩放太多

以上是关于fabric.js 调整画布大小以适应屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何为Fabric.js启用响应式设计

颤振形状调整大小并在图像背景画布上拖动

使用 jquery mobile 调整图像大小以适应移动设备上的屏幕

调整按钮以适应不同的屏幕尺寸

无法让 UIImageView 调整大小以适应屏幕

如何调整html中的图像大小以适应屏幕尺寸?