I'm coding a greeting card generator to train in VueJS 3. Everything is working correctly, apart from one thing, look at my code:
<template>
<div>
<h1>greeting card generator</h1>
<div class="board">
<canvas id='myCanvas' :width="size.w" :height="size.h" tabindex='0'
style="border:1px solid #000000;"
></canvas>
</div>
<textarea
:style="'width:' + size.w + 'px; resize:none;'"
v-model="texte"
placeholder="Write your text here">
</textarea>
</div>
</template>
<script>
import {
defineComponent, onMounted, ref, reactive, watch,
} from 'vue';
export default defineComponent({
setup() {
const myCanvas = ref(null);
const texte = ref('');
const rapport = ref(0);
const size = reactive({
w: window.innerWidth * 0.8,
h: (window.innerWidth * 0.8) / 1.8083832335329342,
});
function drawText() {
const fontSize = 0.05 * window.innerWidth - 10;
myCanvas.value.font = `${fontSize}px Adrip`;
myCanvas.value.textAlign = 'center';
const x = size.w / 2;
const lineHeight = fontSize;
const lines = texte.value.split('\n');
for (let i = 0; i < lines.length; i += 1) {
myCanvas.value.fillText(
lines[lines.length - i - 1],
x,
(size.h * 0.98) - (i * lineHeight),
);
}
}
function initCarte() {
const background = new Image();
background.src = '/img/fond.jpeg';
background.onload = function () {
rapport.value = background.naturalWidth / background.naturalHeight;
size.h = size.w / rapport.value;
try {
myCanvas.value.drawImage(background, 0, 0, size.w, size.h);
} catch (e) {
console.log(`ERREUR DE CHARGEMENT D'IMAGE: ${e}`);
}
drawText();
};
}
function handleResize() {
size.w = window.innerWidth * 0.8;
size.h = size.w / rapport.value;
initCarte();
}
window.addEventListener('resize', handleResize);
onMounted(() => {
const c = document.getElementById('myCanvas');
const ctx = c.getContext('2d');
myCanvas.value = ctx;
initCarte();
});
watch(texte, () => {
initCarte();
});
return {
myCanvas,
size,
texte,
};
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
@font-face {
font-family: 'Adrip';
src: local('Adrip'), url('/fonts/adrip1.ttf') format('truetype');
}
#myCanvas {
border: 1px solid grey;
}
</style>
Look at this line:
h: (window.innerWidth * 0.8) / 1.8083832335329342,
If I don't hardcode this and only put the canonical value window.innerWidth * 0.8, the image doesn't display, although the size.h = size.w / rapport.value; line executes correctly.
I really don't understand this behaviour, could somebody explain it to me? Also, if anybody has a clue on how it would be possible to load the image once and for all so that I don't have to load it at every refresh, it would be better :)
Thanks in advance!