Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move common parts of the WebGL/WebGPU example pages to layouts #1889

Merged
merged 4 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 9 additions & 124 deletions templates/example-webgpu.html
Original file line number Diff line number Diff line change
@@ -1,124 +1,9 @@
{% extends "layouts/base.html" %}
{% block content %}
<div class="example">
<div class="example__header">
{% set total_ancestors = page.ancestors | length %}
{% set parent_idx = total_ancestors - 1 %}
{% set category = get_section(path=page.ancestors | nth(n=parent_idx)) %}
<h2 class="example__title">{{ category.title }} / {{ page.title }}</h2>
<a class="example__back" href="/examples-webgpu"><i class="icon icon--chevron-left"></i> Back to examples</a>
<a class="example__github"
href="https://github.com/bevyengine/bevy/blob/latest/{{ page.extra.github_code_path }}">
<i class="icon icon--github"></i> View in GitHub
</a>
</div>
<div class="assets-intro media-content">
<h2 class="warning">Support Warning</h2>
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop. If they don't work on
your configuration, you can check the WebGL2 examples <a href="/examples">here</a>.
</div>
<br />
<div class="example__canvas bevy-instance">
<div class="bevy-instance__progress-status" data-progress-status>
<div class="bevy-instance__progress-file" data-progress-file></div>
<div class="bevy-instance__progress-track">
<div class="bevy-instance__progress-bar" data-progress-bar></div>
</div>
</div>
<canvas class="bevy-instance__canvas" id="bevy" width="1280" height="720"></canvas>
</div>
<div class="example__code media-content">
{% set filename = page.extra.code_path | split(pat="/") | last %}
{{ filename }}:

{% set code = load_data(path=page.extra.code_path) %}
{% set code_md = "```rust" ~ newline ~ code ~ "```" %}
{{ code_md | markdown(inline=true) | safe }}
</div>
{% for shader in page.extra.shader_code_paths %}
<div class="example__code media-content">
{{ shader }}:

{% set code = load_data(path="static/assets/examples/" ~ shader) %}
{% set code_md = "```rust" ~ newline ~ code ~ "```" %}
{{ code_md | markdown(inline=true) | safe }}
</div>
{% endfor %}
</div>
<script type="module">
{#
// Hi curious user!
// This approach to add loading feedback on web is a big HACK. Please review `generate_wasm_examples.sh`
// to see the patches we're applying to the JS file to accept a custom `fetch`. This is a temporary
// workaround until Bevy has an in-engine mode for showing loading feedback. See:
// https://github.com/bevyengine/bevy-website/pull/355
#}

import { progressiveFetch } from '/tools.js';
import '/restart-audio-context.js'
import init from 'https://bevy-webgpu-examples.pages.dev/{{ category.title }}/{{ page.extra.technical_name }}/wasm_example.js'

const canvasEl = document.getElementById('bevy');

let once = false;
const observer_callback = (_mutations, _observer) => {
if (!once) {
// Lock the canvas aspect ratio to prevent the fit_canvas_to_parent setting from creating a feedback loop causing the canvas to grow on resize
canvasEl.style.aspectRatio = canvasEl.attributes.width.value / canvasEl.attributes.height.value;
once = true;
}
};

const observer = new MutationObserver(observer_callback);

const config = { attributeFilter: ['width', 'height'] };

observer.observe(canvasEl, config);

const progressStatusEl = document.querySelector('[data-progress-status]');
const progressFileEl = document.querySelector('[data-progress-file]');
const progressBarEl = document.querySelector('[data-progress-bar]');
let hideProgressTimeoutId;

async function loadingBarFetch(resource) {
return progressiveFetch(resource, {
start: ({ filename }) => {
progressStatusEl.style.display = 'block';
progressFileEl.textContent = filename;

if (hideProgressTimeoutId) {
clearTimeout(hideProgressTimeoutId);
}
},
update: ({ isIndeterminate, loadedPercent }) => {
progressBarEl.classList.toggle('bevy-instance__progress-bar--indeterminate', isIndeterminate);
progressBarEl.style.width = loadedPercent + '%';
},
finish: () => {
{#
// This is a little hack to avoid progress-bar flashing between assets. The thing
// is that we don't know how many assets are going to load, so we don't know which
// one is the last one. If a new asset starts loading within 50ms, then this timeout
// is cleared and the progress element stays visible, avoiding the flashing.
// The downside is that the progress bar shows for a brief moment once the wasm starts.
#}
hideProgressTimeoutId = setTimeout(() => {
progressStatusEl.style.display = 'none';
}, 50);
}
})
}
window.bevyLoadingBarFetch = loadingBarFetch;

{#
// The following .catch() is a simple filter to remove an exception thrown by winit in
// its normal control flow. This exception will always be thrown and is not an error.
// Details here: https://github.com/rust-windowing/winit/blob/master/src/platform_impl/web/event_loop/mod.rs
#}
init().catch((error) => {
if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
throw error;
}
});
</script>
{% endblock content %}
{% extends "layouts/example.html" %}

{% block examples_url %}/examples-webgpu{% endblock examples_url %}
{% block wasm_base_url %}https://bevy-webgpu-examples.pages.dev{% endblock wasm_base_url %}
{% block intro %}
<h2 class="warning">Support Warning</h2>
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop.
If they don't work on your configuration, you can check the WebGL2 examples <a href="/examples">here</a>.
{% endblock intro %}
131 changes: 8 additions & 123 deletions templates/example.html
Original file line number Diff line number Diff line change
@@ -1,123 +1,8 @@
{% extends "layouts/base.html" %}
{% block content %}
<div class="example">
<div class="example__header">
{% set total_ancestors = page.ancestors | length %}
{% set parent_idx = total_ancestors - 1 %}
{% set category = get_section(path=page.ancestors | nth(n=parent_idx)) %}
<h2 class="example__title">{{ category.title }} / {{ page.title }}</h2>
<a class="example__back" href="/examples"><i class="icon icon--chevron-left"></i> Back to examples</a>
<a class="example__github"
href="https://github.com/bevyengine/bevy/blob/latest/{{ page.extra.github_code_path }}">
<i class="icon icon--github"></i> View in GitHub
</a>
</div>
<div class="assets-intro media-content">
This example is running in WebGL2 and should work in most browsers. You can check the WebGPU examples <a href="/examples-webgpu">here</a>.
</div>
<br />
<div class="example__canvas bevy-instance">
<div class="bevy-instance__progress-status" data-progress-status>
<div class="bevy-instance__progress-file" data-progress-file></div>
<div class="bevy-instance__progress-track">
<div class="bevy-instance__progress-bar" data-progress-bar></div>
</div>
</div>
<canvas class="bevy-instance__canvas" id="bevy" width="1280" height="720"></canvas>
</div>

<div class="example__code media-content">
{% set filename = page.extra.code_path | split(pat="/") | last %}
{{ filename }}:

{% set code = load_data(path=page.extra.code_path) %}
{% set code_md = "```rust" ~ newline ~ code ~ "```" %}
{{ code_md | markdown(inline=true) | safe }}
</div>
{% for shader in page.extra.shader_code_paths %}
<div class="example__code media-content">
{{ shader }}:

{% set code = load_data(path="static/assets/examples/" ~ shader) %}
{% set code_md = "```rust" ~ newline ~ code ~ "```" %}
{{ code_md | markdown(inline=true) | safe }}
</div>
{% endfor %}
</div>
<script type="module">
{#
// Hi curious user!
// This approach to add loading feedback on web is a big HACK. Please review `generate_wasm_examples.sh`
// to see the patches we're applying to the JS file to accept a custom `fetch`. This is a temporary
// workaround until Bevy has an in-engine mode for showing loading feedback. See:
// https://github.com/bevyengine/bevy-website/pull/355
#}

import { progressiveFetch } from '/tools.js';
import '/restart-audio-context.js'
import init from 'https://bevy-webgl2-examples.pages.dev/{{ category.title }}/{{ page.extra.technical_name }}/wasm_example.js'

const canvasEl = document.getElementById('bevy');

let once = false;
const observer_callback = (_mutations, _observer) => {
if (!once) {
// Lock the canvas aspect ratio to prevent the fit_canvas_to_parent setting from creating a feedback loop causing the canvas to grow on resize
canvasEl.style.aspectRatio = canvasEl.attributes.width.value / canvasEl.attributes.height.value;
once = true;
}
};

const observer = new MutationObserver(observer_callback);

const config = { attributeFilter: ['width', 'height'] };

observer.observe(canvasEl, config);

const progressStatusEl = document.querySelector('[data-progress-status]');
const progressFileEl = document.querySelector('[data-progress-file]');
const progressBarEl = document.querySelector('[data-progress-bar]');
let hideProgressTimeoutId;

async function loadingBarFetch(resource) {
return progressiveFetch(resource, {
start: ({ filename }) => {
progressStatusEl.style.display = 'block';
progressFileEl.textContent = filename;

if (hideProgressTimeoutId) {
clearTimeout(hideProgressTimeoutId);
}
},
update: ({ isIndeterminate, loadedPercent }) => {
progressBarEl.classList.toggle('bevy-instance__progress-bar--indeterminate', isIndeterminate);
progressBarEl.style.width = loadedPercent + '%';
},
finish: () => {
{#
// This is a little hack to avoid progress-bar flashing between assets. The thing
// is that we don't know how many assets are going to load, so we don't know which
// one is the last one. If a new asset starts loading within 50ms, then this timeout
// is cleared and the progress element stays visible, avoiding the flashing.
// The downside is that the progress bar shows for a brief moment once the wasm starts.
#}
hideProgressTimeoutId = setTimeout(() => {
progressStatusEl.style.display = 'none';
}, 50);
}
})
}
window.bevyLoadingBarFetch = loadingBarFetch;

{#
// The following .catch() is a simple filter to remove an exception thrown by winit in
// its normal control flow. This exception will always be thrown and is not an error.
// Details here: https://github.com/rust-windowing/winit/blob/master/src/platform_impl/web/event_loop/mod.rs
#}
init().catch((error) => {
if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
throw error;
}
});
</script>
{% endblock content %}
{% extends "layouts/example.html" %}

{% block examples_url %}/examples{% endblock examples_url %}
{% block wasm_base_url %}https://bevy-webgl2-examples.pages.dev{% endblock wasm_base_url %}
{% block intro %}
This example is running in WebGL2 and should work in most browsers.
You can check the WebGPU examples <a href="/examples-webgpu">here</a>.
{% endblock intro %}
50 changes: 10 additions & 40 deletions templates/examples-webgpu.html
Original file line number Diff line number Diff line change
@@ -1,40 +1,10 @@
{% extends "layouts/page-with-menu.html" %}
{% import "macros/assets.html" as assets_macros %}
{% block page_name %}Examples{% endblock page_name %}
{% block mobile_page_menu %}{{ assets_macros::assets_menu(prefix="page-menu", root=section) }}{% endblock mobile_page_menu %}
{% block page_menu %}{{ assets_macros::assets_menu(prefix="page-menu", root=section) }}{% endblock page_menu %}
{% block page_content %}
<div class="assets">
<div class="assets-intro media-content">
These examples demonstrate how to use Bevy's features in a minimal, easy to understand way. Click an example below
to run it in
your browser (using WASM + WebGPU) and view the source code. You can also view these examples (and others) in the
<a href="https://github.com/bevyengine/bevy/tree/main/examples#examples">Bevy repo</a>.
<h2 class="warning">Support Warning</h2>
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop. If they don't work on
your configuration, you can check the WebGL2 examples <a href="/examples">here</a>.
</div>
<div class="assets-search">
<input class="assets-search__input"
type="text"
id="assets-search"
placeholder="Search Example">
</div>
{% for subsection in section.subsections %}
{% set section = get_section(path=subsection) %}
<h1 class="asset-section" id="{{ section.title | slugify }}">
{{ section.title }}<a class="anchor-link" href="#{{ section.title | slugify }}">#</a>
</h1>
{% if section.pages %}
<div class="item-grid item-grid--multi-cols">
{% set pages = section.pages %}
{% if section.extra.sort_order_reversed %}
{% set pages = section.pages | reverse %}
{% endif %}
{% for post in pages %}{{ assets_macros::card(post=post) }}{% endfor %}
</div>
{% endif %}
{% endfor %}
</div>
<script type="module">import '/assets.js'</script>
{% endblock page_content %}
{% extends "layouts/examples.html" %}

{% block intro %}
These examples demonstrate how to use Bevy's features in a minimal, easy to understand way.
Click an example below to run it in your browser (using WASM + WebGPU) and view the source code.
You can also view these examples (and others) in the <a href="https://github.com/bevyengine/bevy/tree/main/examples#examples">Bevy repo</a>.
<h2 class="warning">Support Warning</h2>
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop.
If they don't work on your configuration, you can check the WebGL2 examples <a href="/examples">here</a>.
{% endblock intro %}
49 changes: 8 additions & 41 deletions templates/examples.html
Original file line number Diff line number Diff line change
@@ -1,41 +1,8 @@
{% extends "layouts/page-with-menu.html" %}
{% import "macros/assets.html" as assets_macros %}
{% block page_name %}Examples{% endblock page_name %}
{% block mobile_page_menu %}{{ assets_macros::assets_menu(prefix="page-menu", root=section) }}{% endblock mobile_page_menu %}
{% block page_menu %}{{ assets_macros::assets_menu(prefix="page-menu", root=section) }}{% endblock page_menu %}
{% block page_content %}
<div class="assets">
<div class="assets-intro media-content">
These examples demonstrate how to use Bevy's features in a minimal, easy to understand way. Click an example below
to run it in
your browser (using WASM + WebGL) and view the source code. You can also view these examples (and others) in the
<a href="https://github.com/bevyengine/bevy/tree/latest/examples#examples">Bevy repo</a>.
<p>
If you would like to try WASM + WebGPU, you can explore our <a href="/examples-webgpu">live WebGPU examples</a>
page.
</p>
</div>
<div class="assets-search">
<input class="assets-search__input"
type="text"
id="assets-search"
placeholder="Search Example">
</div>
{% for subsection in section.subsections %}
{% set section = get_section(path=subsection) %}
<h1 class="asset-section" id="{{ section.title | slugify }}">
{{ section.title }}<a class="anchor-link" href="#{{ section.title | slugify }}">#</a>
</h1>
{% if section.pages %}
<div class="item-grid item-grid--multi-cols">
{% set pages = section.pages %}
{% if section.extra.sort_order_reversed %}
{% set pages = section.pages | reverse %}
{% endif %}
{% for post in pages %}{{ assets_macros::card(post=post) }}{% endfor %}
</div>
{% endif %}
{% endfor %}
</div>
<script type="module">import '/assets.js'</script>
{% endblock page_content %}
{% extends "layouts/examples.html" %}

{% block intro %}
These examples demonstrate how to use Bevy's features in a minimal, easy to understand way.
Click an example below to run it in your browser (using WASM + WebGL) and view the source code.
You can also view these examples (and others) in the <a href="https://github.com/bevyengine/bevy/tree/latest/examples#examples">Bevy repo</a>.
<p>If you would like to try WASM + WebGPU, you can explore our <a href="/examples-webgpu">live WebGPU examples</a> page.</p>
{% endblock intro %}
Loading