Cet article présente principalement :
Nom : planche à dessin intelligente.
Pile technologique : HTML5, CSS3, JavaScript, mobile
Description de la fonction :
Adresse d'aperçu de l'adresse du projet
Aperçu
Aperçu PC :
Aperçu mobile :
Après avoir lu l'aperçu ci-dessus et expérimenté le Smart Drawing Pad , je pense que ce n'est pas grave. N'oubliez pas de donner un coup de pouce. Que vous soyez très excité ou non, je suis très excité de toute façon. obtenu les résultats du projet. Je l'ai dit. Un tas de bêtises, vous pouvez maintenant commencer à taper du code pour obtenir l'effet souhaité ! ! !
Remarque : Les effets du projet suivants sont principalement liés à JavaScript. Ce qui suit n'est que le code qui fournit des idées d'implémentation , pas l'intégralité du Code .
3. Atteindre les résultats du projet étape par étape(1) Page d'analyse
Grâce au diagramme de cas d'utilisation , savons-nous quelles fonctions les utilisateurs peuvent utiliser pour accéder à notre site Web ?
Ce que les utilisateurs peuvent faire :
(2) mise en page HTML
Quand j'ai écrit du HTML, j'ai introduit les fichiers CSS et JS
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, initial-scale=1.0> <meta http-equiv=X-UA -Compatible content=ie=edge> <title>Smart Drawing Pad</title> <link rel=shortcut icon href=./image/favicon.png type=image/x-icon> <link rel=stylesheet href=./css/style.css></head><body> <canvas id=canvas></canvas> <div class=bg-btn></ div> <div class=color-group id=bgGroup> <h3>Sélectionnez la couleur d'arrière-plan :</h3> <ul class=clearfix> <li class=bgcolor-item style=background-color : bleu;></li> <li class=bgcolor-item style=background-color: noir;></li> <li class=bgcolor-item style=background-color: #FF3333;></li> <li class=bgcolor-item style=background-color : #0066FF;></li> <li class=bgcolor-item style=background-color : #FFFF33;></li> <li class=bgcolor-item style=background-color: #33CC66;></li> <li class=bgcolor-item style=background-color: gris;></li> <li class=bgcolor-item style=background- couleur : #F34334;></li> <li class=bgcolor-item style=background-color : #fff;box-shadow : 0 1px 2px 0 rgba(32,33,36,0.28);></li> <li class=bgcolor-item style=background-color : #9B27AC;></li> <li class=bgcolor-item style=background-color : #4CB050;></li> <li class=bgcolor-item style=background-color: #029688;></li> </ul> <i class=closeBtn></i> </div> <div class=tools> <div class=container> <button class=save id=save <button class=brush active id=brush <button class=eraser id=eraser < bouton class=clear id=clear <button class=undo id=undo <button class=redo id=redo </div> </div> <div class=pen-detail id=penDetail> <i class=closeBtn></i> <p>Taille du stylo</p> <span class=circle-box><i id=thickness></i></span> <input type=range id=range1 min=1 max=10 value=1> <p>Couleur du stylo</p> <ul class=pen-color clearfix> <li class=color-item active style=background-color: black;></ li> <li class=color-item style=background-color : #FF3333;></li> <li class=color-item style=background-color : #99CC00;></li> <li class=color-item style=background -color : #0066FF;></li> <li class=color-item style=background-color : #FFFF33;></li> <li class=color-item style=background-color : #33CC66;></li> </ul> <p>Opacité</p> <i class=showOpacity></i> <input type=range id=range2 min=1 max=10 value=1> </ div> <script src=./js/main.js></script></body></html>
(3) Utilisez CSS pour embellir l'interface
Le code CSS peut embellir l'interface selon les habitudes personnelles, je n'écrirai donc pas le code CSS ici. Vous pouvez directement consulter le code du projet ou revoir les éléments des outils de développement. Si vous avez des questions, vous pouvez discuter avec moi en privé, je ne pense pas que ce soit un gros problème.
(4) Utiliser JS pour implémenter des fonctions spécifiques du projet
1. Préparation
Tout d'abord, préparez un conteneur, qui est une planche à dessin. Le conteneur a été écrit dans le HTML précédent. C'est un pur non-sens.
<identifiant du canevas=canvas></canvas>
Puis initialisez js
let canvas = document.getElementById('canvas');let context = canvas.getContext('2d'); Je prévois de rendre le plan de travail en plein écran, je vais donc ensuite définir la largeur et la hauteur de canvas
laissez pageWidth = document.documentElement.clientWidth;let pageHeight = document.documentElement.clientHeight;canvas.width = pageWidth;canvas.height = pageHeight;
Étant donné que certains IE ne prennent pas en charge canvas , si nous voulons être compatibles avec IE, nous pouvons créer un canvas , puis l'initialiser avec excanvas et ajouter exCanvas.js pour IE. Nous ne considérons explicitement pas IE ici.
Mais lorsque je change la fenêtre du navigateur sur mon ordinateur, la planche à dessin ne s'adapte pas de manière adaptative. Solution:
// N'oubliez pas d'exécuter la fonction autoSetSize function autoSetSize(){ canvasSetSize(); // Lors de l'exécution de cette fonction, la largeur et la hauteur du canevas seront définies en premier function canvasSetSize(){ let pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; toile.width = pageWidth; toile.hauteur = pageHeight; Une fois la taille de la fenêtre modifiée, l'événement resize sera déclenché pour réinitialiser la largeur et la hauteur de la fenêtre du canevas.onresize = function(){ canvasSetSize( }}2. Réaliser la fonction de dessin
Idée d'implémentation : écoutez les événements de la souris et utilisez drawLine() pour dessiner les données enregistrées.
painting = false .mousedown ), définissez painting sur true , indiquant que la peinture est en cours et que la souris n'est pas relâchée. Enregistrez les clics de souris.mousemove ). Si la souris se déplace trop vite, le navigateur ne peut pas suivre la vitesse de dessin et des espaces apparaîtront entre les points, nous devons donc relier les points dessinés avec des lignes ( lineTo() ).mouseup ), définissez painting sur false . Remarque : La méthode drawCircle n'a en fait pas besoin d'être écrite. C'est juste pour que tout le monde comprenne par où commencer à cliquer ?
function ListenToUser() { // Définir une variable pour initialiser l'état du pinceau let painting = false; // Enregistrer la dernière position du pinceau let lastPoint = {x: undefined, y: undefined}; // Événement de pression de la souris canvas.onmousedown = function (e){ painting = true; let x = e.clientX; let y = e.lastPoint = {'x':x,'y':y}; drawCircle(x,y,5); } //Événement de déplacement de souris canvas.onmousemove = function(e){ if(painting){ let x = e.clientX; let y = e.clientY; :x,'y':y}; drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y); Événement de libération de la souris canvas.onmouseup = function(){ painting = false; }}// Fonction de dessin de point function drawCircle(x,y,radius){ // Crée un nouveau chemin Après la génération, la commande de dessin graphique pointe vers le. chemin Générer un chemin. context.beginPath(); // Dessine un arc (cercle) avec (x, y) comme centre et radius comme rayon, // commençant à startAngle et se terminant à endAngle, dans la direction donnée par antihoraire (la valeur par défaut est dans le sens des aiguilles d'une montre) ) à générer. context.arc(x,y,radius,0,Math.PI*2); // Génère un graphique solide en remplissant la zone de contenu du chemin context.fill( // Après avoir fermé le chemin, le graphique La commande de dessin est redirigée vers le milieu du contexte. context.closePath();}function drawLine(x1,y1,x2,y2){ //Définit la largeur de la ligne context.lineWidth = 10; //Définit le style de fin de ligne. context.lineCap = round; // Définit le style de la jointure entre les lignes context.lineJoin = round; // moveTo(x,y) déplace le trait vers les coordonnées spécifiées x et y context.moveTo(x1,y1 ); / lineTo(x, y) trace une ligne droite depuis la position actuelle jusqu'aux positions x et y spécifiées context.lineTo(x2,y2); // Dessine le contour graphique à travers les lignes context.stroke(); contexte.closePath();}3. Implémentez la fonction gomme
Idées de mise en œuvre :
eraserEnabled = false .click sur la gomme, cliquez sur la gomme, changez l'état de la gomme, eraserEnabled = true et changez de classe pour obtenir l'effet activé .eraserEnabled vaut true , déplacez la souris et utilisez context.clearRect() pour implémenter la gomme. Mais j'ai découvert que dans l'API canvas, la méthode clearRect peut effacer les pixels, mais la méthode clearRect efface la zone rectangulaire. Après tout, les gommes de la plupart des gens sont habituées à être rondes, donc la fonction puissante de la zone de découpage est introduite. est la méthode du clip. Le code suivant utilise context.clearRect() pour implémenter la gomme. Veuillez consulter la section étape par étape pour savoir comment mieux mettre en œuvre les sassafras en caoutchouc.
let Eraser = document.getElementById(eraser);let EraserEnabled = false;// N'oubliez pas d'exécuter la fonction ListenToUser function ListenToUser() { // ... signifie que le code précédemment écrit est omis // ... // Appuyez sur la souris Événement suivant canvas.onmousedown = function(e){ // ... if(eraserEnabled){//Pour utiliser la gomme context.clearRect(x-5,y-5,10,10) }else{ lastPoint = {'x':x,'y':y} } } // Événement de déplacement de la souris canvas.onmousemove = function(e){ let x = e.clientX; let y = e.clientY; !painting){return} if(eraserEnabled){ context.clearRect(x-5,y-5,10,10 }else{ var newPoint =); {'x':x,'y':y}; drawLine(lastPoint.x, lastPoint.y,newPoint.x, newPoint.y); } } // ...}// Cliquez sur la gomme. Eraser.onclick = function(){ EraserEnabled = true; Eraser.classList.add('active');4. Implémenter la fonction d'effacement d'écran
Idées de mise en œuvre :
Obtenez le nœud de l'élément.
Cliquez sur le bouton Effacer pour effacer le canevas.
let reSetCanvas = document.getElementById(clear);//Réaliser l'effacement de l'écran reSetCanvas.onclick = function(){ ctx.clearRect(0,0,canvas.width,canvas.height); setCanvasBg('white');}// Réinitialiser la fonction de couleur d'arrière-plan du canevas setCanvasBg(color) { ctx.fillStyle = color; 0, toile.largeur, toile.hauteur);}5. Implémenter la fonction d'enregistrement sous forme d'image
Idées de mise en œuvre :
let save = document.getElementById(save); // Télécharger l'image save.onclick = function(){ let imgUrl = canvas.toDataURL('image/png'); let saveA = document.createElement('a'); body.appendChild(saveA); saveA.href = imgUrl; saveA.download = 'mypic'+(new Date).getTime(); saveA.target = '_blank'; saveA.click();}6. Implémenter la fonction de changement de couleur d'arrière-plan
Idées de mise en œuvre :
let selectBg = document.querySelector('.bg-btn');let bgGroup = document.querySelector('.color-group');let bgcolorBtn = document.querySelectorAll('.bgcolor-item');let penDetail = document. getElementById(penDetail);let activeBgColor = '#fff';//implémentation de la couleur d'arrière-plan de changement pour (let i = 0; i < bgcolorBtn.length; i++) { bgcolorBtn[i].onclick = function (e) { // Arrêtez de bouillonner e.stopPropagation(); for (let i = 0; i < bgcolorBtn.length ; i++) { bgcolorBtn[i].classList.remove(active); this.classList.add(activeBgColor =); this.style.backgroundColor; setCanvasBg(activeBgColor); } }}document.onclick = function(){ bgGroup.classList.remove('active');}selectBg.onclick = function(e){ bgGroup.classList.add(' actif'); e.stopPropagation();}7. Mettre en œuvre la fonction de modification de l'épaisseur de la brosse
Idées de mise en œuvre :
let range1 = document.getElementById('range1');let lWidth = 2;let ifPop = false;range1.onchange = function(){ console.log(range1.value); style.transform = 'scale('+ (parseInt(range1.value)) +')'; console.log(thickness.style.transform ) lWidth = parseInt(range1.value*2);}// Fonction de dessin de ligne function drawLine(x1,y1,x2,y2){ // ... context.lineWidth = lWidth; // ...}// Cliquez sur le pinceau pinceau .onclick = function(){ EraserEnabled = false; brush.classList.add('active'); Boîte contextuelle console.log('pop') penDetail.classList.add('active'); }else{ penDetail.classList.remove('active' } ifPop = !ifPop;}8. Implémenter la fonction de changement de couleur du pinceau
L'idée de mise en œuvre est similaire à celle de changer la couleur d'arrière-plan de la planche à dessin .
let aColorBtn = document.getElementsByClassName(color-item);getColor();function getColor(){ for (let i = 0; i < aColorBtn.length; i++) { aColorBtn[i].onclick = function () { for ( soit je = 0; je < aColorBtn.length; i++) { aColorBtn[i].classList.remove(active); this.classList.add(active); activeColor = this.style.backgroundColor; ctx.fillStyle = activeColor;9. Implémenter les fonctions d'annulation et de rétablissement des modifications
Idées de mise en œuvre :
canvasHistory chaque fois qu'une opération de dessin est terminée (utilisez toDataURL() du canevas pour générer un instantané, qui génère une image base64) ;canvasHistory à l'aide drawImage() de canvas ; let undo = document.getElementById(undo);let redo = document.getElementById(redo);// ...canvas.onmouseup = function(){ painting = false; canvasDraw();}let canvasHistory = [];let step = -1; // Fonction de méthode de dessin canvasDraw(){ step++; if(step < canvasHistory.length){ canvasHistory.length = step; Ajouter un nouveau dessin à l'historique canvasHistory.push(canvas.toDataURL());}//Méthode d'annulation function canvasUndo(){ if(step > 0){ step--; // ctx.clearRect(0,0,canvas .width,canvas.height); let canvasPic = new Image(); canvasPic.src = canvasHistory[step]; ctx.drawImage(canvasPic, 0, 0); } undo.classList.add('active'); }else{ undo.classList.remove('active'); alert('Impossible de continuer l'annulation'); / Méthode de rétablissement function canvasRedo(){ if(step < canvasHistory.length - 1){ step++; let canvasPic = new Image(); canvasHistory[étape]; canvasPic.onload = function () { // ctx.clearRect(0,0,canvas.width,canvas.height); ctx.drawImage(canvasPic, 0, 0); 'active'); }else { redo.classList.remove('active') alert('Déjà le dernier enregistrement'); }}undo.onclick = function(){ canvasUndo();}redo.onclick = function(){ canvasRedo();}10. Compatible avec les terminaux mobiles
Idées de mise en œuvre :
true , l'événement touch est utilisé ; false , mouse est utilisé // ...if (document.body.ontouchstart !== undefined) { // Utiliser l'événement tactile anvas.ontouchstart = function (e) { // Commencer à toucher} canvas.ontouchmove = function (e) { // Commencer à glisser } canvas.ontouchend = function () { // Fin du glissement }}else{ // Utiliser l'événement souris // ... } // ... 4. Piétiner les pièges Problème 1 : Lorsque vous modifiez la fenêtre du navigateur sur votre ordinateur, la planche à dessin ne s'adapte pas.Solution:
Dans le traitement des événements de réponse au redimensionnement, les paramètres de taille de page obtenus sont les paramètres modifiés.
Lorsque la taille de la fenêtre change, réinitialisez la largeur et la hauteur du canevas. Pour faire simple, une fois la fenêtre modifiée, réaffectez canvas.width et canvas.height.
// N'oubliez pas d'exécuter la fonction autoSetSize function autoSetSize(){ canvasSetSize(); // Lors de l'exécution de cette fonction, la largeur et la hauteur du canevas seront définies en premier function canvasSetSize(){ let pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; toile.width = pageWidth; toile.hauteur = pageHeight; Une fois la taille de la fenêtre modifiée, l'événement resize sera déclenché pour réinitialiser la largeur et la hauteur de la fenêtre du canevas.onresize = function(){ canvasSetSize( }} Question 2 : Lorsque la largeur de la ligne tracée est relativement petite, c'est bien, mais une fois qu'elle est plus épaisse, des problèmes surviendront.Solution : Jetez un œil à la documentation et découvrez la méthode. Il vous suffit simplement de modifier le code pour tracer des lignes .
// Fonction de dessin de ligne function drawLine(x1,y1,x2,y2){ context.beginPath(); context.lineWidth = lWidth; //-----Add----- // Définit le style de fin de ligne. context.lineCap = round; // Définit le style de la jonction entre les lignes context.lineJoin = round //-----Join----- context.moveTo(x1,y1); y2); contexte.AVC(); contexte.closePath();} Question 3 : Comment réaliser un sassafras rond en caoutchouc ?Solution:
Dans l'API canevas, la méthode clearRect peut effacer les pixels, mais la méthode clearRect efface une zone rectangulaire. Après tout, les gommes de la plupart des gens sont habituées à être rondes, c'est pourquoi la fonction puissante de la zone de découpage est introduite, c'est-à-dire la méthode clip. L'utilisation est très simple :
ctx.save()ctx.beginPath()ctx.arc(x2,y2,a,0,2*Math.PI);ctx.clip()ctx.clearRect(0,0,canvas.width,canvas.height) ;ctx.restore();
Le code ci-dessus réalise l'effacement d'une zone circulaire, c'est-à-dire qu'il implémente d'abord un chemin circulaire, puis utilise ce chemin comme zone de découpage, puis efface les pixels. Une chose à noter est que vous devez d'abord enregistrer l'environnement de dessin et réinitialiser l'environnement de dessin après avoir effacé les pixels. Si vous ne réinitialisez pas, les futurs dessins seront limités à cette zone de découpage.
Question 4 : Comment être compatible avec les terminaux mobiles ?1.Ajouter une balise méta
Étant donné que le navigateur mettra initialement à l'échelle la page lorsqu'elle sera affichée sur le téléphone mobile, nous pouvons définir l'attribut méta viewport dans la balise méta pour indiquer au navigateur de ne pas redimensionner la page. Largeur de la page = largeur de l'écran de l'appareil utilisateur.
<méta nom=viewport content=width=device-width,initial-scale=1,user-scalable=no,maximum-scale=1.0,minimum-scale=1.0/>/*Page width=Mobile width:width=device-width L'utilisateur ne peut pas mettre à l'échelle : user-scalable=pas de mise à l'échelle : échelle initiale=1 mise à l'échelle maximale : échelle maximale=1,0 mise à l'échelle minimale : échelle minimale=1,0*/
2. Presque tous les événements tactiles sont utilisés du côté mobile, ce qui est différent du côté PC.
Étant donné que le côté mobile utilise les événements tactiles, les attributs H5 touchstart/touchmove/touchend sont utilisés. Cependant, le côté PC ne prend en charge que les événements de souris, la détection des fonctionnalités est donc requise.
Dans l'événement touch , les coordonnées sont obtenues via .touches[0].clientX et .touches[0].clientY , qui doivent être distinguées de l'événement mouse .
Eh bien, ce n'est pas un gros problème. C'est juste que j'ai raté l'écriture de context.beginPath(); et j'ai passé du temps à résoudre le bug là-dessus. Cela me rappelle qu'il y a des dizaines de millions de lignes de code, et la première ligne de. les commentaires ne sont pas standardisés, la programmation n'est pas standardisée, et mon collègue a deux lignes, il vaut mieux fonctionner selon les spécifications de fonctionnement documentées, ça sent tellement bon ! ! !
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.