body {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
max-width: 100%;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
}
h1, h2, h3 {
color: #2c3e50;
}
.container {
background-color: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.subscription-form {
background-color: #e8f4f8;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
}
.exercise-container {
display: none;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input, select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
button {
background-color: #3498db;
color: white;
border: none;
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
button:hover {
background-color: #2980b9;
}
.exercise-text {
line-height: 2;
font-size: 18px;
}
.gap {
border-bottom: 1px solid #333;
padding: 0 5px;
margin: 0 3px;
min-width: 50px;
display: inline-block;
}
input.gap-input {
width: 50px;
border: none;
border-bottom: 1px solid #333;
font-size: 16px;
text-align: center;
}
.result {
margin-top: 30px;
padding: 20px;
background-color: #eafaf1;
border-radius: 8px;
display: none;
}
.certificate {
text-align: center;
margin-top: 30px;
padding: 20px;
border: 2px solid #2c3e50;
border-radius: 8px;
display: none;
}
.difficulty-selector {
margin-bottom: 20px;
}
.error {
color: red;
font-size: 14px;
}
#certificatePreview {
position: relative;
width: 100%;
height: 450px;
background-color: #fff;
border: 10px solid transparent;
border-image: linear-gradient(45deg, #f39c12, #e67e22, #d35400, #c0392b, #e74c3c) 1;
box-sizing: border-box;
overflow: hidden;
}
.certificate-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.07;
z-index: 0;
background-position: center;
background-repeat: no-repeat;
background-size: 70%;
}
.certificate-content {
position: relative;
z-index: 1;
padding: 20px;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.certificate-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.certificate-title {
flex-grow: 1;
text-align: center;
}
.certificate-logo {
width: 120px;
height: 60px;
}
.certificate-footer {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.certificate-qr {
width: 120px;
height: 120px;
display: flex;
justify-content: center;
align-items: center;
}
.certificate-qr img {
max-width: 100%;
max-height: 100%;
}
.certificate-signature {
flex-grow: 1;
text-align: center;
}
.triangle-pattern {
position: absolute;
width: 150px;
height: 120px;
}
.triangle-pattern.top-right {
top: 0;
right: 0;
}
.triangle-pattern.bottom-left {
bottom: 0;
left: 0;
}
Exercice de Grammaire: Les Articles Contractés
Inscrivez-vous pour commencer l’exercice
Veuillez vous abonner et remplir vos informations pour accéder à l’exercice.
Complétez le texte avec les articles contractés appropriés
Choisissez le niveau de difficulté:
Facile
Moyen
Difficile
Les Articles Contractés en Français (Niveau Facile)
Chaque samedi, je vais cinéma avec mes amis. Nous adorons regarder films d’aventure ensemble. Après le film, nous mangeons restaurant italien près du cinéma. Les enfants jouent jeux vidéo et vont ensuite parc. Là, ils jouent balançoires et discutent plans pour la semaine. Elle parle dernier livre qu’elle a commencé à lire. Nous achetons fruits frais marché local le dimanche. Ils reviennent travail tard, mais les chiens aiment courir parcs avant la nuit. Les livres, ils les rangent étagères. Je pense voyages que j’aimerais faire plus tard. Il joue football avec son équipe tous les mercredis. Nous parlons projets de notre association. Elle revient gymnase après l’entraînement. Ils vont magasins pour acheter des vêtements. J’ai peur araignées. Je parle temps avec mes voisins. Ils jouent cartes pendant les soirées. Nous revenons théâtre après le spectacle. Elle pense enfants de son école lors des réunions. Il parle voyage qu’il a prévu en Italie. Ils vont fêtes de famille chaque année.
Les Articles Contractés en Français (Niveau Moyen)
La voiture voisin est rapide et il l’utilise pour se rendre réunions importantes de son travail. Les feuilles arbres changent de couleur et tombent avec l’arrivée de l’automne, marquant la fin de la saison chaude. Nous discutons souvent dernier documentaire que nous avons regardé ensemble, analysant les thèmes abordés. Les clés maison sont difficiles à retrouver quand on est pressé, surtout le matin. Elle va cours de danse pour se détendre après une longue journée de travail. Ils habitent à proximité magasins et vont souvent faire du shopping le week-end. Je vais concerts de musique classique pour apprécier la beauté de la musique. Le goût café est plus intense le matin, un rituel pour bien commencer la journée. Ils parlent défis rencontrés lors de leur voyage à l’étranger, partageant leurs expériences. Nous allons montagnes pour faire de la randonnée et profiter de la nature. La couleur fleurs dans son jardin est éclatante, attirant les regards de tous les passants. Elle a offert un cadeau enfants du quartier pour Noël. Le bruit vagues est apaisant quand on se promène sur la plage. Ils se souviennent moments heureux passés ensemble durant leur enfance. Je suis allé concerts de jazz hier soir, c’était une expérience unique. La qualité produits locaux est excellente, nous devrions les soutenir. Il a participé jeux olympiques l’année dernière et a remporté une médaille. La fin film était émouvante. Ils parlent événements marquants de l’histoire moderne. Nous allons îles en vacances pour nous détendre. Le son cloches de l’église est mélodieux. Elle a donné de l’argent personnes dans le besoin. Le début livre était lent, mais la suite est passionnante. Ils discutent animaux de la ferme.
Les Articles Contractés en Français (Niveau Difficile)
La complexité règles grammaticales françaises représente un défi pour les étudiants étrangers, surtout lorsqu’il s’agit d’assimiler l’usage langage soutenu dans les textes littéraires. La valeur œuvres d’art réside dans leur capacité à transcender le temps et les cultures, offrant une perspective unique sur l’histoire humaine. L’accès savoir est devenu plus facile grâce à la technologie moderne, mais il est crucial de développer un esprit critique pour distinguer les informations fiables. Ils sont conscients enjeux environnementaux et cherchent activement des solutions durables pour protéger notre planète. La beauté paysages alpins attire de nombreux touristes chaque année, fascinés par la majesté des montagnes et la pureté de l’air. Il se souvient jour où ils se sont rencontrés, un moment qui a changé sa vie à jamais. L’importance détails est primordiale dans les enquêtes policières, où chaque indice peut mener à la résolution d’un crime. L’analyse texte littéraire exige une attention particulière, car les subtilités de la langue peuvent révéler des significations cachées. Ils parlent conséquences de la crise économique mondiale, cherchant des moyens de surmonter les difficultés. L’influence décisions politiques est considérable sur la vie quotidienne des citoyens. La difficulté exercices de grammaire augmente à mesure que l’on avance dans l’apprentissage, testant les limites de nos connaissances. Il a une préférence pour le goût vin rouge, surtout celui de la région de Bordeaux. Ils parlent avantages de la technologie dans le domaine de l’éducation. L’accès données personnelles est strictement réglementé pour protéger la vie privée. La complexité problème est évidente pour les experts. Ils sont conscients risques liés à ce projet innovant. L’importance détails est cruciale dans la rédaction de rapports scientifiques. L’analyse marché est complexe en raison de la concurrence internationale. Ils parlent résultats de l’enquête avec les journalistes. L’influence décisions économiques est forte sur les entreprises locales. La difficulté questions posées lors de l’examen était notable. Il a une préférence pour le goût thé vert, surtout celui importé du Japon. Ils parlent enjeux politiques actuels avec passion. L’accès informations sensibles est strictement contrôlé pour des raisons de sécurité nationale.
Résultat
Certificat de Réussite
Exercice de Grammaire: Les Articles Contractés
Ce certificat atteste que
a complété avec succès l’exercice sur les articles contractés en français
Score: / 100
Niveau:
Date:
// Variables globales
let currentDifficulty = ‘facile’;
let userInfo = {
prenom: ”,
nom: ”,
email: ”
};
// Logo Aplenguas en SVG
const aplenguas_logo_svg = `
`;
// Attente que le DOM soit chargé
document.addEventListener(‘DOMContentLoaded’, function() {
// Éléments du DOM
const startButton = document.getElementById(‘startButton’);
const changeDifficultyButton = document.getElementById(‘changeDifficultyButton’);
const checkButton = document.getElementById(‘checkButton’);
const generatePdfButton = document.getElementById(‘generatePdfButton’);
const difficultySelect = document.getElementById(‘difficultySelect’);
// Définir l’arrière-plan du certificat
const certificateBackground = document.querySelector(‘.certificate-background’);
certificateBackground.style.backgroundImage = `url(‘data:image/svg+xml;base64,${btoa(aplenguas_logo_svg)}’)`;
// Ajouter les logos SVG
const headerLogo = document.getElementById(‘certificateHeaderLogo’);
const footerLogo = document.getElementById(‘certificateFooterLogo’);
headerLogo.innerHTML = aplenguas_logo_svg;
footerLogo.innerHTML = aplenguas_logo_svg;
// Ajouter aussi le logo au container caché pour l’exportation PDF
document.getElementById(‘logoSvgContainer’).innerHTML = aplenguas_logo_svg;
// Ajout des écouteurs d’événements
startButton.addEventListener(‘click’, startExercise);
changeDifficultyButton.addEventListener(‘click’, changeDifficulty);
checkButton.addEventListener(‘click’, checkAnswers);
generatePdfButton.addEventListener(‘click’, generatePdf);
// Générer le QR code
function generateQRCode() {
const qrCodeContainer = document.getElementById(‘qrCodeContainer’);
qrCodeContainer.innerHTML = ”;
try {
// Version du QR code (1-40) avec un niveau de correction d’erreur ‘L’
var qr = qrcode(4, ‘L’);
qr.addData(‘https://aplenguas.com’);
qr.make();
qrCodeContainer.innerHTML = qr.createImgTag(4);
} catch (error) {
console.error(“Erreur lors de la génération du QR code:”, error);
// Fallback si la génération du QR code échoue
qrCodeContainer.innerHTML = ‘
‘;
}
}
// Fonction pour démarrer l’exercice
function startExercise() {
// Validation des champs
const prenom = document.getElementById(‘prenom’).value.trim();
const nom = document.getElementById(‘nom’).value.trim();
const email = document.getElementById(‘email’).value.trim();
const subscribe = document.getElementById(‘subscribe’).checked;
// Réinitialisation des messages d’erreur
document.getElementById(‘prenomError’).textContent = ”;
document.getElementById(‘nomError’).textContent = ”;
document.getElementById(‘emailError’).textContent = ”;
document.getElementById(‘subscribeError’).textContent = ”;
let isValid = true;
// Vérification des champs
if (!prenom) {
document.getElementById(‘prenomError’).textContent = ‘Veuillez entrer votre prénom.’;
isValid = false;
}
if (!nom) {
document.getElementById(‘nomError’).textContent = ‘Veuillez entrer votre nom.’;
isValid = false;
}
if (!email) {
document.getElementById(‘emailError’).textContent = ‘Veuillez entrer votre email.’;
isValid = false;
} else if (!isValidEmail(email)) {
document.getElementById(‘emailError’).textContent = ‘Veuillez entrer un email valide.’;
isValid = false;
}
if (!subscribe) {
document.getElementById(‘subscribeError’).textContent = ‘Vous devez vous abonner pour continuer.’;
isValid = false;
}
if (isValid) {
// Enregistrement des informations de l’utilisateur
userInfo.prenom = prenom;
userInfo.nom = nom;
userInfo.email = email;
// Affichage de l’exercice
document.getElementById(‘subscriptionForm’).style.display = ‘none’;
document.getElementById(‘exerciseContainer’).style.display = ‘block’;
// Affichage de l’exercice du niveau sélectionné
showExercise(currentDifficulty);
}
}
// Validation d’email simple
function isValidEmail(email) {
const re = /^[^s@]+@[^s@]+.[^s@]+$/;
return re.test(email);
}
// Fonction pour changer le niveau de difficulté
function changeDifficulty() {
const newDifficulty = difficultySelect.value;
showExercise(newDifficulty);
currentDifficulty = newDifficulty;
// Réinitialiser les champs de saisie
const inputs = document.querySelectorAll(‘.gap-input’);
inputs.forEach(input => {
input.value = ”;
input.style.backgroundColor = ”;
});
// Cacher le résultat
document.getElementById(‘resultContainer’).style.display = ‘none’;
document.getElementById(‘certificatePreview’).style.display = ‘none’;
}
// Fonction pour afficher l’exercice sélectionné
function showExercise(difficulty) {
document.getElementById(‘exerciseFacile’).style.display = ‘none’;
document.getElementById(‘exerciseMoyen’).style.display = ‘none’;
document.getElementById(‘exerciseDifficile’).style.display = ‘none’;
document.getElementById(‘exercise’ + difficulty.charAt(0).toUpperCase() + difficulty.slice(1)).style.display = ‘block’;
}
// Fonction pour vérifier les réponses
function checkAnswers() {
const inputs = document.querySelectorAll(‘#exercise’ + currentDifficulty.charAt(0).toUpperCase() + currentDifficulty.slice(1) + ‘ .gap-input’);
let correctAnswers = 0;
inputs.forEach(input => {
const userAnswer = input.value.trim();
const correctAnswer = input.getAttribute(‘data-answer’);
if (userAnswer.toLowerCase() === correctAnswer.toLowerCase()) {
input.style.backgroundColor = ‘#d4edda’;
correctAnswers++;
} else {
input.style.backgroundColor = ‘#f8d7da’;
}
});
// Calcul du score
const score = Math.round((correctAnswers / 25) * 100);
// Affichage du résultat
document.getElementById(‘scoreDisplay’).textContent = `Votre score est de ${score}% (${correctAnswers} réponses correctes sur 25)`;
document.getElementById(‘resultContainer’).style.display = ‘block’;
// Prévisualisation du certificat
document.getElementById(‘certificateNamePreview’).textContent = `${userInfo.prenom} ${userInfo.nom}`;
document.getElementById(‘certificateScorePreview’).textContent = score;
document.getElementById(‘certificateLevelPreview’).textContent = currentDifficulty.charAt(0).toUpperCase() + currentDifficulty.slice(1);
document.getElementById(‘certificateDatePreview’).textContent = new Date().toLocaleDateString(‘fr-FR’);
document.getElementById(‘certificatePreview’).style.display = ‘block’;
// Générer le QR code pour le certificat
generateQRCode();
}
// Fonction pour générer le PDF du certificat
function generatePdf() {
// Importer la bibliothèque jsPDF
const { jsPDF } = window.jspdf;
// Créer un nouveau document PDF
const doc = new jsPDF({
orientation: ‘landscape’,
unit: ‘mm’,
format: ‘a4’
});
// Récupérer l’élément du certificat
const certificateElement = document.getElementById(‘certificatePreview’);
// Récupérer les dimensions
const width = doc.internal.pageSize.getWidth();
const height = doc.internal.pageSize.getHeight();
// Ajouter le style pour l’exportation PDF
certificateElement.style.border = ‘none’;
certificateElement.style.width = ‘100%’;
certificateElement.style.height = ‘100%’;
// Ajouter le logo SVG comme image de fond
const logoSvg = document.getElementById(‘logoSvgContainer’).querySelector(‘svg’);
if (logoSvg) {
// Réduire l’opacité pour l’image de fond
logoSvg.style.opacity = ‘0.05’;
// Utiliser svg2pdf.js pour convertir le SVG en PDF
try {
const svgElement = document.getElementById(‘logoSvgContainer’).querySelector(‘svg’);
const scale = Math.min(width / svgElement.viewBox.baseVal.width, height / svgElement.viewBox.baseVal.height) * 0.7;
const offsetX = (width – svgElement.viewBox.baseVal.width * scale) / 2;
const offsetY = (height – svgElement.viewBox.baseVal.height * scale) / 2;
doc.svg(svgElement, {
x: offsetX,
y: offsetY,
width: svgElement.viewBox.baseVal.width * scale,
height: svgElement.viewBox.baseVal.height * scale
});
} catch (error) {
console.error(“Erreur lors de l’ajout du SVG:”, error);
}
}
// Ajouter les informations du certificat
doc.setFontSize(30);
doc.setTextColor(44, 62, 80); // couleur #2c3e50
doc.text(‘Certificat de Réussite’, width / 2, 30, { align: ‘center’ });
doc.setFontSize(20);
doc.text(‘Exercice de Grammaire: Les Articles Contractés’, width / 2, 40, { align: ‘center’ });
doc.setFontSize(16);
doc.text(‘Ce certificat atteste que’, width / 2, 60, { align: ‘center’ });
doc.setFontSize(24);
doc.setTextColor(52, 73, 94); // couleur #34495e
doc.text(`${userInfo.prenom} ${userInfo.nom}`, width / 2, 70, { align: ‘center’ });
doc.setFontSize(16);
doc.setTextColor(44, 62, 80); // retour à #2c3e50
doc.text(‘a complété avec succès l’exercice sur les articles contractés en français’, width / 2, 80, { align: ‘center’ });
doc.setFontSize(18);
const score = document.getElementById(‘certificateScorePreview’).textContent;
doc.text(`Score: ${score} / 100`, width / 2, 95, { align: ‘center’ });
const niveau = document.getElementById(‘certificateLevelPreview’).textContent;
doc.text(`Niveau: ${niveau}`, width / 2, 105, { align: ‘center’ });
const date = document.getElementById(‘certificateDatePreview’).textContent;
doc.text(`Date: ${date}`, width / 2, 115, { align: ‘center’ });
// Ajouter la signature
doc.line(width / 2 – 30, 140, width / 2 + 30, 140);
doc.text(‘Signature du Professeur’, width / 2, 150, { align: ‘center’ });
// Ajout du QR code
try {
const qrImg = document.querySelector(‘#qrCodeContainer img’);
if (qrImg) {
doc.addImage(qrImg.src, ‘PNG’, 30, 130, 30, 30);
}
} catch (error) {
console.error(“Erreur lors de l’ajout du QR code:”, error);
}
// Ajout des triangles décoratifs
function addTriangle(x1, y1, x2, y2, x3, y3, color) {
doc.setFillColor(color);
doc.triangle(x1, y1, x2, y2, x3, y3, ‘F’);
}
// Triangles en haut à droite
addTriangle(width – 40, 20, width – 30, 30, width – 20, 20, ‘#f39c12’);
addTriangle(width – 30, 20, width – 20, 30, width – 10, 20, ‘#e67e22’);
addTriangle(width – 20, 20, width – 10, 30, width, 20, ‘#f39c12’);
// Triangles en bas à gauche
addTriangle(20, height – 20, 30, height – 30, 40, height – 20, ‘#34495e’);
addTriangle(10, height – 20, 20, height – 30, 30, height – 20, ‘#2c3e50’);
addTriangle(0, height – 20, 10, height – 30, 20, height – 20, ‘#34495e’);
// Sauvegarder le PDF
const filename = `certificat_${userInfo.prenom.toLowerCase()}_${userInfo.nom.toLowerCase()}_${currentDifficulty}.pdf`;
doc.save(filename);
// Restaurer le style du certificat
certificateElement.style.border = ’10px solid transparent’;
certificateElement.style.borderImage = ‘linear-gradient(45deg, #f39c12, #e67e22, #d35400, #c0392b, #e74c3c) 1’;
}
});