Я разрабатываю программу для рисования на основе Python, Whyteboard . У меня есть инструменты, которые пользователь может создавать новые формы на холсте, такие как текст / изображения / прямоугольники / круги / многоугольники. У меня также есть инструмент «Выбор», который позволяет пользователям изменять эти фигуры - например, перемещать позицию фигуры, изменять ее размер или редактировать позиции точек многоугольника.
Я добавляю новую функцию, в которой перемещение или изменение размера точки около края холста автоматически прокручивает холст. Я думаю, что это хорошая идея с точки зрения удобства использования программы, и меня раздражает, когда другие программы не имеют этой функции.
Я добился хорошего прогресса в кодировании этого; ниже приведен код Python для демонстрации того, что я делаю. Эти функции демонстрируют, как некоторые фигуры вычисляют свои «ребра»:
def find_edges(self):
"""A line."""
self.edges = {EDGE_TOP: min(self.y, self.y2), EDGE_RIGHT: max(self.x, self.x2),
EDGE_BOTTOM: max(self.y, self.y2), EDGE_LEFT: min(self. x, self.x2)}
def find_edges(self):
"""An image"""
self.edges = {EDGE_TOP: self.y, EDGE_RIGHT: self.x + self.image.GetWidth(),
EDGE_BOTTOM: self.y + self.image.GetWidth(), EDGE_LEFT: self.x}
def find_edges(self):
"""Get the bounding rectangle for the polygon"""
xmin = min(x for x, y in self.points)
ymin = min(y for x, y in self.points)
xmax = max(x for x, y in self.points)
ymax = max(y for x, y in self.points)
self.edges = {EDGE_TOP: ymin, EDGE_RIGHT: xmax, EDGE_BOTTOM: ymax, EDGE_LEFT: xmin}
А вот код, который у меня есть для реализации прокрутки, когда форма приближается к краю:
def check_canvas_scroll(self, x, y, moving=False):
"""
We check that the x/y coords are within 50px from the edge of the canvas
and scroll the canvas accordingly. If the shape is being moved, we need
to check specific edges of the shape (e.g. left/right side of rectangle)
"""
size = self.board.GetClientSizeTuple() # visible area of the canvas
if not self.board.area > size: # canvas is too small to need to scroll
return
start = self.board.GetViewStart() # user's starting "viewport"
scroll = (-1, -1) # -1 means no change
if moving:
if self.shape.edges[EDGE_RIGHT] > start[0] + size[0] - 50:
scroll = (start[0] + 5, -1)
if self.shape.edges[EDGE_BOTTOM] > start[1] + size[1] - 50:
scroll = (-1, start[1] + 5)
# snip others
else:
if x > start[0] + size[0] - 50:
scroll = (start[0] + 5, -1)
if y > start[1] + size[1] - 50:
scroll = (-1, start[1] + 5)
# snip others
self.board.Scroll(*scroll)
Этот код на самом деле работает довольно хорошо. Если мы перемещаем фигуру, то нам нужно знать ее края, чтобы вычислить, когда они приближаются к краю холста. Если мы изменяем размер только одной точки, мы просто используем координаты x / y этой точки, чтобы увидеть, находится ли она близко к краю.
Проблема, которую я имею, немного сложна для описания - в основном, если вы переместите фигуру влево и перестанете ее перемещать, если вы поместили фигуру в пределах 50 пикселей от холста, то в следующий раз чтобы переместить форму, код, который говорит: «Хорошо, эта форма близка к концу?» срабатывает, и холст прокручивается влево, даже если вы перемещаете фигуру вправо.
Кто-нибудь может подумать, как это остановить? Я создал видео на YouTube , чтобы продемонстрировать проблему. Примерно в 0:54 я перемещаю многоугольник слева от холста и размещаю его там. В следующий раз, когда я переместлю его, холст прокручивается влево, хотя я и перемещаю его вправо
Еще одна вещь, которую я хотел бы добавить, но я застрял на том, набирает ли скорость прокрутка, чем дольше прокручивается фигура? Таким образом, с большим холстом вы не перемещаете фигуру целую вечность, перемещаясь на 5 пикселей за раз, когда вам нужно преодолеть расстояние в 2000 пикселей. Есть предложения?
Спасибо всем - простите за супер длинный вопрос!