SkiaSharp est une bibliothèque d’enveloppes .NET à code source libre reposant sur le logiciel Skia de Google, développée et maintenue par les ingénieurs de Xamarin. Poursuivez votre lecture pour apprendre à créer de superbes animations dans votre application mobile avec Xamarin.Forms et SkiaSharp.
Il me fait grand plaisir de partager avec vous certains de mes sujets de prédilection dans le développement de logiciels: infographie et applications mobiles. J'adore le graphisme depuis que je suis tout petit – j'aimais dessiner sur papier et, lorsque mes parents m'ont offert mon premier ordinateur personnel, un étonnant ZX Spectrum, je suis devenu complètement fasciné par l'infographie.
SkiaSharp est. une bibliothèque de wrapper open-source .NET du moteur graphique Skia et en combinaison avec Xamarin.Forms, qui est un excellent framework de développement d'applications mobiles open-source multiplate-forme, vous pouvez donner une nouvelle vie à vos applications mobiles.
Skia , The Star Performer
Skia est un moteur graphique 2D de haute performance et à source ouverte, écrit en C ++. C’est la propriété de Google et son soutien. Preuve de ses performances solides, il a été utilisé dans plusieurs produits grand public, tels que Google Chrome, Chrome OS, Android ou Mozilla FireFox, pour n'en nommer que quelques-uns. Le référentiel Skia est disponible ici: https://github.com/google/skia
Skia propose des versions de bibliothèque natives pour Android, iOS, Mac, Windows et ChromeOS.
Comme on pouvait s'y attendre d'un moteur graphique 2D, Skia dispose d'une API permettant de dessiner des primitives graphiques telles que du texte, des géométries et des images. Il possède une API en mode de rendu immédiat, de sorte que chaque appel effectué avec l'API Skia sera rapidement tracé à l'écran.
A Sharp Skia
SkiaSharp est un La bibliothèque d'enveloppes .NET sur Skia de Google, développée et maintenue par les ingénieurs de Xamarin et, bien sûr, est entièrement open source sous licence MIT. Vous pouvez consulter son référentiel de code source sur Github: https://github.com/mono/SkiaSharp
Sur les plates-formes autres que Windows, SkiaSharp s'exécute sur Xamarin et, comme pour toutes les autres. La bibliothèque NET, le moyen le plus simple d’ajouter SkiaSharp à vos projets est de NuGet: https://www.nuget.org/packages/SkiaSharp
SkiaSharp Canvas View
Pour voir réellement ce qui est à l’écran vous dessinez avec l’API SkiaSharp, SkiaSharp fournit un contrôle de zone de travail sur chaque plate-forme prise en charge. Ceci est fait par SkiaSharp.Views, une bibliothèque d'extension reposant sur SkiaSharp: https://www.nuget.org/packages/SkiaSharp.Views.Forms .
Voici quelques exemples du contrôle natif sur toile, fourni par SkiaSharp sur certaines plates-formes:
// Xamarin.iOS
public classe SKCanvasView : UIView .
{
public événement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
].
// Xamarin.Andruck ] public class SKSurfaceView : SurfaceView ISurfaceHolderCallback
{
public événement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
].
// Mac
. classe SKCanvasView : NSView
{
public évènement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
].
// UWP
. partiel classe SKXamlCanvas : Toile
{
public événement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
].
// WPF
public classe SKElement : FrameworkElement
{
public événement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
]
Comme vous le savez, Xamarin.Forms possède sa propre API multiplate-forme et ses contrôles qui encapsulent les API et les contrôles natifs. Par conséquent, pour les applications Xamarin.Forms, SkiaSharp dispose d'une bibliothèque dédiée appelée SkiaSharp.Views.Forms: https://www.nuget.org/packages/SkiaSharp.Views.Forms
SkiaSharp.Views. Forms fournit un contrôle Xamarin.Forms pour la toile, la classe SkCanvasView
:
// Xamarin.Forms
public SKCanvasView : Voir . ] ISKCanvasViewController
{
public événement EventHandler < SKPaintSurfaceEventArgs > PaintSurface ;
]
Sous le capot, le Xamarin. Les rendus de formulaires pour SKCanvasView
utilisent les mêmes vues natives qui partagent la même implémentation que dans SkiaSharp.Views
S'appuyant sur la vue SkiaSharp Canvas
Comme vous pouvez le voir ci-dessus, sur toutes les plates-formes, SkiCanvasView
a un événement PaintSurface
. Il déclenche l'événement lorsque le canevas doit être peint, soit parce que la vue a été redimensionnée, soit parce que vous avez appelé la méthode InvalidateSurface ()
:
_skCanvasView.InvalidateSurface ();
Sur le gestionnaire d'événements , vous obtenez une instance de SkiCanvas
que vous pouvez utiliser pour dessiner avec l’API SkiaSharp:
. . .
_skCanvasView . PaintSurface + = SkCanvasViewRequiredPainting ;
. . . . 19659080] objet expéditeur SKPaintSurfaceEventArgs e )
{
SKSurface skSurface = et . Surface ;
SKCanvas skCanvas = skSurface . Toile ;
skCanvas . Clear () ;
var paint = nouveau SKPaint (). 19659021] {
Style = SKPaintStyle . AVC
Couleur = Couleur . Bleu . Couleur du dessus ()
StrokeWidth = 10
} ;
// Dessinez sur l'instance skCanvas à l'aide de l'API SkiaSharp
skCanvas . DrawRect [ x y largeur hauteur peinture ) ;
}
Je trouve impressionnant de voir comment la combinaison de Xamarin, Xamarin.Forms et SkiaSharp permet de réunir .NET et Skia sur autant de plates-formes différentes et de fournir une plate-forme .NET croisée. API pour le développement d'applications mobiles et Skia!
Cet article traite de l'utilisation de Xamarin.Forms et de SkiaSharp. Par conséquent, ce que vous lirez au sujet de la prochaine utilisation utilise le SkCanvasView
de la bibliothèque SkiaSharp.Views.Forms.
Implémentation d'une surbrillance animée dans une application mobile avec Xamarin.Forms et SkiaSharp
À titre d'exemple, je vais montrer comment créer une surbrillance qui se déplace entre les entrées et un bouton d'un formulaire d'inscription, en créant une animation captivante effet. L'application est construite avec Xamarin.Forms, Skia.Sharp et C #, qui s'exécute de manière transparente sur Android et iOS. Voici une capture d'écran de l'application finale exécutée dans le simulateur iOS: https://www.youtube.com/watch?v=BBZWcWjJO_g
Vous pouvez consulter le code source complet de l'application dans mon référentiel sur GitHub: https://github.com/andreinitescu/AnimatedHighlightApp
L'implémentation est en C # et est partagée à 100% sur toutes les plates-formes: aucun code personnalisé, aucune plate-forme n'est impliqué, aucun Xamarin n'est impliqué. Les formes de rendu et aucun effet n'a été utilisé. Je ne l'ai pas testé sur d'autres plates-formes prises en charge par Xamarin.Forms et SkiaSharp, mais je suis sûr que le code fonctionne très bien sur celles-ci également.
Nous remercions les sources suivantes et leurs auteurs pour l'idée de conception d'animation: [19659111] Implémentation de la surbrillance
L'effet de surbrillance est créé en combinant le tracé d'un chemin géométrique avec l'API SkiaSharp et l'animation de la partie visible du chemin à l'aide de l'API d'animation Xamarin.Forms. Voici les principales étapes de ma mise en œuvre:
-
Créer la présentation du formulaire d'inscription
-
Construire et dessiner
SkPath
sursur SkCanvasView
en fonction de la position des éléments de formulaire dans la disposition du conteneur -
Rendre une certaine partie de
SkPath
visible à l'aide d'un effet de tiret -
Animation du point culminant entre les éléments
Création de la disposition du formulaire d'inscription
Le formulaire d'inscription comporte trois Entrée
éléments pour entrer le nom d'utilisateur, le mot de passe et le mot de passe de confirmation, et un bouton pour le soumettre. J'utilise un
StackLayout
comme conteneur pour les éléments de formulaire, mais tout autre conteneur fonctionnerait:
< StackLayout x: Nom = ] " _formLayout " ... >
< Label Texte = " Nom d'utilisateur " [19659129] Style = " { de StaticResource FormLabelStyle } " />
< Entrée de [1965915]]. = " { StaticResource FormEntryStyle } "
Focused = " EntryFocused " " />
< Label Texte = " Mot de passe "
Marge = " 0, 15, 0, 0 "
Style =" { StaticResource FormLabelStyle } " />
< Entrée IsPassword = " Vrai "
Style = "19659121] { StaticResource FormEntryStyle "
Focused = = EntryFocused " /
< Label Texte = " Confirmer le mot de passe "
Marge = " 0, 15, 0, 0 "
Style = "[19659121] { StaticResource FormLabelStyle } " /> 19659125] < Entrée IsPassword < True "
Style =" { StaticResource FormEntryStyle } "
Focused = " . " />
< Button Text = " Inscrivez-vous "
" Margin
19659121] = " 0, 40, 0, 0 "
Style = " { de référence statique FormSubmitBtnStyle } .
Clicked = " ButtonClicked " />
</ StackLayout >
Créez et dessinez SkPath sur SkCanView Basée sur la position des éléments de formulaire dans la disposition du conteneur
La ligne de surbrillance réelle est un chemin géométrique tracé à l'aide de l'API SkiaSharp. En utilisant la position de chaque élément Xamarin.Forms dans la présentation de formulaire, je crée un SkPath
reliant tous les éléments de formulaire, puis dessine le SkPath
créé sur le SKCanvasView
vue. Voici comment SkPath
complet se présente comme suit:
< Grille >
< Grille.Définitions >
< ColumnDefinition ] = " Auto " />
</ Grid.ColumnDefinitions >
<[19659224] skiaSharp: SKCanvasView x: Name = " _skCanvasView "
PaintSurface = "
SizeChanged = " SkCanvasViewSizeChanged " /> 19659125] < StackLayout x: Images de référence ] = " _formLayout " ... >
...
</ StackLayout >
</ Grille >
Création du SkPath
basé sur la position de Xamarin. Les éléments de formulaire sont implémentés dans la méthode CreatePathHighlightInfo
ici .
Rendre certaines parties de SkPath visibles à l'aide de l'effet Chemin du tiret
Lorsqu'un élément reçoit le focus, je ne rend visible que la partie. du SkPath
destiné à représenter l'élément mis en évidence:
paint . PathEffect = SKPathEffect . CreateDash ( intervalles : strokeDash . Intervalle phase : : . 04] strokeDash . Phase ) ;
skCanvas . DrawPath ( skPath paint ) ;
Comme vous pouvez le voir, le CreatesDash
prend un tableau d'intervalles et une phase .
Les intervalles
sont un tableau de valeurs flottantes indiquant la longueur de l'intervalle d'activation. et la longueur de l'intervalle “off” . Par exemple, un tableau d'intervalles avec les éléments 10, 5 placés sur un chemin de ligne crée l'effet de voir 10 pixels suivis d'un intervalle de 5 pixels (en supposant que la largeur du trait est de 1 pixel), et cette succession se répète le long du chemin: [19659003]
Dans le cadre de la création du chemin du point culminant, à côté de la construction du SkPath
je construis également un tableau de tirets représentant les intervalles du chemin correspondant à la mise en évidence de chaque Entrée
. et Élément Button
:
class HighlightPath
{
en lecture seule Dictionnaire < int de la série StrokeDash > de [1945927]]. ] new Dictionary < int StrokeDash > () ;
. . .
}
class StrokeDash
{
public float [] Intervalles { get ; ; ] set ; }
public float Phase { get ; set ; ]
. . .
}
J'utilise la position de l'élément sur la présentation du formulaire comme une clé pour savoir comment obtenir le tiret basé sur l'élément ciblé.
J'ai trois éléments Entry
et un bouton
. La liste de tirets contient quatre entrées représentant les valeurs de tirets, ce qui rend le chemin visible lorsque chaque élément a le focus. Voici une capture d'écran avec les valeurs de tiret du débogueur:
Pour que le surlignage apparaisse comme tel En me déplaçant entre les éléments de formulaire, j'anime les valeurs de tiret (intervalles et phase), des valeurs de tiret actuelles aux valeurs de tiret précalculées correspondant à l'élément devant apparaître en surbrillance.
J'ai commencé par créer mon propre StrokeDashAnimation
classe, qui encapsule animant le trait dans le trait les intervalles
et phase
valeurs:
classe StrokeDashAnimation
{
StrokeDash _currStrokeDash ;
public StrokeDash de { get ; }
public StrokeDash jusqu'à [ ]; }
public Durée du temps { get ; }
public Amélioration de la vitesse { }
public StrokeDashAnimation ( StrokeDash de de StrokeDash à de temps []] ] {
De = de ;
À = à ;
Durée = durée ;
}
. . .
}
J'utilise la classe StrokeDash
pour encapsuler valeur de tiret actuelle, dont les animations et les propriétés de phase sont mises à jour séparément pour chaque animation.
Si vous n'avez pas utilisé d'animation dans Xamarin.Forms, le cadre dispose d'un support très simple mais très puissant pour la création d'animations basées sur l'animation d'un double
valeur.
Le fonctionnement de Animation
est très simple: vous lui donnez un début double
un double
fin valeur et un type d'accélération. L'animation
utilise l'accélération pour calculer la valeur interpolée entre les valeurs de début et de fin. Une fois que vous avez commencé à utiliser la méthode Commit
une instance de Animation
appellera votre rappel pour chaque valeur calculée, en commençant par la valeur initiale donnée jusqu'à atteindre la valeur finale.
Animation
peut contenir d'autres instances de Animation
. Lorsque vous démarrez l'animation parent, ses animations enfants commencent.
Pour en savoir plus sur l'animation Xamarin.Forms et ses fonctionnalités, cliquez ici: https: //docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/animation/[19459012_rev19199003]Dans ma mise en œuvre, je crée une animation contenant trois animations internes pour chaque propriété de trait d'un trait: intervalle “ on ”, intervalle“ off ”et phase:
class StrokeDashAnimation
{
StrokeDash _currStrokeDash ;
public StrokeDash de { get ; }
public StrokeDash jusqu'à [ ]; }
public Durée du temps { get ; }
public Amélioration de la vitesse { }
public StrokeDashAnimation ( StrokeDash de de StrokeDash à de temps []] ] {
De = de ;
À = à ;
Durée = Durée ;
}
public void Start ( Action < StrokeDash > onValueCallback )
{
_currStrokeDash = De ;
var anim = nouveau Animation ( ( v ). 19659389] = > surValueCallback ( _currStrokeDash ) ) ;
anim . Ajouter [ 0 1 nouveau Animation (
callback : v = > _currStrokeDash . Phase = ( float ).
début : à partir de . Phase
fin : à . Phase
assouplissement : assouplissement ) ) ;
anim . Ajouter [ 0 1 nouveau Animation (
callback : v = > _currStrokeDash . Intervalles [ 0 ] = 19659080] float ) v
début : à partir de . intervalles [ 0 ]
fin : à . Intervalles [ 0 ]
assouplissement : assouplissement ) ) ;
anim . Ajouter [ 0 1 nouveau Animation (
rappel : v = > _currStrokeDash . Intervalles [ 1 ] = 19659080] float ) v
début : à partir de . intervalles [ 1 ]
fin : à . Intervalles [ 1 ]
assouplissement : assouplissement ) ) ;
anim . Commit (
owner : Application . Actuelle . Page principale
nom : "highlightAnimation"
longueur : ( uint ) Durée . TotalMillisecondes ) ;
}
}
le focus est changé en un Entrée
ou Bouton
est cliqué, je lance l'animation en passant des valeurs de tiret actuelles aux valeurs de tiret précalculées:
void DrawDash ( SKCanvasView skCanvasView StrokeDash fromDash StrokeDash toDash )
{
si de [1945904] deDash [1945904]. ! = null )
{
var anim = new StrokeDashAnimation (
de : duDash
à : àDash
durée : _highlightSettings . AnimationDuration ) ;
anim . Début ( ( strokeDashToDraw ) = > RequestDraw ( skCanvasView strokeDashToDraw ) ) ;
}
autre
RequestDraw ( skCanasView duDash ;
}
void RequestDraw ( SKCanvasView skCanvasView StrokeDash strokeDashToDraw )
[
_highlightState . StrokeDash = strokeDashToDraw ;
skCanvasView . InvalidateSurface () ;
}
Pour chaque nouvelle valeur de trait de trait calculé, j'invalide la surface SkCanvasView
afin d'invalider faites-le déclencher son événement PaintSurface
. Sur le gestionnaire d'événement paint, je trace le chemin avec les nouvelles valeurs de tiret conservées par _highlightState.StrokeDash
:
public nul Draw ( SKCanView skCanvasView SKCanvas skCanvas )
{
skCanvas . Clear () ;
if ( _highlightState == null )
retour ;
if ( _skPaint == null )
_skPaint = CreateHighlightSkPaint ( skCanvasView _highlightSettings _highlightState
StrokeDash strokeDash = _highlightState . StrokeDash ;
// Commentez la ligne suivante pour afficher le chemin complet sans effet de tiret
_skPaint . PathEffect = SKPathEffect . CreateDash ( strokeDash . [19459904]. [19459264]. . Phase ) ;
skCanvas . DrawPath ( _highlightState . HighlightPath . Tracé
Source link