2016-04-02 7 views
5

इससे पहले कि आप सोचें कि "यह आदमी इस समस्या पर मदद क्यों मांग रहा है, निश्चित रूप से यह 1000x लागू किया गया है" - जबकि आप अधिकतर सही हैं, मैंने इस समस्या को कई खुले के साथ हल करने का प्रयास किया है स्रोत libs अभी तक मैं हूँ।एसवीजी माउस पर ज़ूम इन करें - गणितीय मॉडल

मैं एक एसवीजी आधारित "माउस व्हील पर ज़ूम इन, माउस पर ध्यान केंद्रित" को लागू करने का प्रयास कर रहा हूं।

मुझे पता है कि कई पुस्तकालय हैं जो इसे पूरा करते हैं, डी 3 और एसवीजी-पैन-ज़ूम को दो नाम देने के लिए। दुर्भाग्य से, उन libs का उपयोग कर मेरे कार्यान्वयन मेरी उम्मीदों से कम गिर रहे हैं। मैं उम्मीद कर रहा था कि इस प्रकार की यूआई सुविधा के लिए अंतर्निहित गणितीय मॉडल के साथ समुदाय से मुझे कुछ मदद मिल सकती है।

असल में, वांछित व्यवहार Google मानचित्र की तरह है, उपयोगकर्ता का माउस उनके स्थान पर होवर करता है, वे माउस व्हील (अंदरूनी) को स्क्रॉल करते हैं, और नक्शा छवि के पैमाने को बढ़ाता है, जबकि स्थान पर आच्छादित हो जाता है व्यूपोर्ट का क्षैतिज और ऊर्ध्वाधर केंद्र।

स्वाभाविक रूप से, मेरे पास व्यूपोर्ट की चौड़ाई/ऊंचाई और माउस के एक्स/वाई तक पहुंच है।

इस उदाहरण में, मैं सिर्फ एक्स अक्ष पर ध्यान दिया जाएगा, व्यूपोर्ट 900 इकाइयों व्यापक है, वर्ग 100 इकाइयों विस्तृत है, यह एक्स ऑफसेट है 400 इकाइयों है, और बड़े पैमाने 1: 1

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

enter image description here

माउस एक्स स्थिति मान लिया जाये पर या 450 इकाइयों के पास थी, अगर में जब तक पैमाने पर पहुंच गया 2 एक उपयोगकर्ता पहियों: 1, मैं करूंगा उम्मीद एक्स -450 इकाइयों तक पहुँचने के लिए ऑफसेट, इसलिए की तरह ध्यान केंद्रित करने की बात केंद्रित ।

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

enter image description here

x और y ऑफसेट वर्तमान पैमाने/माउस ऑफसेट के एक समारोह के रूप में पहिया स्क्रॉल में से प्रत्येक के वेतन वृद्धि पर पुनर्गणना की जरूरत है।

मेरे सभी प्रयास वांछित व्यवहार से पूरी तरह से कम हो गए हैं, किसी भी सलाह की सराहना की जाती है।

जबकि मैं किसी भी मदद की सराहना करता हूं, कृपया सुझावों के साथ तीसरे पक्ष के पुस्तकालयों, jQuery प्लगइन्स और उस प्रकृति की चीजों के जवाब देने से बचें। मेरा उद्देश्य यहां एक सामान्य अर्थ में इस समस्या के पीछे गणितीय मॉडल को समझना है, एसवीजी का मेरा उपयोग मुख्य रूप से चित्रकारी है।

उत्तर

5

मैं आमतौर पर जो करता हूं वह है कि मैं तीन परिवर्तनीय ऑफ़सेट एक्स ऑफसेट वाई और स्केल बनाए रखता हूं। उन्हें एक कंटेनर समूह में बदलने के रूप में लागू किया जाएगा, जैसे आपके तत्व <g transform="translate(0 0) scale(1)">

यदि माउस उत्पत्ति पर होगा तो नया अनुवाद गणना करने के लिए तुच्छ होगा। तुम बस पैमाने में अंतर की भरपाई x और y गुणा करते हैं:

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

क्या तुम कर सकते हो का अनुवाद ऑफसेट ताकि माउस मूल में है। फिर आप स्केल करते हैं और फिर आप हर चीज़ का अनुवाद करते हैं।इस टाइपप्रति वर्ग सिर्फ करने के लिए एक scaleRelativeTo विधि है पर एक नज़र डालें आप क्या चाहते हैं:

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); 
    } 

    } 

दी बदलने दे दिया है translate(offsetX,offsetY) scale(scale) द्वारा और एक स्क्रॉल घटना एक नए पैमाने के लिए अग्रणी (mouseX, mouseY) में हुई तो अगर newScale आप नए ट्रांसफॉर्म की गणना करेगा:

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

अंत में, बस सुंदर - धन्यवाद – James

संबंधित मुद्दे