代码之家  ›  专栏  ›  技术社区  ›  Brad

在flexbox内按比例缩放画布

  •  1
  • Brad  · 技术社区  · 6 年前

    假设我有以下HTML:

    <div>
      <canvas class="colorPicker" width="800" height="800"></canvas>
      <canvas class="colorPicker" width="800" height="800"></canvas>
    </div>
    

    这个CSS:

    div {
      display: flex;
      width: 100%;
      overflow: hidden;
    }
    
    div > canvas{
      flex-grow: 1;
      flex-shrink: 1;
      width: 50%;
    }
    

    画布的比例不是成比例的。它们比宽的高。当我在画布上绘制圆时,这是可见的。

    Badly Scaled Canvases

    (J小提琴: https://jsfiddle.net/08rckfek/ )

    为什么会这样?

    如果我在父分区中不使用flexbox,则画布的比例是正确的。

    而且,我必须详细说明,这似乎很奇怪 width: 50% 完全。 flex-shrink 被忽略,即使我指定了一个基础。

    如何根据父flexbox的宽度自动按比例缩放一行画布?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Temani Afif    6 年前

    你需要设置 align-items 默认情况下,其值为 stretch

    document.addEventListener('DOMContentLoaded', (e) => {
    	document.querySelectorAll('canvas.colorPicker').forEach((canvas) => {
      
      const ctx = canvas.getContext('2d');
      const centerX = canvas.width / 2;
      const centerY = canvas.height / 2;
      const radius = Math.min(canvas.width, canvas.height) / 2;
    
      // Base white circle, so middle has a full color
      ctx.beginPath();
      ctx.arc(centerX, centerY, radius/2, 0, 2*Math.PI, false);
      ctx.closePath();
      ctx.fillStyle = '#fff';
      ctx.fill();
    
      for (let angle=0; angle<=360; angle+=1) {
        const startAngle = (angle-2)*Math.PI/180;
        const endAngle = angle * Math.PI/180;
        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.arc(centerX, centerY, radius, startAngle, endAngle);
        ctx.closePath();
    
        const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
        gradient.addColorStop(0, 'hsl(' + angle + ', 100%, 100%)');
        gradient.addColorStop(0.5, 'hsl(' + angle + ', 100%, 50%)');
        gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 0%)');
        ctx.fillStyle = gradient;
        ctx.fill();
      }
    });
    });
    div {
      display: flex;
      width: 100%;
      overflow: hidden;
      align-items:flex-start;
    }
    
    div > canvas{
      flex-grow: 1;
      flex-shrink: 1;
      width: 50%;
    }
    <div>
      <canvas class="colorPicker" width="800" height="800"></canvas>
      <canvas class="colorPicker" width="800" height="800"></canvas>
    </div>