Maison > Article > interface Web > Tutoriel sur l'utilisation de HTML5 pour obtenir les compétences du didacticiel effect_html5 sur l'effet de maculage de la gomme
Cet effet vient d'être utilisé dans un projet récent, qui s'apparente un peu à une carte à gratter Sur un appareil mobile, une image est grattée pour en afficher une autre. Le rendu est le suivant :
DEMO veuillez cliquer à droite : DEMO
C'est assez courant sur Internet. Au départ, je voulais simplement trouver une démo en ligne et appliquer sa méthode. Après l'avoir appliquée, j'ai découvert cela. sous Android En raison des exigences des clients, il n'est pas nécessaire qu'il soit particulièrement fluide sur Android, au moins il doit être jouable, mais la démo que j'ai trouvée en ligne est trop lente et ne peut pas être lue du tout. Je voulais juste en écrire un moi-même, et cet article sert uniquement à enregistrer le processus de recherche.
La première chose qui vient à l'esprit pour cet effet de scraping est d'utiliser le canevas HTML5. Dans l'API canvas, la méthode clearRect qui peut effacer les pixels est la méthode clearRect, mais la méthode clearRect efface le rectangle de la zone. la plupart des gens y sont habitués. Les gommes sont polyvalentes, c'est pourquoi la fonction puissante de la zone de découpage est introduite, qui est la méthode de découpage. L'utilisation est très simple :
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.
Maintenant que l'effet d'effacement est là, il est maintenant temps d'écrire l'effet d'effacement du mouvement de la souris. Je vais utiliser la souris pour le décrire ci-dessous, car la version mobile est similaire, c'est-à-dire remplacer mousedown par touchstart, mousemove. avec touchmove et mouseup avec touchend , et l'acquisition du point de coordonnées passe de e.clientX à e.targetTouches[0].pageX.
Pour implémenter l'effacement des mouvements de la souris, j'ai d'abord pensé à effacer la zone circulaire où se trouve la souris dans l'événement mousemove déclenché lorsque la souris bouge. Après l'avoir écrit, j'ai constaté que lorsque la souris se déplace très rapidement, l'effacement est effacé. La zone n'est plus cohérente, et l'effet suivant apparaîtra. Ce n'est évidemment pas l'effet de gomme souhaité.
Comme tous les points sont incohérents, la prochaine chose à faire est de connecter ces points. Si vous implémentez la fonction de dessin, vous pouvez directement connecter les deux points via lineTo puis dessiner, mais l'effet d'effacement est la zone de découpage. nécessite un chemin fermé. Si vous connectez simplement deux points, la zone de découpage ne peut pas être formée. Ensuite, j'ai pensé à utiliser des méthodes de calcul pour calculer les quatre coordonnées finales des rectangles dans les deux zones d'effacement, qui est le rectangle rouge dans l'image ci-dessous :
La méthode de calcul est également très simple, car on peut connaître les coordonnées des deux extrémités de la ligne reliant les deux zones de détourage, et aussi savoir quelle largeur la ligne que l'on veut, les coordonnées des quatre extrémités du rectangle deviennent facile à trouver, il y a donc le code ci-dessous :
Code XML/HTMLCopier le contenu dans le presse-papiers
x1, y1 et x2, y2 sont les deux points finaux, ainsi les coordonnées des quatre points finaux sont obtenues. De cette façon, la zone de découpage est un cercle plus un rectangle, et le code est organisé comme suit :
Code XML/HTMLCopier le contenu dans le presse-papier
Obtenez imgData, parcourez les pixels dans imgData, puis analysez l'alpha en rgba dans le tableau de données de imgData, c'est-à-dire analysez la transparence si le pixel est effacé, la transparence sera de 0, c'est-à-dire que c'est pour. comparez le nombre de pixels avec une transparence non nulle dans le canevas actuel au nombre total de pixels sur le canevas. Si la proportion de pixels avec une transparence non nulle est inférieure à 40 %, cela signifie qu'il y en aura plus de 60 %. de la zone sur la toile actuelle. Une fois effacée, l’image peut être automatiquement présentée.
Notez ici que j'ai mis le code pour vérifier les pixels dans l'événement mouseup, car la quantité de calcul est relativement importante. Si l'utilisateur clique sauvagement sur la souris, l'événement mouseup sera déclenché de manière extravagante, ce qui signifie qu'il sera fou. En déclenchant cette boucle pour calculer les pixels, la quantité de calcul est si importante qu'elle bloque le processus et bloque l'interface. La solution est la suivante : ajoutez un délai d'attente pour retarder l'exécution du calcul des pixels et effacez le délai d'attente à chaque fois. fois que l'utilisateur clique, c'est-à-dire si l'utilisateur clique pendant une longue période. Rapidement, ce calcul ne sera plus déclenché. Une autre façon d'améliorer est de faire des inspections aléatoires. La façon dont je l'ai écrit ci-dessus est de vérifier pixel par pixel. le nombre de pixels est trop grand, il restera certainement bloqué, vous pouvez donc utiliser une inspection aléatoire, telle que Vérifier tous les 30 pixels. Le code modifié est le suivant :
Copier le code
Cela peut empêcher au maximum les utilisateurs de cliquer de manière extravagante. S'il existe d'autres méthodes de vérification plus efficaces, veuillez donner votre avis, merci.
A cette étape, tout était écrit, puis il était temps de tester. Les résultats n'étaient toujours pas optimistes sur Android, j'ai donc dû penser à une autre façon. Finalement, j'ai découvert l'attribut globalCompositeOperation dans le fichier. environnement de dessin. La valeur par défaut de cette propriété est source-over, c'est-à-dire qu'elle sera superposée lorsque vous dessinez sur des pixels existants, mais il existe également une propriété appelée destination-out. L'explication officielle est : afficher l'image de destination en dehors de l'environnement de dessin. image source. Seule la partie de l'image cible en dehors de l'image source sera affichée et l'image source est transparente. Cela semble difficile à comprendre, mais en fait, si vous le testez vous-même, vous constaterez que c'est très simple, c'est-à-dire que lorsque vous dessinez sur la base de pixels existants, les pixels existants dans la zone que vous dessinez deviendront transparents. peut le changer directement en regardant la photo Facile à comprendre :
Illustration de l'effet de l'attribut globalCompositeOperation.
Avec cet attribut, cela signifie qu'il n'est pas nécessaire d'utiliser le clip, et qu'il n'est pas nécessaire d'utiliser sin ou cos pour calculer la zone de découpage, utilisez simplement une ligne épaisse, ce qui peut réduire considérablement le coût. le calcul est réduit et les appels à l'API de l'environnement de dessin sont réduits. Les performances sont améliorées et l'exécution sur Android devrait être beaucoup plus fluide. Voici le code modifié :
擦除那部分代码就这么一点,也就相当于画图功能,直接设置line属性后通过lineTo进行绘制线Il s'agit d'une opération globaleCompositeOperation avec destination-out, et d'un service globalCompositeOperation.了擦除效果。鼠标滑动触发的事件里面代码也少了很多,绘图对象的调用次数减少了,计算也减少了,性能提升大大滴。
改好代码后就立即用自己的android机子测试了一下,果然如此,跟上一个相比,流畅了很多,至少达到了客户要求的能玩的地步了。
源码地址:https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Funny-demo/clip/clip.html