That's my code:
import React, { useEffect, useRef } from "react";
import PropTypes from "prop-types";
import "../fonts/fonts.css";
import "../App.css";
import { motion } from "framer-motion";
import { useParams } from "react-router-dom";
const Canvas = ({ height, width, imageUrl, courseId }) => {
const canvasRef = useRef(null);
const { userId, userName } = useParams();
function divideUserId(userId) {
const cleanedUserId = userId.replace(/[^\w]/g, "").toUpperCase();
const parts = [];
for (let i = 0; i < 3; i++) {
const startIndex = i * 3;
const endIndex = startIndex + 3;
const part = cleanedUserId.slice(startIndex, endIndex);
parts.push(part);
}
return parts;
}
const draw = (context) => {
const date = new Date().toLocaleDateString();
const kursyPomocniczne = [
{
secretId: "mat_podst",
name: "Kurs do matury podstawowej",
},
{
secretId: "mat_rozszerz",
name: "Kurs do matury rozszerzonej",
},
{
secretId: "mat_stud",
name: "Kurs matematyki studenckiej",
},
];
const courseName = kursyPomocniczne.find(
(course) => course.secretId === courseId
).name;
const userText = userName.split("+").join(" ");
const userTextWidth = context.measureText(userText).width;
const userTextHeight = 40; // Zakładamy, że wysokość tekstu to 40px
const canvasCenterX = context.canvas.width / 2;
const canvasCenterY = context.canvas.height / 2;
const userTextX = canvasCenterX - userTextWidth / 2;
const userTextY = canvasCenterY + (userTextHeight + 117 / 2);
const isFemale =
userText && userText.charAt(userText.length - 1).toUpperCase() === "A";
if (!isFemale) {
context.strokeStyle = "#192e50";
context.lineWidth = 4;
context.beginPath();
context.moveTo(501, 495);
context.lineTo(490, 495);
context.stroke();
context.beginPath();
context.moveTo(401, 536);
context.lineTo(390, 536);
context.stroke();
context.beginPath();
context.moveTo(721, 536);
context.lineTo(710, 536);
context.stroke();
} else {
context.strokeStyle = "#192e50";
context.lineWidth = 4;
context.beginPath();
context.moveTo(705, 536);
context.lineTo(694, 536);
context.stroke();
}
context.fillStyle = "#192e50";
context.font = "22px 'Serif', serif";
context.fillText(date, 330, 608);
context.fillStyle = "#192e50";
context.font = "56px 'Great Vibes', cursive";
context.fillText(userText, userTextX, userTextY);
const courseCanvas = document.createElement("canvas");
courseCanvas.width = 830;
courseCanvas.height = 706;
const courseContext = courseCanvas.getContext("2d");
const courseCenterX = courseContext.canvas.width / 2;
const courseTextWidth = courseContext.measureText(courseName).width;
const courseTextX = courseCenterX - courseTextWidth / 2;
courseContext.fillStyle = "#192e50";
courseContext.font = "18px 'Serif', serif";
courseContext.fillText(courseName.toUpperCase(), courseTextX, 520);
context.drawImage(courseCanvas, 0, 0);
const tempCanvas = context.canvas.cloneNode();
const singContext = tempCanvas.getContext("2d");
singContext.fillStyle = "#192e50";
singContext.font = "9px 'Ubuntu', serif";
singContext.justifyContent = "center";
const parts = divideUserId(userId);
parts.forEach((part, index) => {
const partY = canvasCenterY - (40 - 572 / 2) + 10 * index;
singContext.globalAlpha = 0.3;
singContext.fillText(part, 881, partY);
});
context.drawImage(tempCanvas, 0, 0);
singContext.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
};
useEffect(() => {
const canvas = canvasRef.current;
const context = canvas.getContext("2d");
const image = new Image();
image.onload = () => {
context.drawImage(image, 0, 0, width, height);
draw(context);
};
image.src = imageUrl;
}, [draw, height, width, imageUrl]);
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
>
<canvas
ref={canvasRef}
height={height}
width={width}
className="rounded-xl mx-auto xl:w-4/5 xl:h-3/5 lg:w-3/5 lg:h-3/5 md:w-3/5 md:h-3/5 sm:w-3/5 sm:h-3/5 xs:w-3/5 xs:h-3/5"
/>
</motion.div>
);
};
Canvas.propTypes = {
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
imageUrl: PropTypes.string.isRequired,
};
export default Canvas;
Well, I've tried almost every option with font face constructor, adding font face in App.css, creating file from where I'm importing this fonts, downloading fonts as a woff, as ttf and importing from folder, importing from google fonts link and none of them work. The font is not being loaded as a component mounts, it actually has to load before the component is rendered so that for sure the font will be included. Now, I have to refresh the page to see this font. For default the font is being rendered as Comic Sans since it's default cursive font. What should I do?
Well, I managed to solve the issue through workaround using another div which force the font to load before the canvas is being rendered:
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
>
<div
style={{
fontFamily: "Great Vibes",
}}
className="absolute -left-10"
>
.
</div>
<canvas
ref={canvasRef}
height={height}
width={width}
className="rounded-xl mx-auto w-10/12"
/>
</motion.div>