Suivi des déplacements

De RAD Studio
Aller à : navigation, rechercher

Remonter à Amélioration du dessin des lignes


Tel qu'est écrit le gestionnaire de l'événement OnMouseMove, il présente l'inconvénient de dessiner une ligne, non pas depuis sa position d'origine, mais depuis la position actuelle de la souris. Pour y remédier, il suffit de placer la position de dessin au point d'origine et de tirer la ligne jusqu'au point en cours :

procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Drawing then
  begin
    Canvas.MoveTo(Origin.X, Origin.Y);{ déplacer le crayon au point de départ }
    Canvas.LineTo(X, Y);
  end;
end;
void __fastcall TForm1::FormMouseMove(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y) {
	if (Drawing) {
		Canvas->MoveTo(Origin.x, Origin.y); // placer le crayon sur le point de départ
     Canvas->LineTo(X, Y);
	}
}

Le code précédent fait le suivi de la position en cours de la souris, mais les lignes intermédiaires restent affichées et la ligne finale se voit à peine. L'astuce consiste à effacer chaque ligne avant de tracer la ligne suivante. Cela implique de garder la trace de son emplacement. C'est la fonction du champ MovePt ajouté préalablement.

Vous devez définir MovePt par le point d'arrivée de chaque ligne intermédiaire, et utiliser MovePt et Origin pour effacer cette ligne avant de dessiner la suivante :

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Drawing := True;
  Canvas.MoveTo(X, Y);
  Origin := Point(X, Y);
  MovePt := Point(X, Y);{ faire le suivi de la position du déplacement }
 end;

 procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Drawing then
  begin
    Canvas.Pen.Mode := pmNotXor; { utiliser le mode XOR pour dessiner/effacer }
     Canvas.MoveTo(Origin.X, Origin.Y);{ déplacer le crayon à l'origine}
     Canvas.LineTo(MovePt.X, MovePt.Y);{ effacer l'ancienne ligne }
     Canvas.MoveTo(Origin.X, Origin.Y);{ commencer de nouveau à l'origine}
     Canvas.LineTo(X, Y);{ dessiner la nouvelle ligne}
   end;
   MovePt := Point(X, Y);{ enregistrer le point pour le prochain déplacement }
   Canvas.Pen.Mode := pmCopy;
 end;
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
   TShiftState Shift, int X, int Y) {
   Drawing = true;            // définir l'indicateur de dessin
   Canvas->MoveTo(X, Y);      // Définir la position du crayon
   Origin = Point(X, Y);      // stocker le point de départ de la ligne
   MovePt = Point(X, Y);      // stocker le dernier point final
 }

 void __fastcall TForm1::FormMouseMove(TObject *Sender, TMouseButton Button,
   TShiftState Shift, int X, int Y) {
   if (Drawing) {
     Canvas->Pen->Mode = pmNotXor;        // Utiliser le mode XOR pour dessiner/effacer
     Canvas->MoveTo(Origin.x, Origin.y);  // placer le crayon sur le point de départ
     Canvas->LineTo(MovePt.x, MovePt.y);  // effacer l'ancienne ligne
     Canvas->MoveTo(Origin.x, Origin.y);  // placer à nouveau le crayon sur le point de départ
     Canvas->LineTo(X, Y);                // dessiner la nouvelle ligne
   }
   MovePt = Point(X, Y);      // stocker le nouveau point final
 Canvas->Pen->Mode = pmCopy;
}

Maintenant, un effet satisfaisant est obtenu lorsque la ligne est dessinée. En modifiant le mode du crayon en pmNotXor, il combine la ligne avec les pixels de l'arrière-plan. Lorsque la ligne est effacée, les pixels sont en fait ramenés à leur état antérieur. En remettant le mode du crayon à pmCopy (sa valeur par défaut) après avoir dessiné les lignes, le crayon est prêt pour le dessin final lorsque le bouton de la souris est relâché.

Voir aussi