У меня есть изображение из спрайтов. Я пытаюсь сделать его отзывчивым, поэтому, когда я изменяю размер своего браузера, изображение также изменяется для небольших устройств и их экранов.
Вот демо: 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% не будет работать.
Сейчас не отвечает:
Вы можете использовать обработчик события «изменить размер» и масштабировать все спрайты, как показано ниже (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 Да, вы можете использовать один параметр масштабирования, который будет рассчитываться на основе минимального значения ширины и высоты.
Можете ли вы обновить свой код, чтобы увидеть, что вы имеете в виду?
@Grasper Взгляните на второй образец.
Это обязательно должно быть в окне? Какой еще xtype может его удержать. У меня это внутри макета карты.
Я использовал окно для изменения размера холста. Вы можете использовать любой элемент упаковки, чтобы изменить его размер.
Извините, что беспокою вас, но я ошибся. У меня были неправильные ExtJ, выбранные в Fiddle. Я имел ввиду 7.2, современный(материальный). Кажется, ваше решение не работает для этой версии. Вы знаете, если что-то отсутствует?
Хорошо, тогда открывайте новую тему с новым вопросом и не забудьте описать его получше.
Ну вот! fiddle.sencha.com/#fiddle/3ama&view/editor
Несмотря на то, что это хорошо, есть ли способ сохранить соотношение и предотвратить масштабирование, растяжение? Значит, этот круг всегда круг?