1

我在 5.0 中运行此代码时遇到了问题,但在 3.3 中运行良好。我已经设置了所有东西,但仍然存在问题。我这样做是错误的吗?

<canvas width="1000" height="584">

      <drawview width="200" height="300" 
              x="12" 
              y="12">
        <handler name="onwidth">
            this.redraw();
        </handler>
        <handler name="onheight">
            this.redraw();
        </handler>
        <method name="redraw">
            this.clear();
            var roundness = 5;
            this.beginPath();
            this.moveTo(roundness, 0);
            this.lineTo(this.width - roundness, 0);
            this.quadraticCurveTo(this.width, 0, this.width, roundness);
            this.lineTo(this.width, this.height - roundness);
            this.quadraticCurveTo(this.width, this.height, this.width - roundness, this.height);
            this.lineTo(roundness, this.height);
            this.quadraticCurveTo(0, this.height, 0, this.height - roundness);
            this.lineTo(0, roundness);
            this.quadraticCurveTo(0, 0, roundness, 0);
            this.closePath();

            var g = this.createRadialGradient(-this.width * .5, -this.height *.5, .7, 1.5 * this.width, 1.5 * this.height, 0)
            this.globalAlpha = 0;
            g.addColorStop(0, 0x000000);
            this.globalAlpha = 0.8;
            g.addColorStop(1, 0xffffff);

            this.setAttribute("fillStyle", g);
            this.fill();
        </method>
    </drawview>
</canvas>
4

1 回答 1

1

onwidth 和 onheight 处理程序在 drawview 的初始化期间被调用,此时组件初始化尚未完成。如果您检查组件的 isinited 属性,则可以确保仅在组件准备好时才调用重绘方法。我在这个例子中添加了一些调试输出来告诉你发生了什么:

<drawview id="dv" width="100%" height="100%" 
      x="12" 
      y="12">
  <attribute name="isready" value="false" type="boolean" />
  <handler name="oncontext">
    this.setAttribute("isready", true);
    this.redraw();
  </handler>
  <handler name="onwidth">
    Debug.write('onwidth: calling redraw()');
    this.redraw();
  </handler>
  <handler name="onheight">
    Debug.write('onheight: calling redraw()');
    this.redraw();
  </handler>
  <method name="redraw">
    Debug.info('redraw: this.ininited=' + this.isinited + ' / isready=' + this.isready);
    if (this.isready) {
      this.clear();
      var roundness = 5;
      this.beginPath();
      this.moveTo(roundness, 0);
      this.lineTo(this.width - roundness, 0);
      this.quadraticCurveTo(this.width, 0, this.width, roundness);
      this.lineTo(this.width, this.height - roundness);
      this.quadraticCurveTo(this.width, this.height, this.width - roundness, this.height);
      this.lineTo(roundness, this.height);
      this.quadraticCurveTo(0, this.height, 0, this.height - roundness);
      this.lineTo(0, roundness);
      this.quadraticCurveTo(0, 0, roundness, 0);
      this.closePath();

      var g = this.createRadialGradient(-this.width * .5, -this.height *.5, .7, 1.5 * this.width, 1.5 * this.height, 0);
      this.globalAlpha = 0;
      g.addColorStop(0, 0x000000);
      this.globalAlpha = 0.8;
      g.addColorStop(1, 0xffffff);

      this.setAttribute("fillStyle", g);
      this.fill();
    }
  </method>
</drawview>

编辑:更新了代码支持以使用 oncontext 事件而不是 isinited 值

我检查了 drawview 文档,drawview 有一个特殊的事件,称为 oncontext 事件。从文档:

oncontext 事件在上下文准备好使用时发送,这在 IE DHTML 中可能需要一些时间。

如果您查看 OpenLaszlo 参考中的 drawview 文档,您将看到示例使用 oncontext 事件处理程序来绘制到画布中。
我已经更新了我的解决方案以使用附加属性isready,一旦收到 oncontext 事件,该属性就会设置为 true。正如您在下面的调试输出中看到的那样,isinited 在 isready 设置为 true 之前设置为 true:

onwidth: calling redraw() 
INFO: redraw: this.ininited=true / isready=false 
onheight: calling redraw() 
INFO: redraw: this.ininited=true / isready=false 
INFO: redraw: this.ininited=true / isready=true 

如果您为 DHTML 运行时编译错误代码,您应该看到以下警告:

警告:this.context 尚未定义。请在使用绘图方法之前检查 context 属性的存在,和/或注册 oncontext 事件以了解该属性何时可用。

不幸的是,SWF 运行时没有显示这样的警告。

于 2012-08-27T13:44:23.107 回答