Как заставить Canvas обрезать его содержимое во Flex? - PullRequest
6 голосов
/ 07 февраля 2009

Я рисую линию на объекте Canvas с помощью графических методов moveTo и lineTo. Если один конец линии находится за пределами Canvas, линия выделяется и рисуется над или под другими элементами приложения.

Как мне сделать так, чтобы Canvas содержал в себе строку?

Спасибо!

Ответы [ 6 ]

2 голосов
/ 10 мая 2009
<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 голосов
/ 07 февраля 2009

У меня была похожая проблема некоторое время назад. Вам нужно вставить другой контейнер внутри холста и вместо этого нарисовать примитивную графику. Я считаю, что это потому, что компонент Canvas только обрезает дочерние компоненты, а не примитивную графику.

Пример здесь: http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=60&catid=585&threadid=1421196. Включает пример кода примерно на полпути вниз по странице.

0 голосов
/ 08 марта 2010

Я только что разработал компонент Flex Box, который действует как обычный контейнер компонента, но рисует фон прямоугольника с закругленными углами, а другой прямоугольник с закругленными углами указывает на уровень заполнения. Для этого мне нужно было обрезать верхнюю часть, которая не должна заполняться. Рисование прямоугольника заливки до высоты заливки было невозможным, поскольку закругленные углы не совпадали.

Что я выучил:

  • Я создал компонент Canvas только для рисования уровня заполнения с границами 0/0 и шириной / высотой блока
  • Я добавил этот холст в Box с индексом 0 с помощью addChildAt ()
  • Я установил для свойства includeInLayout значение false для этого холста, поскольку он не должен участвовать в компоновке самого Box, а действовать как некая плавающая панель рисования сверху
  • Затем я добавил еще один Canvas в качестве маски для этого fill-canvas (addChild () и установил свойство mask)

Вот код:

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();
    }
}
0 голосов
/ 03 марта 2010

Ссылка в рекомендуемом ответе не работает. Я решил проблему, поместив другой холст внутри моего холста, который больше, чем внешний холст.

Пример:

<?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>

Если размер окна Canvas будет изменен во время выполнения, добавьте прослушиватель события resize, чтобы изменить размер холста Canvas.

0 голосов
/ 26 февраля 2010

Установить свойство ClipToBounds для Canvas в true:

<Canvas ClipToBounds="True">... Content ...</Canvas>
0 голосов
/ 26 мая 2009

Похоже, это может быть полезно:

http://forums.adobe.com/message/199071#199071

...