如何使画布响应

时间:2016-01-13 17:15:30

标签: css html5 canvas responsive-design

我使用bootstrap。我希望用户能够选择画布大小,同时保持设计屏幕在div内响应。

<div class="row">
  <div class="col-xs-2 col-sm-2" id="border">content left</div>
  <div class="col-xs-6 col-sm-6" id="border">
    Width <input type="number" class="form-control"><br>
  Height <input type="number" class="form-control"><br>
  canvas
  <canvas id="canvas" width="500" height="300">  
  </canvas>

  </div>
  <div class="col-xs-2 col-sm-2" id="border">content right</div>

如何将画布的大小限制为div的大小?

我不知道是否有必要使用JavaScript。

修改

应该考虑到用户输入宽度和高度值,并且画布必须与div成比例大小

https://jsfiddle.net/1a11p3ng/2/

9 个答案:

答案 0 :(得分:15)

改变宽度并不难。只需从代码中删除width属性,然后在width: 100%;

的CSS中添加#canvas即可
#canvas{
  border: solid 1px blue;  
  width: 100%;
}

改变高度有点困难:你需要javascript。我使用过jQuery,因为我更舒服。

您需要从canvas标记中删除height属性并添加以下脚本:

  <script>
  function resize(){    
    $("#canvas").outerHeight($(window).height()-$("#canvas").offset().top- Math.abs($("#canvas").outerHeight(true) - $("#canvas").outerHeight()));
  }
  $(document).ready(function(){
    resize();
    $(window).on("resize", function(){                      
        resize();
    });
  });
  </script>

你可以看到这个小提琴:https://jsfiddle.net/1a11p3ng/3/

修改

回答你的第二个问题。你需要javascript

0)首先,我将你的#border id更改为一个类,因为对于html页面内的元素,id必须是唯一的(你不能有2个具有相同id的标签)

.border{
  border: solid 1px black;
}

#canvas{
  border: solid 1px blue;  
  width: 100%;
}

1)更改了HTML以在需要时添加ID,两个输入和一个用于设置值的按钮

<div class="row">
  <div class="col-xs-2 col-sm-2 border">content left</div>
  <div class="col-xs-6 col-sm-6 border" id="main-content">
    <div class="row">
      <div class="col-xs-6">
        Width <input id="w-input" type="number" class="form-control">
      </div>
      <div class="col-xs-6">
        Height <input id="h-input" type="number" class="form-control">
      </div>
      <div class="col-xs-12 text-right" style="padding: 3px;">
        <button id="set-size" class="btn btn-primary">Set</button>
      </div> 
    </div>
    canvas
    <canvas id="canvas"></canvas>

  </div>
  <div class="col-xs-2 col-sm-2 border">content right</div>
</div>

2)设置画布的高度和宽度,使其适合容器

$("#canvas").outerHeight($(window).height()-$("#canvas").offset().top-Math.abs( $("#canvas").outerHeight(true) - $("#canvas").outerHeight()));

3)设置宽度和高度形式的值

$("#h-input").val($("#canvas").outerHeight());
$("#w-input").val($("#canvas").outerWidth());

4)最后,每当您单击按钮时,将画布宽度和高度设置为设置的值。如果宽度值大于容器的宽度,那么它会将画布的大小调整为容器的宽度(否则会破坏您的布局)

    $("#set-size").click(function(){
        $("#canvas").outerHeight($("#h-input").val());
        $("#canvas").outerWidth(Math.min($("#w-input").val(), $("#main-content").width()));
    });

请在此处查看完整示例https://jsfiddle.net/1a11p3ng/7/

更新2:

要完全控制宽度,您可以使用:

<div class="container-fluid">
<div class="row">
  <div class="col-xs-2 border">content left</div>
  <div class="col-xs-8 border" id="main-content">
    <div class="row">
      <div class="col-xs-6">
        Width <input id="w-input" type="number" class="form-control">
      </div>
      <div class="col-xs-6">
        Height <input id="h-input" type="number" class="form-control">
      </div>
      <div class="col-xs-12 text-right" style="padding: 3px;">
        <button id="set-size" class="btn btn-primary">Set</button>
      </div> 
    </div>
      canvas
    <canvas id="canvas">

    </canvas>

  </div>
  <div class="col-xs-2 border">content right</div>
</div>
</div>
  <script>
   $(document).ready(function(){
    $("#canvas").outerHeight($(window).height()-$("#canvas").offset().top-Math.abs( $("#canvas").outerHeight(true) - $("#canvas").outerHeight()));
    $("#h-input").val($("#canvas").outerHeight());
    $("#w-input").val($("#canvas").outerWidth());
    $("#set-size").click(function(){
        $("#canvas").outerHeight($("#h-input").val());
      $("#main-content").width($("#w-input").val());
      $("#canvas").outerWidth($("#main-content").width());
    });
   });
  </script>

https://jsfiddle.net/1a11p3ng/8/

如果宽度太高,

内容左侧和内容右侧列将移动到中央div并且中心div,但如果您使用bootstrap,这将无法帮助。然而,这不是响应意味着什么。一个真正响应的网站将调整其大小到用户屏幕,以保持您想要的布局,无需任何外部输入,让用户设置任何可能破坏您的布局的大小并不意味着建立响应式网站。

答案 1 :(得分:8)

您可以通过3个简单的步骤获得响应式画布:

  1. width中删除height<canvas>属性。

    <canvas id="responsive-canvas"></canvas>
    
  2. 使用CSS,将画布的width设置为100%

    #responsive-canvas {
      width: 100%;
    }
    
  3. 使用JavaScript,将高度设置为宽度的某个比例。

    var canvas = document.getElementById('responsive-canvas');
    var heightRatio = 1.5;
    canvas.height = canvas.width * heightRatio;
    

答案 2 :(得分:5)

这似乎有效:

#canvas{
  border: solid 1px blue; 
  width:100%;
}

答案 3 :(得分:5)

<div class="outer">
 <canvas id="canvas"></canvas>
</div>    
.outer {
 position: relative;
 width: 100%;
 padding-bottom: 100%;
}

#canvas {
 position: absolute;
 width: 100%;
 height: 100%;
}

答案 4 :(得分:4)

用jquery扩展接受的答案

如果你想添加更多画布?,这个jquery.each会回答它

responsiveCanvas(); //first init
$(window).resize(function(){
  responsiveCanvas(); //every resizing
  stage.update(); //update the canvas, stage is object of easeljs

});
function responsiveCanvas(target){
  $(canvas).each(function(e){

    var parentWidth = $(this).parent().outerWidth();
    var parentHeight =  $(this).parent().outerHeight();
    $(this).attr('width', parentWidth);
    $(this).attr('height', parentHeight);
    console.log(parentWidth);
  })

}

它将为你完成所有工作

为什么我们不通过css或样式设置widthheight?因为它会拉伸你的画布而不是让它变成期望的尺寸

答案 5 :(得分:2)

object-fit CSS属性设置应如何调整替换元素(例如img或视频)的内容的大小以适合其容器。

魔术地讲,对象适配也适用于canvas元素。不需要JavaScript,并且画布不会拉伸,会自动按比例填充。

canvas {
    width: 100%;
    object-fit: contain;
}

答案 6 :(得分:1)

在现代浏览器中,有一种更好的方法是使用vhvw单位。

vh是视口高度。

所以您可以尝试这样的事情:

<style>
canvas {
  border: solid 2px purple;
  background-color: green;
  width: 100%;
  height: 80vh;
}
</style>

这会扭曲宽高比。

可以通过使用相同的单位来保持宽高比。这是一个长宽比为2:1的示例:

<style>
canvas {
  width: 40vh;
  height: 80vh;
}
</style>

答案 7 :(得分:1)

尝试在画布上使用max-width: 100%;

canvas {
  max-width: 100%;
}

答案 8 :(得分:0)

嗨,我知道这篇文章已经进行了一段时间了,但是我的画布有一个非常相似的问题。如前所述,视口会调整大小,窗口中的元素也会调整大小。可以使用css完成此操作,但是它不适用于画布中的元素。现在,如果您的画布上下文是2D,这就是对我有用的解决方案... 可以用作方法。

class ParentObject{
 constructor()
        /**
        * @this this._width - Private width variable that would store the size of the window width
        */
        this._width = Number();
       
        /**
         * @this this._height - Private Height variable that would store the height of the window
         */
        this._height= Number();
        
        /**
         * Calls the getCanvasDimensions method
         */
        this.getCanvasDimensions();
       
        //Getting the Width and Height as soon as the Window loads
        window.addEventListener('load',()=>{
            this.getCanvasDimensions()
        })
       
        //As the window is resized we are getting the new Canvas Dimensions
        window.addEventListener('resize',()=>{
            this.getCanvasDimensions();

getCanvasDimensions() {
        // Width is determined by the css value for the viewport width this is then respected by the device pixel ratio. This is then used to set the canvas.width value
        this._width = Math.round((Number(getComputedStyle(canvas).getPropertyValue('width').slice(0,-2))/devicePixelRatio) * devicePixelRatio);
        //Setting the canvas width 
        canvas.width = this._width
        
        // height is determined by the css value for the viewport height this is then respected by the device pixel ratio. This is then used to set the canvas.height value
        this._height = Math.round((Number(getComputedStyle(canvas).getPropertyValue('height').slice(0,-2))/devicePixelRatio) * devicePixelRatio);
        //Setting the canvas height
        canvas.height = this._height
        
    }
get width(){
        //This sets the width to the private _width value
        return this._width
        
    }
get height(){
        //This sets the height to the private _height value
        return this._height
    }

作为全局范围内的函数:

let width,height
function responsiveCanvas(){
   let w = Math.round((Number(getComputedStyle(canvas).getPropertyValue('width').slice(0,-2))/devicePixelRatio) * devicePixelRatio);
 width = canvas.height = w;

let h  = Math.round((Number(getComputedStyle(canvas).getPropertyValue('height').slice(0,-2))/devicePixelRatio) * devicePixelRatio);
height = canvas.height = h;
}
window.addEventListener('load',responsiveCanvas)
window.addEventListener('resize',responsiveCanvas)

然后仅使用widthheight变量来引用尺寸。 无论如何,我希望这可以帮助某人。