ExtJS 如何使绘制精灵响应?

ExtJS how to make draw sprites responsive?

我有一个由精灵组成的图像。我试图让它响应,所以当我调整浏览器大小时,图像也会针对较小的设备及其屏幕调整大小。

这是演示:https://fiddle.sencha.com/#fiddle/3al5&view/editor

sprites: [{
                type: 'circle',
                cx: 150,
                cy: 150,
                r: 150,
                fillStyle: '#000'
            }, {
                type: 'circle',
                cx: 150,
                cy: 150,
                r: 100,
                fillStyle: '#fff'
            },]

widthheight 设置为 100% 将不起作用。

现在,没有反应:

您可以使用 'resize' 事件处理程序并缩放所有精灵,如下所示 (v.5.1):

Ext.application({
  name: 'Fiddle',

  launch: function () {
    Ext.create({
      xtype: 'window',
      title: 'Resizable Sprite Window',
      width: 400,
      height: 400,
      layout: 'fit',
      items: [
        {
          xtype: 'draw',
          plugins: ['spriteevents'],
          sprites: [
            {
              type: 'circle',
              cx: 150,
              cy: 150,
              r: 150,
              fillStyle: '#000',
            },
            {
              type: 'circle',
              cx: 150,
              cy: 150,
              r: 100,
              fillStyle: '#fff',
            },
            {
              type: 'rect',
              height: 4,
              radius: 1,
              width: 30,
              x: 135,
              y: 44,
              fillStyle: '#fff',
            },
            {
              type: 'text',
              x: 212.5,
              y: 41.7,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '1',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 258.2,
              y: 87.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '2',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 275,
              y: 150,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '3',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 258.2,
              y: 212.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '4',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 212.5,
              y: 258.2,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '5',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 275,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '6',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 87.5,
              y: 258.2,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '7',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 41.7,
              y: 212.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '8',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 25,
              y: 150,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '9',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 41.7,
              y: 87.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '10',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 87.5,
              y: 41.7,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '11',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 25,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '12',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 75,
              fontSize: '15px',
              fillStyle: '#000',
              text: 'Clock',
              textAlign: 'center',
              textBaseline: 'middle',
            },
          ],
          listeners: {
            afterRender: this.onDrawPanelIdAfterRender,
            spriteclick: this.onDrawPanelIdSpriteClick,
            boxready: function (item, width, height) {
              item.initWidth = width;
              item.initHeight = height;
            },
            resize: function (item, width, height, oldWidth, oldHeight) {
              if (arguments.length == 3) {
                // Looks like to be bug, fires twice with diferent number of arguments..
                return;
              }
              const scalingX = width / item.initWidth;
              const scalingY = height / item.initHeight;
              const items = item.getSurface().getItems();
              items.forEach((spriteItem) => {
                spriteItem.setAttributes({
                  scalingX: scalingX,
                  scalingY: scalingY,
                  scalingCenterX: scalingX,
                  scalingCenterY: scalingY,
                });
              });
            },
          },
        },
      ],
    }).show();
  },
  onDrawPanelIdAfterRender: function (item, event) {
    console.log('afterrender....');
  },
  onDrawPanelIdSpriteClick: function (item, event) {
    console.log('spriteclick....');
    var sprite = item && item.sprite;
    if (sprite) {
      sprite.setAttributes({
        fillStyle: 'red',
      });
      sprite.getSurface().renderFrame();
    }
  },
});

保持比例 (v.5.1):

Ext.application({
  name: 'Fiddle',

  launch: function () {
    var window = Ext.create({
      xtype: 'window',
      title: 'Resizable Sprite Window',
      width: 400,
      height: 400,
      layout: 'fit',
      items: [
        {
          xtype: 'draw',
          plugins: ['spriteevents'],
          sprites: [
            {
              type: 'circle',
              cx: 150,
              cy: 150,
              r: 150,
              fillStyle: '#000',
            },
            {
              type: 'circle',
              cx: 150,
              cy: 150,
              r: 100,
              fillStyle: '#fff',
            },
            {
              type: 'rect',
              height: 4,
              radius: 1,
              width: 30,
              x: 135,
              y: 44,
              fillStyle: '#fff',
            },
            {
              type: 'text',
              x: 212.5,
              y: 41.7,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '1',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 258.2,
              y: 87.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '2',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 275,
              y: 150,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '3',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 258.2,
              y: 212.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '4',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 212.5,
              y: 258.2,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '5',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 275,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '6',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 87.5,
              y: 258.2,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '7',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 41.7,
              y: 212.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '8',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 25,
              y: 150,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '9',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 41.7,
              y: 87.5,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '10',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 87.5,
              y: 41.7,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '11',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 25,
              fontSize: '30px',
              fillStyle: '#fff',
              text: '12',
              textAlign: 'center',
              textBaseline: 'middle',
            },
            {
              type: 'text',
              x: 150,
              y: 75,
              fontSize: '15px',
              fillStyle: '#000',
              text: 'Clock',
              textAlign: 'center',
              textBaseline: 'middle',
            },
          ],
          listeners: {
            afterRender: this.onDrawPanelIdAfterRender,
            spriteclick: this.onDrawPanelIdSpriteClick,
            boxready: function (item, width, height) {
              item.initWidth = width;
              item.initHeight = height;
            },
            resize: function (item, width, height, oldWidth, oldHeight) {
              if (arguments.length == 3) {
                // Looks like to be bug, fires twice with diferent number of arguments..
                return;
              }

              const scalingX = width / item.initWidth;
              const scalingY = height / item.initHeight;
              const proportionalScaling = Math.min(scalingX, scalingY);

              const items = item.getSurface().getItems();
              items.forEach((spriteItem) => {
                spriteItem.setAttributes({
                  scalingX: proportionalScaling,
                  scalingY: proportionalScaling,
                  scalingCenterX: proportionalScaling,
                  scalingCenterY: proportionalScaling,
                });
              });
            },
          },
        },
      ],
    }).show();

    setInterval(function () {
      window.setWidth(Math.ceil(100 + Math.random() * 400));
      window.setHeight(Math.ceil(100 + Math.random() * 400));
    }, 1000);
  },
  onDrawPanelIdAfterRender: function (item, event) {
    console.log('afterrender....');
  },
  onDrawPanelIdSpriteClick: function (item, event) {
    console.log('spriteclick....');
    var sprite = item && item.sprite;
    if (sprite) {
      sprite.setAttributes({
        fillStyle: 'red',
      });
      sprite.getSurface().renderFrame();
    }
  },
});