我正在尝试为我为Unveil.js(http://github.com/michael/unveil)实现的缩放和平移行为添加约束边界。启用边界后,您无法在场景边界外平移,并且zoomlevel(= scale)不应低于1.0。因此,如果您处于zoomlevel 1.0,则根本无法进行平移。
您可以在堆栈示例中看到未受约束的行为:dejavis.org/stacks。使用鼠标滚轮进行缩放。你可以将屏幕擦除屏幕或无限缩小它们,这应该避免。
真正难以解决的问题是,相对于鼠标指针进行缩放也会导致视口移动到位。因此在平移过程中检查边界是不够的。使用Mouswheel时我必须找到一种智能的缩放方式(不做脏跳)。在缩放图片时,Photoshop似乎已经解决了这个问题。
我完全不知道如何解决这个问题。很沮丧。 :/
我正在使用Matrix来存储重复操作的当前View转换。 这是缩放和平移行为的实现代码。
http://github.com/michael/unveil/blob/master/src/scene/behaviors.js
感谢您的任何想法。 :)
干杯,
迈克尔
答案 0 :(得分:2)
我之前的回答有点粗糙,我过于非正式地犯了一些愚蠢的错误。让我再试一次:))
所以你有一个3x3矩阵表示看起来像这样的视图转换(如果没有旋转):
[ sx 0 tx ]
viewMatrix = [ 0 sy tx ]
[ 0 0 1 ]
sx
和sy
代表缩放系数。即缩放参数。
tx
和ty
代表翻译。即平移参数。
(注意:您实际上可以在sx
之后的任何地方替换sy
和s
通过将其与齐次坐标中的点sx = sy
相乘,可以很容易地证明这一点。
p
现在,如果您可视化视口,其中心坐标将位于[ sx 0 tx ] [ px ] [ sx * px + tx ]
[ 0 sy tx ] * [ py ] = [ sy * py + ty ]
[ 0 0 1 ] [ 1 ] [ 1 ]
。
此外,如果画布大小为[-tx -ty]T
,则视口的大小将为(width, height)
(因为视口的大小与绘制的几何图形的比例成反比)。
(width/sx, height/sy)
当相对于锚点sx放大或缩小时,sy,tx和ty都将改变。 (如果你需要这个计算的帮助,只需添加一个评论,我会帮助。我有点忙: - ))
所以现在步骤很简单
_______________
| | ^
| . [-tx] | | height/sy
| [-ty] | |
|_______________| v
width/sx
<--------------->
如果视口边框与画布边界相交,请将视口转换为完全在视图中。可能大概是这样的:
s = max(s, 1.0); sx = sy = s
tx = clamp(tx, width * (1/sx - 1)/2, width * (1 - 1/sx)/2)
(最后检查我的数学结果。我匆忙做了:P)
答案 1 :(得分:0)
为什么不稍微重新解决问题(简单来说)?将视口存储为矩形,并通过变换该矩形来执行所有缩放/平移操作。当矩形越过边界时,只需将其夹在边界上即可。
然后只需从矩形大小和位置计算缩放和平移参数。
希望我理解你正确描述的问题。
(BAD)编辑:当缩放 out 时,您可能不仅想要夹住矩形。 如果矩形的边缘到达边界,则可以将正在缩放的“稳定点”(即通常是鼠标光标坐标)移动到边界上。然后只有相反的边缘会扩大。如果两条边相交,那么“稳定点”将位于拐角处,只有相对的角落会增长。即使一个或多个边缘被约束到边界,这也将使矩形按比例保持一致。
编辑:实际上最简单的方法是不要“夹住”视口的边缘,而只是将其平移直到边缘位于边界上。我以前的编辑有点傻:)。这也将保持纵横比固定,我肯定是你的意图。如果相对边缘触及边界,则只需停止缩放。