Как я могу использовать смещение и масштаб, чтобы в Konva всегда была полностью видна ограничивающая рамка? - PullRequest
0 голосов
/ 18 февраля 2019

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

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

Я могу сделать это для положительно масштабированного графика, согласно этому фрагменту:

const points = [
  [0, 0],
  [100, 50],
  [200, 200],
  [-100, -100],
  [-50, -50]
];

const xCoords = points.map(p => p[0])
const yCoords = points.map(p => p[1])

const boundingBox = {
  x1: Math.min(...xCoords),
  x2: Math.max(...xCoords),
  y1: Math.min(...yCoords),
  y2: Math.max(...yCoords),
};

const actualWidth = window.innerWidth * 0.75;
const actualHeight = window.innerHeight * 0.75;
const canvasWidth = boundingBox.x2 - boundingBox.x1;
const canvasHeight = boundingBox.y2 - boundingBox.y1;

const scale = Math.min(
  actualWidth / canvasWidth,
  actualHeight / canvasHeight
);

const stage = new Konva.Stage({
  container: 'container',
  width: canvasWidth,
  height: canvasHeight,
  scale: {
    x: scale,
    y: scale,
  },
  offset: {
    x: boundingBox.x1,
    y: boundingBox.y1,
  }
});

const layer = new Konva.Layer();

points.forEach(point => {
  const rect = new Konva.Rect({
    x: point[0],
    y: point[1],
    width: 10,
    height: 10,
    fill: point.every(v => v === 0) ?
      'red' : 'green',
  });

  const text = new Konva.Text({
    x: point[0],
    y: point[1],
    text: `    (${point[0]}, ${point[1]})`,
    fill: 'black',
    fontSize: 30,
    fontFamily: 'Calibri',
  });

  layer.add(rect);
  layer.add(text);
})

stage.add(layer);
body {
  font-family: arial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.js"></script>
<div id='container'></div>

Однако, когда я переворачиваю шкалу на отрицательную величину, у меня возникают трудности с отображением точек на холсте.,Ниже я привел пример того, что я пробовал.Возможно, я поступаю совершенно неправильно, но буду благодарен, если кто-нибудь укажет мне правильное направление.

const points = [
  [0, 0],
  [100, 50],
  [200, 200],
  [-100, -100],
  [-50, -50]
];

const xCoords = points.map(p => p[0])
const yCoords = points.map(p => p[1])

const boundingBox = {
  x1: Math.min(...xCoords),
  x2: Math.max(...xCoords),
  y1: Math.min(...yCoords),
  y2: Math.max(...yCoords),
};

const actualWidth = window.innerWidth * 0.75;
const actualHeight = window.innerHeight * 0.75;
const canvasWidth = boundingBox.x2 - boundingBox.x1;
const canvasHeight = boundingBox.y2 - boundingBox.y1;

const scale = Math.min(
  actualWidth / canvasWidth,
  actualHeight / canvasHeight
);

const stage = new Konva.Stage({
  container: 'container',
  width: canvasWidth,
  height: canvasHeight,
  scale: {
    x: -scale,
    y: scale,
  },
  offset: {
    x: boundingBox.x1 - canvasWidth,
    y: boundingBox.y1,
  }
});

const layer = new Konva.Layer();

points.forEach(point => {
  const rect = new Konva.Rect({
    x: point[0],
    y: point[1],
    width: 10,
    height: 10,
    fill: point.every(v => v === 0) ?
      'red' : 'green',
  });

  const text = new Konva.Text({
    x: point[0],
    y: point[1],
    text: `    (${point[0]}, ${point[1]})`,
    fill: 'black',
    fontSize: 30,
    fontFamily: 'Calibri',
  });

  layer.add(rect);
  layer.add(text);
})

stage.add(layer);
body {
  font-family: arial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.js"></script>
<div id='container'></div>

1 Ответ

0 голосов
/ 18 февраля 2019

Я решил эту проблему, изменив смещение на:

x: boundingBox.x1 + canvasWidth

Что, похоже, во всех случаях решает проблему.

const points = [
  [0, 0],
  [100, 50],
  [200, 200],
  [-100, -100],
  [-50, -50]
];

const xCoords = points.map(p => p[0])
const yCoords = points.map(p => p[1])

const boundingBox = {
  x1: Math.min(...xCoords),
  x2: Math.max(...xCoords),
  y1: Math.min(...yCoords),
  y2: Math.max(...yCoords),
};

const actualWidth = window.innerWidth * 0.75;
const actualHeight = window.innerHeight * 0.75;
const canvasWidth = boundingBox.x2 - boundingBox.x1;
const canvasHeight = boundingBox.y2 - boundingBox.y1;

const scale = Math.min(
  actualWidth / canvasWidth,
  actualHeight / canvasHeight
);

const stage = new Konva.Stage({
  container: 'container',
  width: canvasWidth,
  height: canvasHeight,
  scale: {
    x: -scale,
    y: scale,
  },
  offset: {
    x: boundingBox.x1 + canvasWidth,
    y: boundingBox.y1,
  }
});

const layer = new Konva.Layer();

points.forEach(point => {
  const rect = new Konva.Rect({
    x: point[0],
    y: point[1],
    width: 10,
    height: 10,
    fill: point.every(v => v === 0) ?
      'red' : 'green',
  });

  const text = new Konva.Text({
    x: point[0],
    y: point[1],
    text: `    (${point[0]}, ${point[1]})`,
    fill: 'black',
    fontSize: 30,
    fontFamily: 'Calibri',
  });

  layer.add(rect);
  layer.add(text);
})

stage.add(layer);
body {
  font-family: arial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.js"></script>
<div id='container'></div>
...