saccades avec NSAnimation

Philippe49Philippe49 Membre
mai 2007 modifié dans API AppKit #1
Bonjour à  tous

Ma petite question du week-end, simple, pour vous reposer

Pour réaliser un diaporama avec plusieurs images par écran, j'essaye d'utiliser NSViewAnimation ou NSAnimation.
Le résultat est saccadé, horizontalement, c'est naturel et paramétrable, mais aussi verticalement, et cela c'est bizarre.

Voici un petit essai (fichier joint) dans un contexte plus simple (la voiture de Fantomas qui s'envole) qui montre les mêmes problèmes de saccades.

Avez-vous une expérience là -dessus ?

(je me rappelle avoir programmer à  la main de tels mouvements dans des threads sans avoir cet effet là , mais le 'clé en mains" d'Apple devrait quand même réaliser cette tâche)



[Fichier joint supprimé par l'administrateur]

Réponses

  • mai 2007 modifié #2
    Jusqu'à  ce jour je ne m'étais jamais intéressé à  NSAnimation mais ce que je ne comprends pas trop c'est par quoi remplacer :

    - (void)animation:(NSAnimation*)anim didReachProgressMark:(NSAnimationProgress)progress
    


    qui est noté comme "deprecated".
    Edit : en fait c'est marqué "delegate method" !

    Edit : on peut observer la notification : tester : c'est pareil.

    Note : avec un NSTimer c'est fluide.
  • Eddy58Eddy58 Membre
    mai 2007 modifié #3
    Pas mal la voiture de Fantomas, je me croirais revenu sur mon CPC. ;)
    Sinon ça vient en faites du pas de progression qui est trop grand et hâche l'animation. Il faut mettre un diviseur plus grand pour régler le problème : :)
    [tt]
    for(i=0;i<50;i++)
    [animation addProgressMark:i/1000.0];
    [/tt]

    @Supermic : Je ne vois pas de mention Deprecated pour cette méthode dans ma doc (dernière mise à  jour) ?
  • Philippe49Philippe49 Membre
    20:49 modifié #4
    dans 1180180850:

    Pas mal la voiture de Fantomas, je me croirais revenu sur mon CPC. ;)


    Cela fait plaisir quand l'art est reconnu !!

    dans 1180180850:

    Sinon ça vient en faites du pas de progression qui est trop grand et hâche l'animation. Il faut mettre un diviseur plus grand pour régler le problème : :)
    [tt]
    for(i=0;i<999;i++)
    [animation addProgressMark:i/1000.0];
    [/tt]


    Dans ce cas la durée  (setDuration:) est difficilement paramétrable. On obtient 20 secondes au lieu de 2 secondes prévue.

  • 20:49 modifié #5
    Je souhaiterais poser une question : à  quoi sert setFrameRate: on précise le temps de l'animation à  la création ainsi le nombre d'étapes donc pourquoi indiquer un frameRate ?
  • Eddy58Eddy58 Membre
    20:49 modifié #6
    dans 1180182820:

    Dans ce cas la durée  (setDuration:) est difficilement paramétrable. On obtient 20 secondes au lieu de 2 secondes prévue.

    En mettant i<50 pour un diviseur de 1000, l'animation est correcte et dure un temps que je trouve normal, après en effet, le setDuration ne sert plus à  grand chose et là  dans l'immédiat je ne vois pas comment régler ça dans le cadre de cette classe, après il faudrait chercher des exemples pour voir. :o
  • Philippe49Philippe49 Membre
    20:49 modifié #7
    dans 1180183612:

    Je souhaiterais poser une question : à  quoi sert setFrameRate: on précise le temps de l'animation à  la création ainsi le nombre d'étapes donc pourquoi indiquer un frameRate ?


    C'es le nombre d'images (de vue) par secondes (demandé)
  • mai 2007 modifié #8
    Ok mais on précise le nombre de "progressmark" ainsi que la durée de l'animation ce qui est forcément déterminant pour le nombre d'images/sec (progressmark / duration).

    Certainement une subtilité qui m'échappe...
  • Philippe49Philippe49 Membre
    20:49 modifié #9
    dans 1180185328:

    En mettant i<50 pour un diviseur de 1000, l'animation est correcte et dure un temps que je trouve normal


    D'après la doc, le dernier "progressMark" doit être 1.0.
    You can set progress marks in an animation, each of which specifies a percentage of the animation completed; when an animation reaches a progress mark, it notifies its delegate and posts a notification to any observers
    progressmark correspond au pourcentage de l'animation réalisée.

    En mettant i de 1 à  50, et i/1000, les progress mark sont 0.001 0.002 ... 0.049. (rajouter fprintf(stderr,"%.2f",progress); dans la méthode animation:)
    La progression se fait alors dans un petit intervalle de temps initial, moins de une seconde il me semble (théoriquement 2 sec /20 = 1/10), puis de 0.05% à  100% le programme attend ou bien l'animation est terminée.




  • Philippe49Philippe49 Membre
    mai 2007 modifié #10
    dans 1180187226:

    Ok mais on précise le nombre de "progressmark" ainsi que la durée de l'animation ce qui est forcément déterminant pour le nombre d'images/sec (progressmark / duration).

    Certainement une subtilité qui m'échappe...


    je pense que le système fait "au mieux" pour répondre à  la demande.

    En ajustant cela a l'air mieux :
    frame rate 36 images/sec
    for(i=0;i<108;i++) [animation addProgressMark:i/107.];

    [transform translateXBy:5. yBy:0.5];
    [transform rotateByDegrees:0.5];


    Je regarde sur mon appli diaporama si on peut ajuster ainsi par tâtonnements ... sachant que des images sont plus sensibles aux "vibrations que mon splendide Fantom Car !

  • Eddy58Eddy58 Membre
    20:49 modifié #11
    J'ai consulté le "Animation Programming Guide", et il est fortement déconseillé d'utiliser les progress marks pour avoir une animation fluide :


    Important: Although you can use progress marks to “time-slice” the animation of an object, it is not an ideal way to achieve a smooth animation. A recommended alternative is to subclass NSAnimation and redraw an object at each change of frame; see “Smooth Animations” for more information.
  • mai 2007 modifié #12
    Philippe49 : il me semble alors que pour ton problème () tu devrais réduire les effets du NSAffineTransform afin d'augmenter d'autant le nombre de progressMark.

    Eddy58 : sans progress mark aucune animation ? Je pensais que c'était justement ça le problème et qu'en passant par un NSTimer c'était plus "régulier".

    http://developer.apple.com/documentation/Cocoa/Conceptual/AnimationGuide/Articles/TimingAnimations.html#//apple_ref/doc/uid/TP40003581-CJBGGDAD
  • Philippe49Philippe49 Membre
    20:49 modifié #13
    dans 1180188865:

    J'ai consulté le "Animation Programming Guide", et il est fortement déconseillé d'utiliser les progress marks pour avoir une animation fluide :


    Important: Although you can use progress marks to “time-slice” the animation of an object, it is not an ideal way to achieve a smooth animation. A recommended alternative is to subclass NSAnimation and redraw an object at each change of frame; see “Smooth Animations” for more information.



    Oui je l'avais lu, mais je dois être têtu ...
    Ok, on va essayer ainsi .

    Merci !
  • Eddy58Eddy58 Membre
    20:49 modifié #14
    dans 1180188955:

    Eddy58 : sans progress mark aucune animation ? Je pensais que c'était justement ça le problème et qu'en passant par un NSTimer c'était plus "régulier".


    Oui, mais si on passe par un NSTimer autant abandonner cette classe et tout faire soit même. En faites il faudrait définir une trentaine de progress marks par seconde pour obtenir quelque chose de fluide, le meilleur moyen est de sous-classer NSAnimation comme indiqué dans la doc.
  • Philippe49Philippe49 Membre
    mai 2007 modifié #15
    dans 1180189216:


    Ok, on va essayer ainsi .


    Voilà  un essai au plus simple, confondant de simplicité.

    [Fichier joint supprimé par l'administrateur]
Connectez-vous ou Inscrivez-vous pour répondre.