[Résolu] Fading sur une image... Je n'y arrive pas :-(
LeChatNoir
Membre, Modérateur
Salut,
je suis encore dans mes animations...
Merci à Renaud et mpergrand pour leurs réponses sur le précédent topic !
Voilà ce que j'aimerai faire (et ce que j'ai comme architecture) :
Dans une fenêtre, j'ai une NSImageView.
Sur une action particulière, je vais déclencher un NSTimer qui se chargera d'afficher une image constuite à la volée (en fonction de la sélection) en fondu.
Donc ma fonction se chargeant de l'animation devra :
* faire un fondu sortant de la précédente image,
* faire un fondu entrant de la nouvelle.
Pour ça, je compte utiliser les méthode "compositeToPoint...delta" et "dissolve....delta".
Mais comment dois je m'y prendre ?
A des fins de tests, dans mon timer, je fais un lockFocus sur mon NSImageView et un simple composite avec un delta à 1 mais l'image n'apparaà®t pas (malgré un setNeedDisplay).
Elle n'apparait que quand je fais un setImage :-(
Peut être devrais je faire comme conseiller par Renaud : une sous classe de NSView ?
Ou peut être plus simplement utiliser les méthodes CG pour faire varier le RGB ? (mais je ne connais pas bien. Chacha peut être ?)
Je compte poursuivre mes tests ce soir mais je m'en remets à vos lumières en attendant !
Merci !
je suis encore dans mes animations...
Merci à Renaud et mpergrand pour leurs réponses sur le précédent topic !
Voilà ce que j'aimerai faire (et ce que j'ai comme architecture) :
Dans une fenêtre, j'ai une NSImageView.
Sur une action particulière, je vais déclencher un NSTimer qui se chargera d'afficher une image constuite à la volée (en fonction de la sélection) en fondu.
Donc ma fonction se chargeant de l'animation devra :
* faire un fondu sortant de la précédente image,
* faire un fondu entrant de la nouvelle.
Pour ça, je compte utiliser les méthode "compositeToPoint...delta" et "dissolve....delta".
Mais comment dois je m'y prendre ?
A des fins de tests, dans mon timer, je fais un lockFocus sur mon NSImageView et un simple composite avec un delta à 1 mais l'image n'apparaà®t pas (malgré un setNeedDisplay).
Elle n'apparait que quand je fais un setImage :-(
Peut être devrais je faire comme conseiller par Renaud : une sous classe de NSView ?
Ou peut être plus simplement utiliser les méthodes CG pour faire varier le RGB ? (mais je ne connais pas bien. Chacha peut être ?)
Je compte poursuivre mes tests ce soir mais je m'en remets à vos lumières en attendant !
Merci !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
- (void)drawAtPoint:(NSPoint)point fromRect:(NSRect)srcRect operation:(NSCompositingOperation)op fraction:(float)delta (NSImage)
(ça y est tu l'as eu au complet cette fois)
La ImageView est intéressante si tu veux gérer le drag&drop des images, avec des bindings et ce genre de truc, mais juste pour l'affichage d'une image avec des animations et des transformations c'est pas vraiment fait pour.
Oui bon effectivement, j'ai un peu du mal...
Mais je vais me ranger à l'avis d'un sage et sous classer. Bien que ma méthode, même si un peu pourrie, aurait du fonctionner et je ne comprend pas pourquoi elle ne fonctionne pas...
Passons.
Je sous classe NSView. Soit.
Je met une variable d'instance qui représente ma transparence.
Dans la méthode drawRect(NSRect aRect), je fais ma tambouille pour récupérer mon image et je fais mon [mon imagerécup drawAtPoint...delta] (celle que tu me donnes si gentiement )
Si y avait déjà une image, faut que je m'arrange pour la "dissolver" avant et comme c'est l'image qui est dans moi (self), je sais la retrouver pour la "dissolver".
Ouais, c'est cool comme solution. Je m'en voyais bcp plus avec ma NSImageView qui me sert à rien (pas de drag, pas de drop, rien d'un NSControl quoi).
Mais...
Car il y a [glow=red,2,300]toujours[/glow] un mais ::)
Mon timer (qui est dans le controller qui déclenche l'animation), il appelle quoi ?
Il peut pas appeler le drawRect de ma vue quand même ! Ca se fait pas !
Ou alors j'implémente ça dans une méthode autre (perso) de ma NSView et rien dans le drawRect ?
Tout à fait, il faut qu'il appelle une méthode à toi qui elle contient un setNeedsDisplay:YES.:)
- soit tu implémente le fading dans le controller et alors tu effectueras des setAlpha: les uns après les autres en utilisant la valeur de diminution. Ca te donneras un truc comme :
- tu implémente directement le changement dans la vue, auquel cas tu pourras implementer une méthode fadeIn ou fadeOut qui fera le changement de transparence elle-même et que tu appeleras directement depuis le timer. Ca te donneras :
Ensuite, à toi de savoir quand appeler setNeedsDisplay: : soit dans setAlpha: soit autre part
Je m'en vais implémenter tout ça ce soir (si le temps me le permet !).
Merci les gars !
Ta sous-classe devra avoir 2 variables d'instances NSImage aussi (image1 et image2), pour garder l'image précédent et suivante.
Et des méthodes dans ta sous-classe devront être du genre :
-> Le timer va faire des appels à [tt]drawAtPoint:...delta[/tt] (en utilisant image1 et image2 + faisant varier la valeur de l'alpha/delta) + un appel à setNeedsDisplay:YES après chaque.
et dans ton drawRect :
Si tout ce passe comme je l'imagine, le fait que image1 soit nil la toute première fois (toute première image) ne posera pas de problème pour le compositing. et les fois suivantes, ça fera un fondu entre les 2 images (image1 qui est l'image précédente et image2 qui est l'image à afficher)
Enfin moi c'est comme ça que je vois les choses. La classe gère tout (c'est son rôle, c'est pas à ton contrôlleur qui la gère de gérer l'alpha et tout), et toi de l'extérieur tu appelles juste fadeToImage: pour faire un fondu entre la dernière image (celle que ta vue affiche actuellement) et la prochaine image (qui deviendra, à la fin de la transition, la nouvelle "dernière image")
Le timer est intégré à ta sous-classe perso, t'as rien à gérer à l'extérieur.
C'est à ça que sert l'encapsulation dans ta classe. Sinon si ton contrôlleur doti gérer le timer et tout, autant limite ne pas sous-classer
Je n'utilise pas de timer ::)
[EDIT]
Ca pullule de bugs par ici, saleté de bestioles !
2e essai
[Fichier joint supprimé par l'administrateur]
Voilà ce que j'en ai sortis.
Une sous classe de NSView qui fait un fondu entrant/sortant entre 2 images.
La boucle est un peu bancale et certainement améliorable mais je n'ai pas de besoins particuliers en terme de perf donc ca me convient.
Pour l'utiliser, il suffit de copier/coller le code dans une classe Obj-C, de glisser deposer une custom view dans IB. De lui donner le "Custom Type" de la classe et d'appeler quand on le souhaite la méthode fadeImageIn: avec l'image sur laquelle on veut un fondu entrant. Si la vue affichait précédemment une image, il y a un petit fondu sortant avant.
Encore merci à tous !
Le header
L'implémentation :