user21199884
user21199884

Reputation: 13

How can the lateral movement be tracked by tkinters canvas.scale function?

I'm trying to figure out how the scale canvas.scale(tag, x, y, ds, ds) method works in the Tkinter canvas package. It is possible to move elements on the canvas without using the corresponding move canvas.move(tag, dx, dy) method.

So how is the lateral movement changed by the scale method? I want to keep track off this through the line self.coffset = . If you scroll to the corners of the rectangle, the offset should be 0,0, 0,40, 40,0 or 40,40 depending of which corner you scroll to. Note that this is functioning before you scroll by click dragging around. As soon as you scroll, the offset is no longer correct.

import tkinter as tk

class moveScale(tk.Tk):

    def __init__(self):
        super().__init__()

        self.canvas = tk.Canvas(
            self, highlightthickness = 0, borderwidth = 0,
            cursor = "crosshair")
        self.canvas.pack(fill = "both", expand = True)

        # Store for dynamic mouse pointer position
        self.xx = self.yy = 0
        self.coffset, self.cscale = (0, 0), 1

        self.canvas.create_rectangle(0, 0, 40, 40, fill = "")

        # Mouse bindings
        self.bind("<Motion>", self.motion)
        self.bind("<B1-Motion>", self.mover)
        self.bind("<MouseWheel>", self.scaler)

    def motion(self, ev):
        self.xx, self.yy = ev.x, ev.y

    def mover(self, ev):
        dx, dy = ev.x - self.xx, ev.y - self.yy
        self.xx, self.yy = ev.x, ev.y
        self.move("all", dx, dy)

    def move(self, tag, dx, dy):
        self.canvas.move(tag, dx, dy)
        cs = self.cscale
        self.coffset = (self.coffset[0] + dx * cs, self.coffset[1] + dy * cs)
        self.updatetitle()

    def scaler(self, ev):
        if ev.delta > 0:
            ds = 1.1
        else:
            ds = 0.9
        self.scale("all", ev.x, ev.y, ds)

    def scale(self, tag, x, y, ds):
        self.canvas.scale(tag, x, y, ds, ds)
        self.cscale *= ds
        # TODO:
        self.coffset = 
        self.updatetitle()

    def updatetitle(self):
        self.title(f"Offset: {self.coffset}, Scale: {self.cscale}")

main = moveScale()
main.updatetitle()
main.mainloop()

In the documentation I found this:

.scale(tagOrId, xOffset, yOffset, xScale, yScale) Scale all objects according to their distance from a point P=(xOffset, yOffset). The scale factors xScale and yScale are based on a value of 1.0, which means no scaling. Every point in the objects selected by tagOrId is moved so that its x distance from P is multiplied by xScale and its y distance is multiplied by yScale.

This method will not change the size of a text item, but may move it.

Based on this I would have expected

canvas.scale(tag, x,y,ds,ds)

to change the offset like

(self.coffset[0] * ds, self.coffset[1] * ds) this.

With

px, py = self.coffset self.coffset = (x + (px - x) * ds, y + (py - y) * ds)

or

self.coffset = (px + (ds - 1) * (px - x), py + (ds - 1) * (py - y))

It doesn't work.

Upvotes: 0

Views: 165

Answers (0)

Related Questions