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>
我正在尝试使用 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>