Reputation: 13
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