Я пытаюсь реализовать функцию масштабирования для приложения, которое рисует фигуры на экране. Эти фигуры создаются в миллиметрах, преобразованных в пиксели, в зависимости от значения dpi.
Рисование выполняется в PictureBox, который размещается на панели, для которой включена истинная автопрокрутка.
Каждое масштабирование увеличивает размер PictureBox по горизонтали. и по вертикали.
Когда я увеличиваю масштаб с помощью прокрутки колеса мыши, вертикальная полоса прокрутки также перемещается, в то время как горизонтальная полоса прокрутки остается неизменной при прокрутке колеса.
По этой причине фигура остается в правильном положении на экран горизонтально, но вертикально он перемещается вниз шаг за шагом, прокрутка за прокруткой.
Поэтому мне нужна функция, которая компенсирует это движение.
Мой код выглядит примерно так:
private int deltaScroll = 0;
private float previousZoom;
private void viewport_MouseWheel(object sender, MouseEventArgs e)
{
mousePoint = viewport.PointToClient(Cursor.Position);
deltaScroll += e.Delta / 120;
if (e.Delta > 0)
{
ZoomIn();
}
else if (e.Delta < 0)
{
ZoomOut();
}
}
private void ZoomIn()
{
if (zoomFactor < 20.0f) // Prevent zooming in too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor += 0.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void ZoomOut()
{
if (zoomFactor > 0.21f) // Prevent zooming out too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor -= 0.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void CompensateScroll(float previousZoom, float newZoom)
{
int mouseX = viewport.HorizontalScroll.Value + mousePoint.X;
int mouseY = viewport.VerticalScroll.Value + mousePoint.Y;
// Calculate scaling factor
float scaleFactor = newZoom / previousZoom;
// Calculate new scroll deltas, applying the wheel delta to vertical scroll compensation
int deltaX = (int)((mouseX * scaleFactor) - mouseX);
int deltaY = (int)((mouseY * scaleFactor) - mouseY);
// Clamp new scroll values to stay within bounds
int newScrollX = MathExtensions.Clamp(viewport.HorizontalScroll.Value + deltaX, viewport.HorizontalScroll.Minimum, viewport.HorizontalScroll.Maximum);
int newScrollY = MathExtensions.Clamp(viewport.VerticalScroll.Value + deltaY, viewport.VerticalScroll.Minimum, viewport.VerticalScroll.Maximum);
// Apply adjusted scroll positions
viewport.AutoScrollPosition = new Point(newScrollX, newScrollY);
}
private void ApplyZoom()
{
foreach (var shape in shapes)
{
shape.ZoomFactor = zoomFactor;
}
double percentage = 100.0 * zoomFactor;
toolStripLabel2.Text = percentage.ToString("00") + "%";
SetPictureBoxSize(); // Set zoomed pictureBox size (width*zoomFactor, height*zoomFactor)
pictureBox1.Invalidate(); // Refresh
}
Похоже, следующий код работает очень близко к тому, что я хочу:
private int preZoomVerticalScroll;
private void viewport_MouseWheel(object sender, MouseEventArgs e)
{
mousePoint = viewport.PointToClient(Cursor.Position);
preZoomVerticalScroll = (int)(mousePoint.Y * (zoomFactor - 1));
if (ModifierKeys == Keys.Control)
{
if (e.Delta > 0)
{
ZoomIn();
}
else if (e.Delta < 0)
{
ZoomOut();
}
}
}
float previousZoom;
private void ZoomIn()
{
if (zoomFactor < 20.0f) // Prevent zooming in too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor *= 1.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void ZoomOut()
{
if (zoomFactor > 0.21f) // Prevent zooming out too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor /= 1.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void CompensateScroll(float previousZoom, float newZoom)
{
// Get the current scroll position (both X and Y)
int currentScrollX = viewport.HorizontalScroll.Value;
int currentScrollY = preZoomVerticalScroll;
// Get the mouse position relative to the viewport, including current scroll offsets
int mouseX = mousePoint.X + currentScrollX;
int mouseY = mousePoint.Y + currentScrollY;
// Calculate scale factors for X and Y axes based on zoom
float scaleFactor = newZoom / previousZoom;
// Calculate the deltas for both X and Y axes (how much the content should move after zoom)
int deltaX = (int)(mouseX * scaleFactor) - mouseX;
int deltaY = (int)(mouseY * scaleFactor) - mouseY;
// Adjust the scroll position based on the deltas, ensuring they stay within bounds
int newScrollX = MathExtensions.Clamp(currentScrollX + deltaX, viewport.HorizontalScroll.Minimum, viewport.HorizontalScroll.Maximum);
int newScrollY = MathExtensions.Clamp(currentScrollY + deltaY, viewport.VerticalScroll.Minimum, viewport.VerticalScroll.Maximum);
// Set the new scroll position for the viewport
viewport.AutoScrollPosition = new Point(newScrollX, newScrollY);
}
private void ApplyZoom()
{
foreach (var shape in shapes)
{
shape.ZoomFactor = zoomFactor;
}
double percentage = 100.0 * zoomFactor;
toolStripLabel2.Text = percentage.ToString("00") + "%";
SetPictureBoxSize(); // Set zoomed pictureBox size (width*zoomFactor, height*zoomFactor)
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... se-pointer
Масштабируйте и сохраняйте форму по центру указателя мыши. ⇐ C#
Место общения программистов C#
-
Anonymous
1735240585
Anonymous
Я пытаюсь реализовать функцию масштабирования для приложения, которое рисует фигуры на экране. Эти фигуры создаются в миллиметрах, преобразованных в пиксели, в зависимости от значения dpi.
Рисование выполняется в PictureBox, который размещается на панели, для которой включена истинная автопрокрутка.
Каждое масштабирование увеличивает размер PictureBox по горизонтали. и по вертикали.
Когда я увеличиваю масштаб с помощью прокрутки колеса мыши, вертикальная полоса прокрутки также перемещается, в то время как горизонтальная полоса прокрутки остается неизменной при прокрутке колеса.
По этой причине фигура остается в правильном положении на экран горизонтально, но вертикально он перемещается вниз шаг за шагом, прокрутка за прокруткой.
Поэтому мне нужна функция, которая компенсирует это движение.
Мой код выглядит примерно так:
private int deltaScroll = 0;
private float previousZoom;
private void viewport_MouseWheel(object sender, MouseEventArgs e)
{
mousePoint = viewport.PointToClient(Cursor.Position);
deltaScroll += e.Delta / 120;
if (e.Delta > 0)
{
ZoomIn();
}
else if (e.Delta < 0)
{
ZoomOut();
}
}
private void ZoomIn()
{
if (zoomFactor < 20.0f) // Prevent zooming in too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor += 0.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void ZoomOut()
{
if (zoomFactor > 0.21f) // Prevent zooming out too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor -= 0.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void CompensateScroll(float previousZoom, float newZoom)
{
int mouseX = viewport.HorizontalScroll.Value + mousePoint.X;
int mouseY = viewport.VerticalScroll.Value + mousePoint.Y;
// Calculate scaling factor
float scaleFactor = newZoom / previousZoom;
// Calculate new scroll deltas, applying the wheel delta to vertical scroll compensation
int deltaX = (int)((mouseX * scaleFactor) - mouseX);
int deltaY = (int)((mouseY * scaleFactor) - mouseY);
// Clamp new scroll values to stay within bounds
int newScrollX = MathExtensions.Clamp(viewport.HorizontalScroll.Value + deltaX, viewport.HorizontalScroll.Minimum, viewport.HorizontalScroll.Maximum);
int newScrollY = MathExtensions.Clamp(viewport.VerticalScroll.Value + deltaY, viewport.VerticalScroll.Minimum, viewport.VerticalScroll.Maximum);
// Apply adjusted scroll positions
viewport.AutoScrollPosition = new Point(newScrollX, newScrollY);
}
private void ApplyZoom()
{
foreach (var shape in shapes)
{
shape.ZoomFactor = zoomFactor;
}
double percentage = 100.0 * zoomFactor;
toolStripLabel2.Text = percentage.ToString("00") + "%";
SetPictureBoxSize(); // Set zoomed pictureBox size (width*zoomFactor, height*zoomFactor)
pictureBox1.Invalidate(); // Refresh
}
Похоже, следующий код работает очень близко к тому, что я хочу:
private int preZoomVerticalScroll;
private void viewport_MouseWheel(object sender, MouseEventArgs e)
{
mousePoint = viewport.PointToClient(Cursor.Position);
preZoomVerticalScroll = (int)(mousePoint.Y * (zoomFactor - 1));
if (ModifierKeys == Keys.Control)
{
if (e.Delta > 0)
{
ZoomIn();
}
else if (e.Delta < 0)
{
ZoomOut();
}
}
}
float previousZoom;
private void ZoomIn()
{
if (zoomFactor < 20.0f) // Prevent zooming in too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor *= 1.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void ZoomOut()
{
if (zoomFactor > 0.21f) // Prevent zooming out too much
{
previousZoom = zoomFactor; // Store the old zoom factor
zoomFactor /= 1.2f;
ApplyZoom();
// Calculate and apply scroll offsets
CompensateScroll(previousZoom, zoomFactor);
}
}
private void CompensateScroll(float previousZoom, float newZoom)
{
// Get the current scroll position (both X and Y)
int currentScrollX = viewport.HorizontalScroll.Value;
int currentScrollY = preZoomVerticalScroll;
// Get the mouse position relative to the viewport, including current scroll offsets
int mouseX = mousePoint.X + currentScrollX;
int mouseY = mousePoint.Y + currentScrollY;
// Calculate scale factors for X and Y axes based on zoom
float scaleFactor = newZoom / previousZoom;
// Calculate the deltas for both X and Y axes (how much the content should move after zoom)
int deltaX = (int)(mouseX * scaleFactor) - mouseX;
int deltaY = (int)(mouseY * scaleFactor) - mouseY;
// Adjust the scroll position based on the deltas, ensuring they stay within bounds
int newScrollX = MathExtensions.Clamp(currentScrollX + deltaX, viewport.HorizontalScroll.Minimum, viewport.HorizontalScroll.Maximum);
int newScrollY = MathExtensions.Clamp(currentScrollY + deltaY, viewport.VerticalScroll.Minimum, viewport.VerticalScroll.Maximum);
// Set the new scroll position for the viewport
viewport.AutoScrollPosition = new Point(newScrollX, newScrollY);
}
private void ApplyZoom()
{
foreach (var shape in shapes)
{
shape.ZoomFactor = zoomFactor;
}
double percentage = 100.0 * zoomFactor;
toolStripLabel2.Text = percentage.ToString("00") + "%";
SetPictureBoxSize(); // Set zoomed pictureBox size (width*zoomFactor, height*zoomFactor)
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79299670/zoom-and-keep-shape-centered-at-mouse-pointer[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия