【问题标题】:How to make the Canvas clip its contents in Flex?如何使 Canvas 在 Flex 中剪辑其内容?
【发布时间】:2010-10-06 03:10:20
【问题描述】:

我用 moveTo 和 lineTo 图形方法在 Canvas 对象上画了一条线。如果线条的一端位于 Canvas 之外,则线条会溢出并绘制在应用程序中的其他元素之上或之下。

如何使 Canvas 将线条包含在其自身中?

谢谢!

【问题讨论】:

    标签: apache-flex canvas clipping


    【解决方案1】:
    <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】:

      前段时间我也遇到过类似的问题。您需要在画布中嵌入另一个容器,并在其中绘制原始图形。我相信这是因为 Canvas 组件只剪辑子组件,而不是原始图形。

      此处的示例:http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=60&catid=585&threadid=1421196。它在页面的一半左右包含一些示例代码。

      【讨论】:

      【解决方案3】:

      推荐答案中的链接已损坏。我通过在我的画布内放置另一个比外部画布大的画布解决了这个问题。

      例子:

      <?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 的大小。

      【讨论】:

        【解决方案4】:

        我刚刚开发了一个 Flex Box 组件,它作为一个常规的组件容器,但绘制一个圆角矩形背景,另一个圆角矩形表示填充级别。为此,我需要夹住不应填充的上部。无法将填充矩形绘制到填充高度,因为圆角不匹配。

        我学到了什么:

        • 我创建了一个 Canvas 组件,仅用于绘制边界为 0/0 和框的宽度/高度的填充级别
        • 我通过 addChildAt() 将该画布添加到索引为 0 的 Box 中
        • 我将该画布的 includeInLayout 属性设置为 false,因为它不应该参与 Box 本身的布局,而是充当顶部的一些浮动绘图窗格
        • 然后我添加了另一个 Canvas 作为该填充画布的遮罩(addChild() 并设置遮罩属性)

        这里有一些代码:

        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();
            }
        }
        

        【讨论】:

          【解决方案5】:

          看起来这可能有用:

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

          【讨论】:

            【解决方案6】:

            将 Canvas 的 ClipToBounds 属性设置为 true:

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

            【讨论】:

            • 您能再解释一下吗?
            猜你喜欢
            • 1970-01-01
            • 2011-08-23
            • 2022-09-24
            • 2019-05-14
            • 1970-01-01
            • 1970-01-01
            • 2013-04-26
            • 2019-06-07
            • 1970-01-01
            相关资源
            最近更新 更多