I have a Flask app that use the template function of Flask to render a website like this
return render_template('editor.html',
skin_images=SKIN_IMAGES,
cloth_images=CLOTH_IMAGES,
hair_images=HAIR_IMAGES
)
Using this huge HTML File
<!DOCTYPE html>
<html lang="fr-FR">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" href="{{ url_for('static', filename='favicon.png') }}" />
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<link
href="{{ url_for('static', filename='editor.css') }}"
rel="stylesheet"
/>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<title>OR Editor</title>
</head>
<body>
<div>
<div style="position: absolute; top: 0.6rem; left: 0.6rem;">
<a class="btn btn-secondary mt-2" href="../">Home</a>
</div>
<div style="position: absolute; top: 0.6rem; right: 0.6rem;">
<button class="btn btn-primary mt-2" id="downloadBtn">Dowload</button>
</div>
<div style="height: 70vh;">
<!-- Preview canvas -->
<div style="text-align: center; padding: 8vh; display: block;">
<img id="preview" style="height: auto; width: 98vh;" />
</div>
<!-- Tabs navs -->
<ul class="nav nav-tabs mb-3" id="ex1" role="tablist">
<li class="nav-item" role="presentation">
<a
data-mdb-tab-init
class="nav-link active"
id="ex1-tab-1"
href="#ex1-tabs-1"
role="tab"
aria-controls="ex1-tabs-1"
aria-selected="true"
>Tab 1</a
>
</li>
<li class="nav-item" role="presentation">
<a
data-mdb-tab-init
class="nav-link"
id="ex1-tab-2"
href="#ex1-tabs-2"
role="tab"
aria-controls="ex1-tabs-2"
aria-selected="false"
>Tab 2</a
>
</li>
<li class="nav-item" role="presentation">
<a
data-mdb-tab-init
class="nav-link"
id="ex1-tab-3"
href="#ex1-tabs-3"
role="tab"
aria-controls="ex1-tabs-3"
aria-selected="false"
>Tab 3</a
>
</li>
</ul>
<!-- Tabs navs -->
</div>
<!-- Tabs content -->
<div class="tab-content" id="ex1-content">
<div
class="tab-pane fade show active"
id="ex1-tabs-1"
role="tabpanel"
aria-labelledby="ex1-tab-1"
>
{% for image in skin_images %}
<button
class="component-button"
data-component="skin"
data-value="{{ image }}"
>
<img src="{{ url_for('static', filename='skin/') }}" />
</button>
{% endfor %}
</div>
<div
class="tab-pane fade"
id="ex1-tabs-2"
role="tabpanel"
aria-labelledby="ex1-tab-2"
>
{% for image in cloth_images %}
<button
class="component-button"
data-component="cloth"
data-value="{{ image }}"
>
<img src="{{ url_for('static', filename='cloth/') }}" />
</button>
{% endfor %}
</div>
<div
class="tab-pane fade"
id="ex1-tabs-3"
role="tabpanel"
aria-labelledby="ex1-tab-3"
>
{% for image in hair_images %}
<button
class="component-button"
data-component="hair"
data-value="{{ image }}"
>
<img src="{{ url_for('static', filename='hair/') }}" />
</button>
{% endfor %}
</div>
</div>
</div>
<!-- MDB -->
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/7.2.0/mdb.umd.min.js"
></script>
<script>
// Render on load
renderPreview();
const componentButtons = document.querySelectorAll(".component-button");
let selected = {
skin: "default.png",
cloth: "default.png",
hair: "default.png",
};
componentButtons.forEach((button) => {
button.addEventListener("click", (e) => {
let component = button.dataset.component;
let value = button.dataset.value;
selected[component] = value;
renderPreview();
});
});
// Render on change
async function renderPreview() {
// Load images
let skin = selected.skin;
let cloth = selected.cloth;
let hair = selected.hair;
let skinImg = await fetch(`/static/skin/${skin}`);
let clothImg = await fetch(`/static/cloth/${cloth}`);
let hairImg = await fetch(`/static/hair/${hair}`);
let imSkin = await createImageBitmap(await skinImg.blob());
let imCloth = await createImageBitmap(await clothImg.blob());
let imHair = await createImageBitmap(await hairImg.blob());
// Composite
let canvas = document.createElement("canvas");
canvas.getContext("2d").drawImage(imSkin, 0, 0);
// canvas.getContext("2d").globalCompositeOperation = "destination-atop";
canvas.getContext("2d").drawImage(imCloth, 0, 0);
// canvas.getContext("2d").globalCompositeOperation = "destination-atop";
canvas.getContext("2d").drawImage(imHair, 0, 0);
// Update preview
document.getElementById("preview").src = canvas.toDataURL();
}
function old_old_renderPreview() {
// Get component selections
let skin = document.getElementById("skin").value;
let cloth = document.getElementById("cloth").value;
let hair = document.getElementById("hair").value;
// Call Flask route to render preview
fetch(
"/render_preview?skin=" + skin + "&cloth=" + cloth + "&hair=" + hair
)
.then((response) => response.blob())
.then((imageBlob) => {
document.getElementById("preview").src = URL.createObjectURL(
imageBlob
);
});
}
// Get component selections
function downloadAvatar() {
let skin = document.getElementById("skin").value;
let cloth = document.getElementById("cloth").value;
let hair = document.getElementById("hair").value;
let query = `/render_preview?skin=${skin}&cloth=${cloth}&hair=${hair}`;
// Trigger download
fetch(query)
.then((response) => response.blob())
.then((blob) => {
let url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = "avatar.png";
a.click();
});
}
// Add click handler
document
.getElementById("downloadBtn")
.addEventListener("click", downloadAvatar);
</script>
</body>
</html>
But when I try to launch it; I got the error
File "c:\Users\[REDACTED]\.vscode\extensions\ms-python.debugpy-2024.2.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 294, in _get_code_from_file
code = compile(f.read(), fname, 'exec')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\GitHub\ormaker\templates\editor.html", line 1
<!DOCTYPE html>
Any idea about what I do/is wrong ?