2009-02-07 8 views
6

Je trace une ligne sur un objet Canvas avec les méthodes graphiques moveTo et lineTo. Si une extrémité de la ligne se trouve à l'extérieur du canevas, la ligne déborde et est dessinée au-dessus ou en dessous d'autres éléments de l'application.Comment faire pour que le clip Canvas soit contenu dans Flex?

Comment faire en sorte que le Canevas conserve la ligne qu'il contient?

Merci!

Répondre

2
<mx:Canvas id="canvas" top="0" right="51" left="0" bottom="32"> 
<mx:Canvas x="-1" y="0" width="0" height="0"> <!-- This is a HACK to make the canvas clip --> 
</mx:Canvas> 
</mx:Canvas> 
2

J'ai eu un problème similaire il y a quelque temps. Vous devez incorporer un autre conteneur dans le canevas et dessiner les graphiques primitifs à la place. Je crois que c'est parce que le composant Canvas ne capture que les composants enfant, et non les graphiques primitifs.

Exemple ici: http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=60&catid=585&threadid=1421196. Il inclut un exemple de code à mi-chemin de la page.

+0

que les liens ne fonctionne pas pour moi, peut-être vous dire ce fil: http://forums.adobe.com/message/47864 # 47864 – Tom

-1

Ensemble propriété ClipToBounds de la toile pour vrai:

<Canvas ClipToBounds="True">... Content ...</Canvas> 
+0

Pourriez-vous expliquer ceci un peu plus? – cereallarceny

0

Le lien dans la réponse recommandée est cassée. J'ai résolu le problème en plaçant une autre toile à l'intérieur de ma toile qui est plus grande que la toile extérieure.

Exemple:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="onComplete()"> 
    <mx:Script><![CDATA[ 
     private function onComplete():void 
     { 
      canvas.graphics.lineStyle(1); 
      canvas.graphics.moveTo(-100, -100); 
      canvas.graphics.lineTo(400, 400); 
     } 
    ]]></mx:Script> 
    <mx:Canvas id="window" 
       height="300" 
       width="300" 
       clipContent="true" 
       horizontalScrollPolicy="off" 
       verticalScrollPolicy="off" 
       backgroundColor="white"> 
     <mx:Canvas id="canvas" width="301" height="301"> 
     </mx:Canvas> 
    </mx:Canvas> 
</mx:Application> 

Si la fenêtre de toile va être redimensionnée à l'exécution, ajoutez un écouteur d'événement resize pour redimensionner la toile en toile aussi.

0

Je viens de développer un composant Flex Box, qui agit comme un conteneur de composant régulier, mais dessine un fond de rectangle arrondi, avec un autre rectangle arrondi indiquant un niveau de remplissage. Pour cela j'ai eu besoin de couper la partie supérieure qui ne devrait pas être remplie. Dessiner le rectangle de remplissage à la hauteur de remplissage n'était pas une option puisque les coins arrondis ne correspondraient pas.

Ce que j'appris:

  • J'ai créé un composant toile juste pour tirer le niveau de remplissage avec des limites et 0/0 largeur/hauteur de la boîte
  • J'ai ajouté que la toile à la boîte à l'index 0 via addChildAt()
  • Je mis la propriété includeInLayout sur false pour cette toile car il ne devrait pas prendre part à la layouting de la boîte elle-même, mais plutôt agir comme une fenêtre de dessin flottant au-dessus
  • je puis ajouté une autre toile comme le masque à ce fill-canvas (addChild(), et mettre m demander à la propriété)

Voici un code:

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
{ 
    // super 
    super.updateDisplayList(unscaledWidth, unscaledHeight); 

    // prep 
    var g:Graphics = this.graphics; 
    var fgColor:int = this.getStyle("fillColor"); 
    var bgColor:int = this.getStyle("backgroundFillColor"); 
    var radius:int = this.getStyle("cornerRadius"); 

    // clear 
    g.clear(); 

    // draw background 
    g.beginFill(bgColor, 1); 
    g.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, radius, radius); 
    g.endFill(); 

    // draw fill level 
    if (this._fillLevel > 0) { 
     var fillHeight:int = int(unscaledHeight * this._fillLevel); 

     // extra component for drawing fill-level, so we can apply mask just to this 
     if (this._fillLevelCanvas == null) { 
      this._fillLevelCanvas = new Canvas(); 
      this._fillLevelCanvas.x = 0; 
      this._fillLevelCanvas.y = 0; 
      this._fillLevelCanvas.includeInLayout = false; 
      this.addChildAt(this._fillLevelCanvas, 0); 
     } 
     this._fillLevelCanvas.width = unscaledWidth; 
     this._fillLevelCanvas.height = unscaledHeight; 

     // mask 
     if (this._fillLevelMask == null) { 
      this._fillLevelMask = new Canvas(); 
      this._fillLevelMask.x = 0; 
      this._fillLevelMask.y = 0; 
      this._fillLevelCanvas.addChild(this._fillLevelMask); 
      this._fillLevelCanvas.mask = this._fillLevelMask; 
     } 
     this._fillLevelMask.width = this.width; 
     this._fillLevelMask.height = this.height; 
     this._fillLevelMask.graphics.beginFill(0xFFFFFF); 
     this._fillLevelMask.graphics.drawRect(0, this.height-fillHeight, this._fillLevelMask.width, this._fillLevelMask.height); 
     this._fillLevelMask.graphics.endFill();     

     this._fillLevelCanvas.graphics.beginFill(fgColor, 1); 
     this._fillLevelCanvas.graphics.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, radius, radius); 
     this._fillLevelCanvas.graphics.endFill(); 
    } 
} 
Questions connexes