Cet article partage le principe de mise en œuvre, le code d'implémentation et les problèmes rencontrés dans le processus de mise en œuvre de l'animation pour effacer l'animation pour votre référence. Le contenu spécifique est le suivant
Le principe consiste à effacer une certaine image sur un appareil mobile et à afficher une autre image, en utilisant Canvas pour l'implémenter.
Si l'utilisateur efface manuellement, vous devez écouter TouchMove, Touchend et d'autres événements, calculer les coordonnées correspondantes et utiliser ClearRect ou Rect de Canvas pour dessiner des arcs ou des lignes pour y parvenir. Cependant, cela entraînera un retard sur les téléphones Androd.
Canvas a une propriété GlobalComposite Operation. La valeur par défaut de cette propriété est la source, c'est-à-dire qu'elle sera superposée lorsque vous dessinez sur les pixels existants. Cependant, il y a un autre attribut qui est à destination, c'est-à-dire lors de l'affichage de votre image cible en dehors de l'image source, c'est-à-dire lorsque le dessin basé sur les pixels existants, les pixels existants dans la zone que vous dessinez seront définis transparents. Avec cet attribut, cela signifie que vous n'avez pas besoin d'utiliser une série de fonctions telles que Clip. Vous pouvez simplement utiliser des lignes ou des arcs épaisses. Cela réduira les appels à l'API de l'environnement de dessin, améliorera les performances et fonctionnera sur Android beaucoup plus fluide.
Voici mon code d'effacement :
Laissez demandeanimationframe = window.requestanimationframe || window.mozrequestanimationframe || window.webkitRequestanimationframe || window.msRequestanimationFrame; Let CancelanimationFrame = Window.CanceLanimationFrame || Window.MozCanceLanimationFrame; Soit a = 60; Laissez CanvasCleaner = Document.GetElementById ('Cas-1'); Laissez ctxCleaner = CanvasCleaner.getContex CanvascleanerBox.ClientWidth * 2; Canvascleaner.Height = CanvasCleanerBox.ClientHeight * 2; CanvasCleaner.Style.Width = CanvasCleanerBox.ClientWidth + 'PX'; Canvascleaner.Style.Height = CanvasanerBox.ClientHeight + 'Px'; iMgcleaner. 'https://gw.alicdn.com/tps/tb1xbyckvxxxxxxpxxxxxxxxx-1080-1920.jpg';imgcleaner.onload = () => {let width = parseInt (canvascleaner.style.width); w = canvascleaner.width * (imgcleaner.height / imgcleaner.width); ctxCleaner.DrawImage (imgcleaner, 0, 0, canvascleaner.width, w); ctxCleaner.lineCap = 'Round'; // La propriété LineCap définit ou renvoie le style du capuchon de ligne à la fin de la ligne. ctxcleaner.linejoin = 'rond'; ctxCleaner.lineWidth = 100; // Définir ou renvoie la largeur de la ligne actuelle ctxCleaner.GlobalCompositeOperation = 'Destination-out';} Let Drawline = (x1, y1, ctx) => {ctx.save (); ctx.beginPath (); ctx.arc (x1, y1, a, 0, 2 * math.pi); CTX.Fill (); // Fill () Méthode remplit l'image actuelle (chemin). La couleur par défaut est noire. CTX.RESTORE ();}; / * D Afin d'effacer les coordonnées du point de zone, les données que j'ai obtenues en simulant les formes qui doivent être effacées par moi-même sont similaires à ce qui suit: Soit D2 = [ [1 190], [30,180], [60,170], [90,168], [120,167], [150,165], [180,164], [210,163], [240,160], [270,159], [300,154], [330,153], [360,152],, [330,153], [360,152],, [330,153], [360,152],, [330,153], [360,152 [390,150], [420,140], [450,130], [480,120], [510,120], [540,120], [570,120], [600,120], [630,120], [660,120], [690,120], [720,120], [1,190], [20,189], [28,186], [45,185], [50,185], [62,184], [64,182], [90,180], [120,178],, [160,176], [200,174], [240,172]; * / Let Draw = (d, ctx) => {if (idx> = d.length) {CanceLanimationFrame (ts); } else {drawline (d [idx] [0], d [idx] [1], ctx); idx ++; requestanimationFrame (() => {draw (d, ctx);}); }}Parce que j'affiche l'animation d'effacement directement sur la page et que je ne nécessite pas que l'utilisateur l'essuie eux-mêmes, de sorte que les coordonnées de la zone d'effacement sont calculées par moi-même. Ensuite, utilisez RequestanimationFrame pour implémenter l'animation. J'ai commencé à utiliser SetInterval. J'ai constaté que le SetInterval sera toujours gâché par la suite, il est donc recommandé de ne pas utiliser SetInterval.
Dans le processus de réalisation de cet effet, j'ai constaté que lors de l'utilisation de la toile pour dessiner sur la page, l'image devient très floue?
Il s'avère que c'est parce qu'il existe une propriété devicePixelratio dans la variable de fenêtre du navigateur, qui détermine que le navigateur utilisera plusieurs (généralement 2) points de pixels pour rendre un pixel. C'est-à-dire en supposant que la valeur de DevicePixelratio est de 2, une image d'une taille de 100 * 100 pixels sera rendue avec la largeur de 2 pixels dans l'image. Par conséquent, l'image occupera en fait 200 * 200 pixels sur l'écran de la rétine, ce qui équivaut à l'image à agrandir deux fois, donc l'image devient floue.
De cette façon, le problème de la toile sera facilement résolu. Nous pouvons traiter la toile comme une image. Lorsque le navigateur rende la toile, il utilisera la largeur de 2 pixels pour rendre la toile, de sorte que l'image ou le texte dessiné sera flou dans la plupart des appareils rétines.
De même, il existe également une propriété WebKitBackingStorePixelratio (uniquement Safari et Chrome) dans le contexte de la toile. La valeur de cette propriété détermine que le navigateur utilisera plusieurs pixels pour stocker des informations sur le canevas avant de rendre le canevas. La valeur dans Safari sous IOS6 est 2. Par conséquent, si une image 100 * 100 est dessinée dans Safari, l'image générera d'abord une image 200 * 200 en mémoire, puis lorsque le navigateur le rendra, il le rendra comme une image 100x100, donc il deviendra 200x200, ce qui est exactement le même que l'image dans la mémoire, donc il n'y aura aucun problème de distorsion dans Safari sur Ios. Cependant, il y a une distorsion dans Safari dans Chrome et IOS7. La raison en est que les valeurs WebKitBackingStorePixelratio de Safari dans Chrome et IOS7 sont toutes deux 1.
Solution:
canvas.width = canvasbox.clientwidth * 2; canvas.height = canvasbox.clientheight * 2; canvas.style.width = canvas.clientwidth + 'px'; canvas.style.height = canvas.clientheight * 'px'; w = canevas.width * (iMg.height / img.width); // console.log (w); ctx.DrawImage (img, 0, 0, canvas.width, w);
Autrement dit, vous pouvez créer une toile qui est deux fois la taille réelle, puis utiliser le style CSS pour limiter la toile à la taille réelle. Ou utilisez ce polyfill sur github, mais je l'ai essayé et cela ne semble pas fonctionner.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.