2016-04-02 18 views
5

Trước khi bạn nghĩ "tại sao người này yêu cầu trợ giúp về vấn đề này, chắc chắn điều này đã được triển khai 1000x" - trong khi bạn chủ yếu là chính xác, tôi đã cố gắng giải quyết vấn đề này nguồn libs ở đây tôi.SVG phóng to trên chuột - mô hình toán học

Tôi đang cố triển khai SVG dựa trên "phóng to trên con lăn chuột, tập trung vào chuột" từ đầu.

Tôi biết có nhiều thư viện thực hiện việc này, d3 và svg-pan-zoom để đặt tên cho một cặp vợ chồng. Thật không may, triển khai của tôi bằng cách sử dụng những libs đang giảm ngắn mong đợi của tôi. Tôi đã hy vọng rằng tôi có thể nhận được một số trợ giúp từ cộng đồng với mô hình toán học cơ bản cho loại tính năng giao diện người dùng này. Về cơ bản, hành vi mong muốn giống như Google Maps, người dùng di chuột qua vị trí, họ di chuyển con lăn chuột (vào trong) và tỷ lệ của hình ảnh bản đồ tăng lên, trong khi vị trí được di chuột qua trở thành trung tâm ngang và dọc của chế độ xem.

Đương nhiên, tôi có quyền truy cập vào chiều rộng/chiều cao của chế độ xem và x/y của chuột.

Trong ví dụ này, tôi sẽ chỉ tập trung vào các trục x, khung nhìn rộng 900 đơn vị, quảng trường rộng 100 đơn vị, đó là x bù là 400 đơn vị, và quy mô là 1: 1

<g transform="translate(0 0) scale(1)"> 

enter image description here

Giả sử các vị trí chuột x là tại hoặc gần 450 đơn vị, nếu một bánh xe sử dụng cho đến khi quy mô đạt 2: 1, tôi sẽ mong đợi x bù đắp để đạt -450 đơn vị, tập trung các điểm tập trung như vậy .

<g transform="translate(-450 0) scale(2)"> 

enter image description here

x và y offsets cần phải được tính toán lại trên mỗi increment của bánh xe di chuyển như một chức năng của offsets quy mô/chuột hiện tại.

Tất cả các nỗ lực của tôi đã giảm hoàn toàn thiếu hành vi mong muốn, mọi lời khuyên đều được đánh giá cao.

Mặc dù tôi đánh giá cao bất kỳ trợ giúp nào, vui lòng không trả lời với các đề xuất cho thư viện của bên thứ ba, plugin jQuery và những thứ có tính chất đó. Mục tiêu của tôi ở đây là hiểu mô hình toán học đằng sau vấn đề này theo nghĩa chung, việc sử dụng SVG của tôi chủ yếu là minh họa.

Trả lời

5

Những gì tôi thường làm là tôi duy trì ba biến bù đắp x bù đắp y và tỷ lệ. Chúng sẽ được áp dụng dưới dạng biến đổi thành nhóm vùng chứa, như phần tử của bạn <g transform="translate(0 0) scale(1)">.

Nếu chuột ở trên gốc, bản dịch mới sẽ không đáng kể để tính toán. Bạn chỉ nhân số chênh lệch x và y với sự khác biệt về tỷ lệ:

offsetX = offsetX * newScale/scale 
offsetY = offsetY * newScale/scale 

Điều bạn có thể làm là dịch bù để chuột ở gốc. Sau đó, bạn quy mô và sau đó bạn dịch mọi thứ trở lại.Hãy nhìn vào lớp nguyên cảo này mà có một phương pháp scaleRelativeTo để làm những gì bạn muốn:

export class Point implements Interfaces.IPoint { 
    x: number; 
    y: number; 

    public constructor(x: number, y: number) { 
     this.x = x; 
     this.y = y; 
    } 

    add(p: Interfaces.IPoint): Point { 
     return new Point(this.x + p.x, this.y + p.y); 
    } 

    snapTo(gridX: number, gridY: number): Point { 
     var x = Math.round(this.x/gridX) * gridX; 
     var y = Math.round(this.y/gridY) * gridY; 
     return new Point(x, y); 
    } 

    scale(factor: number): Point { 
     return new Point(this.x * factor, this.y * factor); 
    } 

    scaleRelativeTo(point: Interfaces.IPoint, factor: number): Point { 

     return this.subtract(point).scale(factor).add(point); 
    } 

    subtract(p: Interfaces.IPoint): Point { 
     return new Point(this.x - p.x, this.y - p.y); 
    } 

    } 

Vì vậy, nếu bạn đã cho biến đổi do translate(offsetX,offsetY) scale(scale) và một sự kiện cuộn diễn ra tại (mouseX, mouseY) dẫn đến một quy mô mới newScale bạn sẽ tính toán biến đổi mới theo:

offsetX = (offsetX - mouseX) * newScale/scale + mouseX 
offsetY = (offsetY - mouseY) * newScale/scale + mouseY 
+0

Có kết thúc, chỉ đẹp - cảm ơn bạn – James

Các vấn đề liên quan