一千萬個為什麽

搜索

將畫布滾動為您正在移動的形狀接近其邊緣

我開發了一個基於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坐標來查看它是否接近邊緣。

我遇到的問題有點難以描述 - 基本上,如果你向左移動一個形狀,並停止移動它,如果你將形狀定位在離畫布50px的範圍內,那麽下次你去移動形狀,代碼說“好吧,這個形狀接近尾聲?”被觸發,畫布向左滾動,即使你將形狀向右移動也是如此。

誰能想到如何制止這個?我創建了 youtube video 來演示此問題。在大約0:54,我將一個多邊形移動到畫布的左側並將其定位在那裏。下次我移動它時,即使我正在向右移動,畫布也會向左滾動

我想添加的另一件事,但我堅持認為滾動獲得動力的形狀滾動的時間越長?因此,對於大型畫布,當您需要覆蓋2000px距離時,您不會移動多年的形狀,一次移動5px。有什麽建議嗎?

謝謝大家 - 抱歉超長問題!

最佳答案

這聽起來有點像象牙塔,我希望不是...... 如果您的算法不是基於位置而是基於矢量,那麽您可以註意到對象拖動的方向。一旦兩個位置(其中可以形成向量)可用,您的代碼就會啟動。然後你應該能夠弄清楚用戶是朝向還是遠離邊緣

有關矢量的更多內容:

由於您具有x,y坐標系,因此可以將這樣的矢量分解為x,y部分。取任意兩點(x1,y1)和(x2,y2),然後你可以想象一個矢量作為連接兩個點的線。那條線,例如x軸形成一個角度,告訴你該線指向的方向。在你的情況下,你會比較x2和x1。如果x2更大,則用戶向右移動。是y2大於y1它是移動到頂部和其他方向類似的比較...

轉載註明原文: 將畫布滾動為您正在移動的形狀接近其邊緣