P5.js: 如何防止使用flexbox时文本被压碎

P5.js: how to prevent text from being crushed when using flexbox

我正在尝试使用 p5.js 草图创建响应式网页。

在网页中,我使用 flexbox 切换了侧边栏。 但是一旦侧边栏出现在 window 的左边,它就会把我的 canvas 压在 p5.js 中(结果就是 canvas 中的所有 images/text也会变形)。 为了让我的问题更容易理解,我在这里上传了一张图片和一张 demo 非常感谢,非常感谢你的帮助。

/*When button clicked, show / hide the sidebar */
function toggle(){
  $('main').on('click', '.toggle-sidebar', function(){
    var sidebar = $('.sidebar');
       sidebar.toggleClass('is-visible');
       sidebar.toggle(300);
    })
};
toggle();


/*p5.js*/
const typo = (sketch) => {
  let x1 = 0;
  let x2;
  let speed = 3;
  /*Responsive canvas => make the canvas width equals to it's parent container*/
  let cvs_parent_width = document.getElementById("canvas").offsetWidth;
  let cvs_width = cvs_parent_width;
  /*Responsive font => font size is set based on canvas width */
  let ratio_responsive = 200 / 1500;
  
  sketch.setup = () => {
   let cvs = sketch.createCanvas(cvs_width, sketch.windowHeight);
    sketch.textFont("Palatino");
    cvs.style("display", "block");
  };

  sketch.draw = () => {
    sketch.background(220);
    x1 += speed;
    x2 += speed;
    if (x2 > 0) {
      x1 = x2 - cvs_width;
    }
    if (x1 > 0) {
      x2 = x1 - cvs_width;
    }

    let typo_size = cvs_width * ratio_responsive;
    sketch.textSize(typo_size);
    sketch.text("TYPO CRUSHED", x1, 30, cvs_width, sketch.windowHeight);
    sketch.text("TYPO CRUSHED", x2, 30, cvs_width, sketch.windowHeight);
  }
}

let typo_sketch = new p5(typo, "canvas");
html, body  {
  width: 100%;
  height: 100%;
  margin: 0;
}

main{
  overflow:hidden;
}

/* Flexbox for showing n hide sidebar*/
/* flex parent */
.flexgroup {
  display: flex;
  justify-content: flex-end;
}

/* flex item1 */
.sidebar {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: auto;
  height: 100%;
  width:50vw;
}

/* flex item2 */
.image {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 100%;
  max-width:100%;
  transition: flex-basis .3s;
}

.none{
  display:none;
}

.sidebar.is-visible  ~ .image {
  flex-basis: 0;
  transition: flex-basis .3s;
}

/* parameters of canvas */
canvas{
  margin:auto;
  display:block;
  max-width: 100%; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/addons/p5.sound.min.js"></script>
    
    <meta charset="utf-8" />

  </head>
  <body>
  <main>
  <!-- TOGGLE BUTTON-->
  <button class="toggle-sidebar">Toggle</button>

  <!-- FLEXBOX-->
  <div class='flexgroup'>
  <!-- FLEXBOX Item1-->
    <div class="sidebar none">
     <p>
        SIDEBAR
      </p>
    </div>
   
  <!-- FLEXBOX Item2-->
    <div class='image'>
      <div id="canvas">
  <!-- P5.JS-->    
      </div>
    </div>
  </div>
</main>
  </body>
</html>

当 canvas 由于布局更改而调整大小时,绘图上下文大小不会更新以反映这一点。您需要检测新尺寸并相应地更新 canvas 尺寸。当使用完整的 window canvas 或相对于 window 大小的 canvas 时,这可以通过 p5.js windowResized function. However because you are sizing your canvas based on flexbox layout for a specific element (animated no less), things are a little more complicated. If you are using a modern, mainstream web browser, then you can use ResizeObserver。这是一个演示使用 ResizeObserver 解决问题的片段:

/*When button clicked, show / hide the sidebar */
function toggle(){
  $('main').on('click', '.toggle-sidebar', function(){
    var sidebar = $('.sidebar');
       sidebar.toggleClass('is-visible');
       sidebar.toggle(300);
    })
};
toggle();


/*p5.js*/
const typo = (sketch) => {
  let x1 = 0;
  let x2;
  let speed = 3;
  /*Responsive canvas => make the canvas width equals to it's parent container*/
  let cvs_parent_width = document.getElementById("canvas").offsetWidth;
  let cvs_width = cvs_parent_width;
  /*Responsive font => font size is set based on canvas width */
  let ratio_responsive = 200 / 1500;
  let cvs;
  
  sketch.setup = () => {
    cvs = sketch.createCanvas(cvs_width, sketch.windowHeight);
    sketch.textFont("Palatino");
    cvs.style("display", "block");
    new ResizeObserver(canvasParentResized).observe(cvs.parent());
  };
  
  let supressResize = false;
  function canvasParentResized() {
    if (!supressResize) {
      let parent = cvs.parent();
      if (parent && parent.offsetWidth) {
        // console.log('resized');
        supressResize = true;
        cvs_width = cvs_parent_width = parent.offsetWidth;
        sketch.resizeCanvas(cvs_parent_width, sketch.windowHeight);
      } else {
        console.log(parent.offsetWidth);
      }
    } else {
      // Resizing the canvas tiggers the ResizeObserver recursively
      // console.log('supressed');
      supressResize = false;
    }
  }

  sketch.draw = () => {
    sketch.background(220);
    x1 += speed;
    x2 += speed;
    if (x2 > 0) {
      x1 = x2 - cvs_width;
    }
    if (x1 > 0) {
      x2 = x1 - cvs_width;
    }

    let typo_size = cvs_width * ratio_responsive;
    sketch.textSize(typo_size);
    sketch.text("TYPO CRUSHED", x1, 30, cvs_width, sketch.windowHeight);
    sketch.text("TYPO CRUSHED", x2, 30, cvs_width, sketch.windowHeight);
  }
}

let typo_sketch = new p5(typo, "canvas");
html, body  {
  width: 100%;
  height: 100%;
  margin: 0;
}

main{
  overflow:hidden;
}

/* Flexbox for showing n hide sidebar*/
/* flex parent */
.flexgroup {
  display: flex;
  justify-content: flex-end;
}

/* flex item1 */
.sidebar {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: auto;
  height: 100%;
  width:50vw;
}

/* flex item2 */
.image {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 100%;
  max-width:100%;
  transition: flex-basis .3s;
}

.none{
  display:none;
}

.sidebar.is-visible  ~ .image {
  flex-basis: 0;
  transition: flex-basis .3s;
}

/* parameters of canvas */
canvas{
  margin:auto;
  display:block;
  max-width: 100%; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/addons/p5.sound.min.js"></script>
    
    <meta charset="utf-8" />

  </head>
  <body>
  <main>
  <!-- TOGGLE BUTTON-->
  <button class="toggle-sidebar">Toggle</button>

  <!-- FLEXBOX-->
  <div class='flexgroup'>
  <!-- FLEXBOX Item1-->
    <div class="sidebar none">
     <p>
        SIDEBAR
      </p>
    </div>
   
  <!-- FLEXBOX Item2-->
    <div class='image'>
      <div id="canvas">
  <!-- P5.JS-->    
      </div>
    </div>
  </div>
</main>
  </body>
</html>