Introduction
Une application de dessin sur une page Web est une excellente occasion de s'entraîner à travailler avec HTML, CSS et JavaScript, ainsi que de créer des outils interactifs. Dans cet article, nous allons créer une application de dessin simple qui comprendra des outils pour dessiner différentes formes, choisir des couleurs et enregistrer l'image créée. L'application aura une interface conviviale avec plusieurs outils, des paramètres de taille de pinceau et de couleur.
Pour le code source complet et éventuellement des améliorations supplémentaires, consultez notre GitHub.

Préparation
Avant de commencer à écrire le code, assurez-vous que vous avez les composants nécessaires :
HTML — pour la structure de la page.
CSS — pour styliser l'interface.
JavaScript — pour la fonctionnalité de dessin, le traitement des événements et l'enregistrement des images.
Nous aurons également besoin d'icônes pour les boutons qui seront utilisés pour sélectionner les outils de dessin. Ces icônes seront téléchargées dans notre projet via les fichiers du dossier icons.
Création de HTML et connexion de photos et de fichiers
Commençons par créer une page HTML. Ce sera la structure principale de notre application.
HTML crée la structure de la page et définit le balisage de tous les éléments qui seront affichés dans l'application. Voici une description plus détaillée de chaque élément du code HTML :
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Приложение для рисования</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="script.js" defer></script>
</head>
<body>
<div class="container">
<!-- Панель инструментов -->
<section class="tools-board">
<div class="row">
<label class="title">Формы</label>
<ul class="options">
<!-- Инструмент для рисования прямоугольника -->
<li class="option tool" id="rectangle">
<img src="icons/rectangle.svg" alt="Rectangle">
<span>Прямоугольник</span>
</li>
<!-- Инструмент для рисования круга -->
<li class="option tool" id="circle">
<img src="icons/circle.svg" alt="Circle">
<span>Круг</span>
</li>
<!-- Инструмент для рисования треугольника -->
<li class="option tool" id="triangle">
<img src="icons/triangle.svg" alt="Triangle">
<span>Треугольник</span>
</li>
<li class="option">
<input type="checkbox" id="fill-color">
<label for="fill-color">Цвет заливки</label>
</li>
</ul>
</div>
<div class="row">
<label class="title">Опции</label>
<ul class="options">
<!-- Инструмент кисть -->
<li class="option active tool" id="brush">
<img src="icons/brush.svg" alt="Brush">
<span>Щетка</span>
</li>
<!-- Инструмент ластик -->
<li class="option tool" id="eraser">
<img src="icons/eraser.svg" alt="Eraser">
<span>Ластик</span>
</li>
<!-- Ползунок для изменения размера кисти -->
<li class="option">
<input type="range" id="size-slider" min="1" max="30" value="5">
</li>
</ul>
</div>
<div class="row colors">
<label class="title">Цвета</label>
<ul class="options">
<!-- Кнопки выбора цвета -->
<li class="option"></li>
<li class="option selected"></li>
<li class="option"></li>
<li class="option"></li>
<li class="option">
<input type="color" id="color-picker" value="#4A98F7">
</li>
</ul>
</div>
<div class="row buttons">
<!-- Кнопки очистки и сохранения -->
<button class="clear-canvas">Очистить</button>
<button class="save-img">Сохранить как фото</button>
</div>
</section>
<!-- Холст для рисования -->
<section class="drawing-board">
<canvas></canvas>
</section>
</div>
</body>
</html>Explication HTML :
<section class="tools-board">:Il s'agit d'une barre d'outils qui contient plusieurs options pour l'utilisateur. Ici, vous pouvez choisir la forme (rectangle, cercle, triangle), la couleur du pinceau, la taille du pinceau et d'autres paramètres.
<ul class="options">:À l'intérieur de la barre d'outils, des listes (
<ul>) sont créées, chacune représentant un groupe d'options. Ceci est une liste de boutons pour sélectionner une forme (rectangle, cercle, etc.), changer la couleur, la taille du pinceau et d'autres paramètres.
<canvas>:C'est la toile principale sur laquelle le dessin aura lieu. Elle ne contient pas de contenu par défaut et utilise JavaScript pour dessiner.
Boutons et curseurs:
Les boutons « Effacer » et « Enregistrer comme photo » vous permettent d'effacer la toile et d'enregistrer l'image respectivement. Le curseur (
<input type="range">) vous permet de redimensionner le pinceau.
Boutons de couleur:
Dans la section des couleurs, il y a plusieurs boutons pour sélectionner la couleur du pinceau. Chaque bouton représente une couleur, et le dernier élément est un élément pour sélectionner une couleur à l'aide d'un sélecteur de couleur standard.
Style
Maintenant que la structure HTML est prête, vous pouvez passer au style avec CSS. Voici un exemple de styles pour notre application :
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #040925;
}
.container {
display: flex;
width: 100%;
gap: 10px;
padding: 10px;
max-width: 1050px;
}
section {
background: #fff;
border-radius: 7px;
}
.tools-board {
width: 210px;
padding: 15px 22px 0;
}
.tools-board .row {
margin-bottom: 20px;
}
.row .options {
list-style: none;
margin: 10px 0 0 5px;
}
.row .options .option {
display: flex;
cursor: pointer;
align-items: center;
margin-bottom: 10px;
}
.option:is(:hover, .active) img {
filter: invert(17%) sepia(90%) saturate(3000%) hue-rotate(900deg) brightness(100%) contrast(100%);
}
.option :where(span, label) {
color: #5A6168;
cursor: pointer;
padding-left: 10px;
}
.option:is(:hover, .active) :where(span, label) {
color: #4A98F7;
}
.option #fill-color {
cursor: pointer;
height: 14px;
width: 14px;
}
#fill-color:checked ~ label {
color: #4A98F7;
}
.option #size-slider {
width: 100%;
height: 5px;
margin-top: 10px;
}
.colors .options {
display: flex;
justify-content: space-between;
}
.colors .option {
height: 20px;
width: 20px;
border-radius: 50%;
margin-top: 3px;
position: relative;
}
.colors .option:nth-child(1) {
background-color: #fff;
border: 1px solid #bfbfbf;
}
.colors .option:nth-child(2) {
background-color: #000;
}
.colors .option:nth-child(3) {
background-color: #E02020;
}
.colors .option:nth-child(4) {
background-color: #6DD400;
}
.colors .option:nth-child(5) {
background-color: #4A98F7;
}
.colors .option.selected::before {
position: absolute;
content: "";
top: 50%;
left: 50%;
height: 12px;
width: 12px;
background: inherit;
border-radius: inherit;
border: 2px solid #fff;
transform: translate(-50%, -50%);
}
.colors .option:first-child.selected::before {
border-color: #ccc;
}
.option #color-picker {
opacity: 0;
cursor: pointer;
}
.buttons button {
width: 100%;
color: #fff;
border: none;
outline: none;
padding: 11px 0;
font-size: 0.9rem;
margin-bottom: 13px;
background: none;
border-radius: 4px;
cursor: pointer;
}
.buttons .clear-canvas {
color: #6C757D;
border: 1px solid #6C757D;
transition: all 0.3s ease;
}
.clear-canvas:hover {
color: #fff;
background: #6C757D;
}
.buttons .save-img {
background: #4A98F7;
border: 1px solid #4A98F7;
}
.drawing-board {
flex: 1;
overflow: hidden;
}
.drawing-board canvas {
width: 100%;
height: 100%;
}
Ce CSS met en forme des éléments tels que les boutons d'outils, les couleurs et les tailles, créant une interface moderne et conviviale.
Écriture de la logique en JavaScript
Passons maintenant à la partie la plus intéressante : la fonctionnalité de dessin. Nous allons utiliser JavaScript pour gérer les événements liés au dessin sur la toile. Le code JavaScript est connecté via le fichier script.js, que nous examinerons ci-dessous :
Le code JavaScript contrôle la fonctionnalité de dessin sur la toile, interagit avec l'utilisateur et met à jour l'affichage en fonction des paramètres sélectionnés. Examinons les détails de chaque fragment de code.
Initialisation des variables :
const canvas = document.querySelector("canvas"),
toolBtns = document.querySelectorAll(".tool"),
fillColor = document.querySelector("#fill-color"),
sizeSlider = document.querySelector("#size-slider"),
colorBtns = document.querySelectorAll(".colors .option"),
colorPicker = document.querySelector("#color-picker"),
clearCanvas = document.querySelector(".clear-canvas"),
saveImg = document.querySelector(".save-img"),
ctx = canvas.getContext("2d");
let prevMouseX, prevMouseY, snapshot,
isDrawing = false,
selectedTool = "brush",
brushWidth = 5,
selectedColor = "#000";canvas: fait référence à l'élément<canvas>sur la page où le dessin aura lieu.toolBtns: Liste de tous les boutons d'outils (brosse, gomme et formes) avec lesquels l'utilisateur peut interagir.fillColor: Variable pour suivre l'état de la case à cocher "Couleur de remplissage".sizeSlider: Lien vers le curseur pour sélectionner la taille du pinceau.colorBtns: Variable pour tous les boutons de sélection de couleur sur lesquels l'utilisateur peut cliquer pour sélectionner une couleur.colorPicker: Lien vers le sélecteur de couleur HTML standard.clearCanvasetsaveImg: Boutons pour effacer la toile et enregistrer l'image.ctx: Contexte de dessin de la toile, avec lequel les lignes, les formes et d'autres opérations sont effectuées.
Définition de l'arrière-plan de la toile :
const setCanvasBackground = () => {
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = selectedColor;
}Ce code définit un fond blanc pour la toile, puis restaure la couleur actuelle du pinceau pour dessiner.
Initialisation de la toile après le chargement de la page :
window.addEventListener("load", () => {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
setCanvasBackground();
});Lors du chargement de la page, la taille de la toile est définie en fonction de sa taille actuelle à l'écran (via offsetWidth et offsetHeight). Ensuite, la fonction est appelée pour définir l'arrière-plan.
Gestionnaires d'événements :
Gestionnaires de sélection d'outil (pinceau, gomme et formes) :
toolBtns.forEach(btn => {
btn.addEventListener("click", () => {
document.querySelector(".options .active").classList.remove("active");
btn.classList.add("active");
selectedTool = btn.id;
});
});Chaque bouton de l'outil (toolBtns) ajoute un gestionnaire d'événements de clic qui active le bouton en ajoutant la classe active, et modifie l'outil sélectionné en mettant à jour la variable selectedTool.
Modification de la taille du pinceau :
sizeSlider.addEventListener("change", () => brushWidth = sizeSlider.value);Lorsque l'utilisateur change la valeur du curseur, la taille du pinceau est mise à jour.
Changement de couleur :
colorBtns.forEach(btn => {
btn.addEventListener("click", () => {
document.querySelector(".options .selected").classList.remove("selected");
btn.classList.add("selected");
selectedColor = window.getComputedStyle(btn).getPropertyValue("background-color");
});
});Chaque bouton de sélection de couleur met à jour la couleur actuelle du pinceau (selectedColor) et active le bouton sélectionné en ajoutant la classe selected.
Utilisation du sélecteur de couleurs :
colorPicker.addEventListener("change", () => {
colorPicker.parentElement.style.background = colorPicker.value;
colorPicker.parentElement.click();
});Lorsque l'utilisateur sélectionne une couleur via le sélecteur HTML standard, la couleur est mise à jour sur le bouton.
Nettoyage de la toile :
clearCanvas.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
setCanvasBackground();
});
Lorsque vous cliquez sur le bouton « Effacer », toute la toile est effacée et l'arrière-plan est restauré.
Enregistrement de l'image :
saveImg.addEventListener("click", () => {
const link = document.createElement("a");
link.download = `${Date.now()}.jpg`;
link.href = canvas.toDataURL();
link.click();
});Lorsque vous cliquez sur le bouton « Enregistrer comme photo », un lien temporaire est créé pour télécharger l'image, convertissant le contenu de la toile au format data URL.
Dessin sur toile :
const startDraw = (e) => {
isDrawing = true;
prevMouseX = e.offsetX;
prevMouseY = e.offsetY;
ctx.beginPath();
ctx.lineWidth = brushWidth;
ctx.strokeStyle = selectedColor;
ctx.fillStyle = selectedColor;
snapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
const drawing = (e) => {
if (!isDrawing) return;
ctx.putImageData(snapshot, 0, 0);
if (selectedTool === "brush" || selectedTool === "eraser") {
ctx.strokeStyle = selectedTool === "eraser" ? "#fff" : selectedColor;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
} else if (selectedTool === "rectangle") {
drawRect(e);
} else if (selectedTool === "circle") {
drawCircle(e);
} else {
drawTriangle(e);
}
}
canvas.addEventListener("mousedown", startDraw);
canvas.addEventListener("mousemove", drawing);
canvas.addEventListener("mouseup", () => isDrawing = false);startDraw: Lorsque l'utilisateur clique sur la toile, le dessin commence. Les coordonnées initiales sont enregistrées et un instantané de l'état actuel de la toile est créé (pour annuler).drawing: Lorsque l'utilisateur déplace la souris, le dessin est effectué en fonction de l'outil sélectionné.
En général, HTML crée l'interface et la structure, et JavaScript gère toutes les fonctionnalités de dessin, de changement d'outil et de sauvegarde du dessin.
Excellent. Voici à quoi ressemble l'ensemble du code JavaScript :
const canvas = document.querySelector("canvas"),
toolBtns = document.querySelectorAll(".tool"),
fillColor = document.querySelector("#fill-color"),
sizeSlider = document.querySelector("#size-slider"),
colorBtns = document.querySelectorAll(".colors .option"),
colorPicker = document.querySelector("#color-picker"),
clearCanvas = document.querySelector(".clear-canvas"),
saveImg = document.querySelector(".save-img"),
ctx = canvas.getContext("2d");
let prevMouseX, prevMouseY, snapshot,
isDrawing = false,
selectedTool = "brush",
brushWidth = 5,
selectedColor = "#000";
const setCanvasBackground = () => {
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = selectedColor;
}
window.addEventListener("load", () => {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
setCanvasBackground();
});
// Fonctions pour dessiner des formes
const drawRect = (e) => {
if (!fillColor.checked) {
return ctx.strokeRect(e.offsetX, e.offsetY, prevMouseX - e.offsetX, prevMouseY - e.offsetY);
}
ctx.fillRect(e.offsetX, e.offsetY, prevMouseX - e.offsetX, prevMouseY - e.offsetY);
}
const drawCircle = (e) => {
ctx.beginPath();
let radius = Math.sqrt(Math.pow((prevMouseX - e.offsetX), 2) + Math.pow((prevMouseY - e.offsetY), 2));
ctx.arc(prevMouseX, prevMouseY, radius, 0, 2 * Math.PI);
fillColor.checked ? ctx.fill() : ctx.stroke();
}
const drawTriangle = (e) => {
ctx.beginPath();
ctx.moveTo(prevMouseX, prevMouseY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.lineTo(prevMouseX * 2 - e.offsetX, e.offsetY);
ctx.closePath();
fillColor.checked ? ctx.fill() : ctx.stroke();
}
// Manipulateurs pour outils
toolBtns.forEach(btn => {
btn.addEventListener("click", () => {
document.querySelector(".options .active").classList.remove("active");
btn.classList.add("active");
selectedTool = btn.id;
});
});
// Soins des pinceaux
sizeSlider.addEventListener("change", () => brushWidth = sizeSlider.value);
colorBtns.forEach(btn => {
btn.addEventListener("click", () => {
document.querySelector(".options .selected").classList.remove("selected");
btn.classList.add("selected");
selectedColor = window.getComputedStyle(btn).getPropertyValue("background-color");
});
});
colorPicker.addEventListener("change", () => {
colorPicker.parentElement.style.background = colorPicker.value;
colorPicker.parentElement.click();
});
// Nettoyage de la toile
clearCanvas.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
setCanvasBackground();
});
// Enregistrement de l'image
saveImg.addEventListener("click", () => {
const link = document.createElement("a");
link.download = `${Date.now()}.jpg`;
link.href = canvas.toDataURL();
link.click();
});
// Dessin
const startDraw = (e) => {
isDrawing = true;
prevMouseX = e.offsetX;
prevMouseY = e.offsetY;
ctx.beginPath();
ctx.lineWidth = brushWidth;
ctx.strokeStyle = selectedColor;
ctx.fillStyle = selectedColor;
snapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
const drawing = (e) => {
if (!isDrawing) return;
ctx.putImageData(snapshot, 0, 0);
if (selectedTool === "brush" || selectedTool === "eraser") {
ctx.strokeStyle = selectedTool === "eraser" ? "#fff" : selectedColor;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
} else if (selectedTool === "rectangle") {
drawRect(e);
} else if (selectedTool === "circle") {
drawCircle(e);
} else {
drawTriangle(e);
}
}
canvas.addEventListener("mousedown", startDraw);
canvas.addEventListener("mousemove", drawing);
canvas.addEventListener("mouseup", () => isDrawing = false);
Ce code implémente :
Dessin de différentes figures (rectangle, cercle, triangle).
Sélection des outils, y compris le pinceau, la gomme et les options de remplissage.
Changement de couleur et de taille du pinceau.
Nettoyage de la toile et enregistrement de l'image.
Conclusions et avis
Nous avons créé une application de dessin simple en HTML, CSS et JavaScript qui vous permet de dessiner différentes formes, de changer la couleur et la taille du pinceau et d'enregistrer l'image. Cette application peut être étendue en ajoutant des outils supplémentaires, en améliorant l'interface et en s'intégrant au serveur pour enregistrer et partager des dessins.
