【问题标题】:How to enable responsive design for Fabric.js如何为 Fabric.js 启用响应式设计
【发布时间】:2014-03-22 18:44:50
【问题描述】:

有没有办法让 Fabric.js 画布使用浏览器调整大小以在任何设备上启用相同的结果?我说的是响应式设计。

有人有代码示例吗?

【问题讨论】:

    标签: responsive-design html5-canvas fabricjs


    【解决方案1】:

    这个jsFiddle 是一个有效的解决方案。它的灵感来自这个 github issue

    这些是必需的:

    一个 div 围绕由 fabric 控制的画布。

    <div class="fabric-canvas-wrapper">
        <canvas id="theCanvas"></canvas>
    </div>
    

    还有一个窗口调整大小处理程序,触发新画布尺寸和缩放的计算和设置。

    window.onresize = resizeCanvas() {
        const outerCanvasContainer = document.getElementById('fabric-canvas-wrapper');
    
        const ratio          = canvas.getWidth() / canvas.getHeight();
        const containerWidth = outerCanvasContainer.clientWidth;
        const scale          = containerWidth / canvas.getWidth();
        const zoom           = canvas.getZoom() * scale;
    
        canvas.setDimensions({width: containerWidth, height: containerWidth / ratio});
        canvas.setViewportTransform([zoom, 0, 0, zoom, 0, 0]);
    }
    

    就是这样。它似乎工作得很好。如果此解决方案有任何问题,请告诉我。

    我在 3.6.2 版本中使用过 fabric.js。

    【讨论】:

    • 感谢这个 sn-p。只是,我认为你不需要声明containerHeight(从未使用过)
    • 谢谢@Zooly。解决了这个问题。
    • 这对我有用,但在任何点击事件之后。任何解决方案@robsch?
    • @SarathMohandas 你有什么问题?小提琴对你有用吗?
    • @robsch 这对我来说是有角度的,但是在点击事件之后,布局就会出现。
    【解决方案2】:

    基本上你需要获取设备屏幕的宽度和高度。之后只需在您的 Javascript 中相应地调整画布的大小。示例:

    var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
    var height = (window.innerHeight > 0) ? window.innerHeight : screen.height;
    var canvas = document.getElementById("canvas");
    canvas.width = width;
    canvas.height = height;
    

    虽然您的屏幕可能具有不同的分辨率,但在这种情况下,我通常会计算您的原始宽度和设备的宽度比,然后根据该值相应地调整宽度和高度。示例:

    var originalWidth = 960;  //Example value
    var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
    var widthRatio = originalWidth / width;
    canvas.width *= widthRatio;
    canvas.height *= widthRatio;
    

    这通常适用于我在任何设备上,希望这会有所帮助。

    【讨论】:

    • 你的回答听起来很有道理。不幸的是,它在我的示例中不起作用。请使用您的代码和不使用您的代码查看我的 jsfiddles。有:jsfiddle.net/J9mUh/1 没有:jsfiddle.net/gcollect/Nyf5Y/2 我做错了什么?
    • 从我读到的有关 FabricJS 的内容中,您需要通过 setWidth 和 setHeight 方法设置画布宽度和高度。试试看,让我知道它是否有效。
    • 谢谢。现在可以了。画布调整大小。见jsfiddle.net/gcollect/Hx75y/2 无论如何,我的基本问题是,我需要画布的全部内容来表现响应。所有对象都需要根据新窗口设置重新渲染。有任何想法吗?不管怎样,我给你一个 +1 的解决方案
    • 您可以设置画布的 onBeforeScaleRotate 以对其内容进行处理。但是 Joao 回答了您实际提出的问题...如果您想知道其他问题,您应该检查一下并提出一个新问题...
    • 会不会出现您无权访问窗口对象的情况?
    【解决方案3】:

    我知道这已经有一段时间了,但我找到了一种使用缩放功能更简单的方法。

    此代码在窗口调整大小完成时触发。它允许我根据新尺寸确定调整画布中所有内容所需的缩放系数。

    function rescale_canvas_if_needed()
    {
    	var optimal_dimensions = get_optimal_canvas_dimensions();
    	var scaleFactor=optimal_dimensions[0]/wpd.canvas_w;
    	if(scaleFactor != 1) {
    		wpd_editor.canvas.setWidth(optimal_dimensions[0]);
    		wpd_editor.canvas.setHeight(optimal_dimensions[1]);
    		wpd_editor.canvas.setZoom(scaleFactor);
    		wpd_editor.canvas.calcOffset();
    		wpd_editor.canvas.renderAll();
      }
    }
    
    $( window ).resize(function() {
    	clearTimeout(resizeId);
    	resizeId = setTimeout(handle_resize, 500);
     });
     
     function handle_resize()
     {
    	$(".canvas-container").hide();
    	rescale_canvas_if_needed();
    	$(".canvas-container").show();               
    	 
     }

    【讨论】:

    • 这看起来会很好...但是get_optimal_canvas_dimensions 是做什么的?代码 sn-ps 也不起作用:(
    • 您好,抱歉回复晚了,我刚收到通知。该功能是检查画布显示区域中的可用空间并相应地调整画布本身大小的地雷之一。
    • [code]function get_optimal_canvas_dimensions() { var available_width = $("#wpc-editor-container").outerWidth(); var canvas_w = 0; var canvas_h = 0; if (wpd.canvas_w > available_width) { canvas_w = available_width; canvas_h = (canvas_w * wpd.canvas_h) / wpd.canvas_w; } 其他 { canvas_w = wpd.canvas_w; canvas_h = wpd.canvas_h; } 返回 [canvas_w, canvas_h]; }[代码]
    • 谢谢!最后我散列了我自己对该函数的实现,但感谢更新:)
    • 请提供完整代码。 get_optimal_canvas_dimensions 有未定义的变量。
    【解决方案4】:

    我认为这是我需要的答案https://stackoverflow.com/a/29445765/1815624

    它看起来如此接近,但经过一些调整后,我得到了我想要的东西

    你想要的画布大小应该设置为宽度/高度var optimal_dimensions = [1000,1000];

    这还需要进行更多更改来处理高度,因此当用户将手机旋转到横向时,它可能会变得太大而无法在屏幕上看到所有内容 对于这个演示,新编辑的代码的宽度和高度将是 1000 像素

    更新:添加了高度和宽度检测以缩放到窗口...

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <canvas id="canvas" width="1000" height="1000"></canvas>
    
        
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.0.0/fabric.min.js"></script>
       <script>
      var canvas = new fabric.Canvas('canvas');
      canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 }));
    
      canvas.item(0).set({
        borderColor: 'gray',
        cornerColor: 'black',
        cornerSize: 12,
        transparentCorners: true
      });
      canvas.setActiveObject(canvas.item(0));
      canvas.renderAll();
    
     
    function rescale_canvas_if_needed(){
        var optimal_dimensions = [400,400];
        var scaleFactorX=window.innerWidth/optimal_dimensions[0];
        var scaleFactorY=window.innerHeight/optimal_dimensions[1];
        if(scaleFactorX <  scaleFactorY && scaleFactorX < 1) {
            canvas.setWidth(optimal_dimensions[0] *scaleFactorX);
            canvas.setHeight(optimal_dimensions[1] *scaleFactorX);
            canvas.setZoom(scaleFactorX);
        } else if(scaleFactorX >  scaleFactorY && scaleFactorY < 1){
            canvas.setWidth(optimal_dimensions[0] *scaleFactorY);
            canvas.setHeight(optimal_dimensions[1] *scaleFactorY);
            canvas.setZoom(scaleFactorY);
        }else {
            canvas.setWidth(optimal_dimensions[0] );
            canvas.setHeight(optimal_dimensions[1] );
            canvas.setZoom(1);
        }
    
        canvas.calcOffset();
        canvas.renderAll();
    }
    
     
    function handle_resize(){
        $(".canvas-container").hide();
        rescale_canvas_if_needed();
        $(".canvas-container").show();               
         
    }
    var resizeId = null;
    $(function() {
        $(window).resize(function() {
            if(resizeId != null)
            clearTimeout(resizeId);
            resizeId = setTimeout(handle_resize, 500);
         });
        console.log( "ready!" );
        /* auto size it right away... */
        resizeId = setTimeout(handle_resize, 500);
    });
        </script>

    希望这对某人有所帮助...美好的一天。

    【讨论】:

      【解决方案5】:

      使用 jQuery 根据元素的大小调整画布大小。

      window.addEventListener('resize', resizeCanvas, false);
      function resizeCanvas() {
          canvas.setHeight(jQuery('#image').height());
          canvas.setWidth(jQuery('#image').width());
          canvas.renderAll();
      }
      resizeCanvas();
      

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 2013-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 1970-01-01
        • 2014-07-02
        相关资源
        最近更新 更多