svg - एसवीजी में ट्रांसफॉर्म उत्पत्ति कैसे सेट करें




coordinate-transformation (4)

उपयोग transform="rotate(deg, cx, cy)" घुमाने के लिए, जहां डिग्री वह डिग्री है जिसे आप घूमना चाहते हैं और (सीएक्स, साइ) घूर्णन के केंद्र को परिभाषित करता है।

स्केलिंग / आकार बदलने के लिए, आपको (-cx, -cy) द्वारा अनुवाद करना होगा, फिर स्केल करें और फिर वापस अनुवाद करें (सीएक्स, साइ)। आप इसे मैट्रिक्स ट्रांसफॉर्म के साथ कर सकते हैं:

transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"

जहां एसएक्स एक्स-अक्ष में स्केलिंग कारक है, वाई-अक्ष में sy।

मुझे जावास्क्रिप्ट का उपयोग करके एसवीजी दस्तावेज़ में कुछ तत्वों का आकार बदलने और घुमाए जाने की आवश्यकता है। समस्या डिफ़ॉल्ट रूप से है, यह हमेशा मूल के चारों ओर परिवर्तन (0, 0) - शीर्ष बाईं ओर लागू होती है।

मैं इस ट्रांसफॉर्म एंकर पॉइंट को फिर से परिभाषित कैसे कर सकता हूं?

मैंने transform-origin विशेषता का उपयोग करने का प्रयास किया, लेकिन यह किसी भी चीज़ को प्रभावित नहीं करता है।

मैंने इस तरह से इसे किया:

svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');

ऐसा लगता है कि मैंने निर्दिष्ट बिंदु पर मुख्य बिंदु सेट नहीं किया है, हालांकि मैं फ़ायरफ़ॉक्स में देख सकता हूं कि विशेषता सही ढंग से सेट है। मैंने center bottom तरह चीजें और 50% 100% को बिना किसी कंस्ट्रैसिस के कोशिश की। अभी तक कुछ भी काम नहीं किया।

क्या कोई मदद कर सकता है?


मेरा मुद्दा भी ऐसा ही था। लेकिन मैं अपने तत्वों को स्थापित करने के लिए डी 3 का उपयोग कर रहा था, और सीएसएस द्वारा ट्रांसफॉर्म और संक्रमण को संभालना चाहता था। यह मेरा मूल कोड था, जिसे मैं क्रोम 65 में काम कर रहा था:

//...
this.layerGroups.selectAll('.dot')
  .data(data)
  .enter()
  .append('circle')
  .attr('transform-origin', (d,i)=> `${valueScale(d.value) * Math.sin( sliceSize * i)} 
                                     ${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)}`)
//... etc (set the cx, cy and r below) ...

इसने मुझे एक ही डेटा का उपयोग कर जावास्क्रिप्ट में cx , cy , और transform-origin मान सेट करने की अनुमति दी।

लेकिन यह फ़ायरफ़ॉक्स में काम नहीं किया! मुझे क्या करना था circle को g टैग में लपेटना था और ऊपर से उसी स्थिति निर्धारण सूत्र का उपयोग करके इसका translate करना था। मैंने फिर g टैग में circle लगाया, और अपने cx और cy मानों को 0 सेट किया। वहां से, transform: scale(2) केंद्र से अपेक्षा के अनुसार स्केल होगा। अंतिम कोड इस तरह दिखता था।

this.layerGroups.selectAll('.dot')
  .data(data)
  .enter()
  .append('g')
  .attrs({
    class: d => `dot ${d.metric}`,
    transform: (d,i) => `translate(${valueScale(d.value) * Math.sin( sliceSize * i)} ${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)})`
  })
  .append('circle')
  .attrs({
    r: this.opts.dotRadius,
    cx: 0,
    cy: 0,
  })

इस परिवर्तन को करने के बाद, मैंने transform: scale(2) जोड़ने के लिए .dot बजाय circle को लक्षित करने के लिए अपना सीएसएस बदल दिया transform: scale(2) । मुझे transform-origin उपयोग की भी आवश्यकता नहीं थी।

टिप्पणियाँ:

  1. मैं दूसरे उदाहरण में d3-selection-multi का उपयोग कर रहा हूं। यह मुझे प्रत्येक विशेषता के लिए .attr को दोहराने के बजाय .attrs को ऑब्जेक्ट पास करने की अनुमति देता है।

  2. एक स्ट्रिंग टेम्पलेट शाब्दिक का उपयोग करते समय, पहले उदाहरण में चित्रित लाइन-ब्रेक के बारे में जागरूक रहें। इसमें आउटपुट में एक नई लाइन शामिल होगी और आपका कोड तोड़ सकता है।


यदि आप मेरे जैसे हैं और पैन करना चाहते हैं और फिर ट्रांसफॉर्म-उत्पत्ति के साथ ज़ूम करना चाहते हैं, तो आपको थोड़ा और आवश्यकता होगी।

// <g id="view"></g>
var view = document.getElementById("view");

var state = {
  x: 0,
  y: 0,
  scale: 1
};

// Origin of transform, set to mouse position or pinch center
var oX = window.innerWidth/2;
var oY = window.innerHeight/2;

var changeScale = function (scale) {
  // Limit the scale here if you want
  // Zoom and pan transform-origin equivalent
  var scaleD = scale / state.scale;
  var currentX = state.x;
  var currentY = state.y;
  // The magic
  var x = scaleD * (currentX - oX) + oX;
  var y = scaleD * (currentY - oY) + oY;

  state.scale = scale;
  state.x = x;
  state.y = y;

  var transform = "matrix("+scale+",0,0,"+scale+","+x+","+y+")";
  //var transform = "translate("+x+","+y+") scale("+scale+")"; //same
  view.setAttributeNS(null, "transform", transform);
};

यहां यह काम कर रहा है: http://forresto.github.io/dataflow-prototyping/react/


matrix परिवर्तन का उपयोग किए बिना स्केलिंग के लिए:

transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"

और यहां यह सीएसएस में है:

transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)




coordinate-transformation