ExtJS, как заставить рисовать спрайты реагировать?

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

Вот демо: 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'
            },]

Установка ширины и высоты на 100% не будет работать.

Сейчас не отвечает:

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
184
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать обработчик события «изменить размер» и масштабировать все спрайты, как показано ниже (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.info('afterrender....');
  },
  onDrawPanelIdSpriteClick: function (item, event) {
    console.info('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.info('afterrender....');
  },
  onDrawPanelIdSpriteClick: function (item, event) {
    console.info('spriteclick....');
    var sprite = item && item.sprite;
    if (sprite) {
      sprite.setAttributes({
        fillStyle: 'red',
      });
      sprite.getSurface().renderFrame();
    }
  },
});

Несмотря на то, что это хорошо, есть ли способ сохранить соотношение и предотвратить масштабирование, растяжение? Значит, этот круг всегда круг?

Grasper 10.12.2020 14:43

@Grasper Да, вы можете использовать один параметр масштабирования, который будет рассчитываться на основе минимального значения ширины и высоты.

Arthur Rubens 10.12.2020 16:43

Можете ли вы обновить свой код, чтобы увидеть, что вы имеете в виду?

Grasper 10.12.2020 17:23

@Grasper Взгляните на второй образец.

Arthur Rubens 10.12.2020 19:16

Это обязательно должно быть в окне? Какой еще xtype может его удержать. У меня это внутри макета карты.

Grasper 10.12.2020 20:08

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

Arthur Rubens 10.12.2020 20:09

Извините, что беспокою вас, но я ошибся. У меня были неправильные ExtJ, выбранные в Fiddle. Я имел ввиду 7.2, современный(материальный). Кажется, ваше решение не работает для этой версии. Вы знаете, если что-то отсутствует?

Grasper 10.12.2020 21:35

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

Arthur Rubens 10.12.2020 22:51

Ну вот! fiddle.sencha.com/#fiddle/3ama&view/editor

Grasper 11.12.2020 15:35

Другие вопросы по теме