मैंने 4x ज़ूम गति रखने के लिए mbostock के drag+zoom example को संशोधित किया है और इसेमें रखा है 210। मैंने नीचे अपनी सोच समझाई है। यह एक स्टैक ओवरफ़्लो उत्तर पर मेरा पहला प्रयास है, कृपया अच्छा रहें।
जैसा कि राउल मार्टिन के उत्तर में बताया गया है, आप ज़ूम की दर बदलने के लिए redraw()
फ़ंक्शन के भीतर एक सूत्र का उपयोग कर सकते हैं। आपको यह सुनिश्चित करने के लिए कुछ अतिरिक्त कदम उठाने होंगे कि डी 3 व्यवहार अभी भी संशोधित ज़ूम दर के साथ अच्छी तरह से काम करता है।
ज़ूम (जैसे कर्सर) एक चुने हुए बिंदु पर केंद्रित
डिफ़ॉल्ट d3 व्यवहार करके माउस सूचक पर, उदाहरण के लिए ज़ूम केंद्रित अगर आपके पास छवि के ऊपरी बाईं ओर माउस पॉइंटर है तो यह छवि के केंद्र की बजाय ऊपरी बाईं ओर ज़ूम करता है। इस प्रभाव को प्राप्त करने के लिए यह छवि को स्केल करता है और फिर छवि के अनुवाद को भी बदलता है ताकि माउस कर्सर के नीचे बिंदु स्क्रीन पर एक ही स्थान पर रहता है। यही कारण है कि जब आप mousewheel स्क्रॉल करते हैं तो zoom.translate()
का मान बदलता है, भले ही छवि ऐसा दिखाई न दे, यह स्क्रीन पर आगे बढ़ रहा है।
यदि आप ज़ूम गति बदलते हैं तो d3 zoom.translate()
मान अब सही नहीं हैं। तो
var prev_translate = [100,100] // x, y translation of the image in last redraw
var prev_scale = 0.1 // Scale applied to the image last redraw
var new_scale = 0.4 // The new scale being applied
var zoom_cp = [150, 150] // The zoom "center point" e.g. mouse pointer
सूत्र new_translate
बाहर काम करने के छवि के लिए लागू करने के लिए किया गया है:: सही अनुवाद बाहर काम करने के लिए आप निम्नलिखित जानकारी (संख्यात्मक मान ध्यान न दें) पता करने की जरूरत
new_translate[0] = zoom_cp[0] - (zoom_cp[0] - prev_translate[0])
* new_scale/prev_scale;
new_translate[1] = zoom_cp[1] - (zoom_cp[1] - prev_translate[1])
* new_scale/prev_scale;
आप के साथ अपने नए पैमाने के साथ छवि के लिए लागू कर सकते हैं:
svg.attr("transform", "translate(" + new_translate + ")scale(" + new_scale + ")");
फिर आप अद्यतन करने के लिए prev_scale = new_scale
और prev_translate = new_translate
के लिए तैयार होगा
d3 ज़ूम व्यवहार स्केलिंग के बिना redraw()
पान की अगले चरण आप क्लिक करके और खींचकर स्केलिंग के बिना पैन करने के लिए अनुमति देता है। यदि आप क्लिक करते हैं और खींचते हैं तो zoom.scale()
वही रहता है लेकिन zoom.translate()
परिवर्तन रहता है। ज़ूम गति को संशोधित करने के बाद भी नया zoom.translate()
मान अभी भी सही है। हालांकि, आपको यह जानने की आवश्यकता है कि इस zoom.translate()
मान का उपयोग कब करें और उस अनुवाद मूल्य का उपयोग कब करें जब आप केंद्र बिंदु पर ज़ूम करने के लिए गणना करते हैं।
new scale
जैसा ही है या नहीं, यह देखकर आप काम कर सकते हैं कि पैन या ज़ूम हो रहा है या नहीं। यदि दो मान समान हैं तो आप जानते हैं कि एक पैन हो रहा है और आप छवि को स्थानांतरित करने के लिए new_translate = zoom.translate()
का उपयोग कर सकते हैं। अन्यथा, आप जानते हैं कि ज़ूम हो रहा है और आप ऊपर वर्णित अनुसार new_translate
मान की गणना कर सकते हैं। मैं zoomstart
ईवेंट में एक फ़ंक्शन जोड़ कर ऐसा करता हूं।
var zoom_type = "?";
var scale_grad = 4; // Zoom speed multiple
var intercept = 1 * (1 - scale_grad)
var svg = d3.select("body").append("svg:svg")
.attr("width", 1000)
.attr("height", 2000)
.append("svg:g")
.call(d3.behavior.zoom()
.on("zoom", redraw)
.on("zoomstart", zoomstarted))
.append("svg:g");
function zoomstarted() {
zoom_type = "?";
}
function redraw() {
var scale = d3.event.scale;
// Use a linear scale, don't let it go below the minimum scale
// extent
var new_scale = Math.max(scale_grad * scale + intercept,
scale_extent[0]);
// If hit the minimum scale extent then stop d3 zoom from
// going any further
if (new_scale == scale_extent[0]) {
zoom.scale((scale_extent[0] - intercept)/scale_grad);
}
// Set up zoom_type if have just started
// If the scale hasn't changed then a pure translation is
// taking place, otherwise it is a scale
if (zoom_type == "?") {
if (new_scale == prev_scale) {
zoom_type = "translate"
} else {
zoom_type = "scale"
}
}
// zoom_cp is the static point during the zoom, set as
// mouse pointer position (you need to define a listener to track)
var new_translate = [0, 0];
zoom_cp = [mouse_x, mouse_y];
// If the event is a translate just apply d3 translate
// Otherwise calculate what translation is required to
// keep the zoom center point static
if (zoom_type == "translate") {
new_translate = d3.event.translate
} else if (zoom_type == "scale") {
new_translate[0] = zoom_cp[0]
- (zoom_cp[0] - prev_translate[0]) * new_scale/prev_scale;
new_translate[1] = zoom_cp[1]
- (zoom_cp[1] - prev_translate[1]) * new_scale/prev_scale;
}
// Update the variables that track the last iteration of the
// zoom
prev_translate = new_translate;
prev_scale = new_scale;
zoom.translate(new_translate);
// Apply scale and translate behaviour
svg.attr("transform", "translate(" + new_translate +
")scale(" + new_scale + ")");
}
क्या आपने इसे समझ लिया? – kishanio
@ किशनानियो मैंने एक समाधान का प्रस्ताव दिया –