কীভাবে এসভিজিতে রূপান্তর উত্স সেট করবেন


104

আমার জাভাস্ক্রিপ্ট ব্যবহার করে এসভিজি ডকুমেন্টের কিছু উপাদানকে আকার পরিবর্তন এবং ঘোরানো দরকার। সমস্যাটি হ'ল ডিফল্ট হিসাবে, এটি সর্বদা (0, 0)উপরের বাম দিকে উত্সের চারপাশে রূপান্তরটি প্রয়োগ করে ।

আমি কীভাবে এই রূপান্তর অ্যাঙ্কর পয়েন্টটিকে পুনরায় সংজ্ঞায়িত করতে পারি?

আমি transform-originগুণটি ব্যবহার করার চেষ্টা করেছি , তবে এটি কোনও কিছুই প্রভাবিত করে না।

আমি এটি এইভাবে করেছি:

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

এটি নির্দিষ্ট করা পয়েন্টের মূল পয়েন্টটি সেট করে বলে মনে হচ্ছে না যদিও আমি ফায়ারফক্সে দেখতে পারি যে বৈশিষ্ট্যটি সঠিকভাবে সেট করা আছে। আমি প্রথম বন্ধনীর মতো center bottomএবং এর 50% 100%বাইরেও চেষ্টা করেছি । এখনও কিছু হয়নি।

কেউ সাহায্য করতে পারেন?


FWIW, কল্পনানুসারে ফায়ারফক্স 19 বিটা 3 যেমন সংশোধন করা হয়েছে, যদিও আমি এখনও তালিকা ফায়ারফক্স 22. মজিলা Bugzilla মধ্যে সমস্যা হচ্ছে: bugzilla.mozilla.org/show_bug.cgi?id=828286
Toph

উত্তর:


147

ব্যবহার ঘোরানোর জন্য transform="rotate(deg, cx, cy)", ডিগ্রি যেখানে আপনি ঘুরতে চান সেই ডিগ্রি এবং (cx, cy) ঘূর্ণনের কেন্দ্র নির্ধারণ করে।

স্কেলিং / আকার পরিবর্তন করার জন্য আপনাকে (-cx, -cy) দ্বারা অনুবাদ করতে হবে, তারপরে স্কেল করুন এবং তারপরে (সিক্স, সাই) অনুবাদ করতে হবে। আপনি ম্যাট্রিক্স ট্রান্সফর্মের মাধ্যমে এটি করতে পারেন :

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

যেখানে এসএক্স হল এক্স-অক্ষের স্কেলিং ফ্যাক্টর, ওয়াই-অক্ষে সিআই।


তোমাকে অনেক ধন্যবাদ. ঘোরানো পুরোপুরি আমার মনে হয় কাজ করে তবে স্কেলিং / আকার পরিবর্তনটি সর্বদা কিছু এলোমেলো পরিমাণে বন্ধ হয়ে যায়। আমি ম্যাট্রিক্সটি ব্যবহার করে এবং "অনুবাদ (সিএক্স এসএক্স, সাই সি ) স্কেল (এসএক্স, সি ) " এর মতো আলাদাভাবে করার চেষ্টা করেছি । একই ফল।
সিডাডارک

6
এটি কি রূপান্তরিত হবে না "ম্যাট্রিক্স (এসএক্স, 0, 0 , সি , সিএক্স-এসএক্স সিএক্স, সাই- সি সাই)"? কারণ আপনি কেবল পার্থক্য দ্বারা অনুবাদ করতে চান। আমি মনে করি এই যুক্তিটি সঠিক, তবে এটি এখনও আমাকে পজিশনগুলি
ছাড়িয়েছে

এখন এটা কাজ করছে! আমি কেবল ভুল সিএক্স এবং সাই মান ব্যবহার করছিলাম! অনেক ধন্যবাদ!
সিএডার্ক

1
@ জায়েস্টেভেনস হ্যাঁ, ম্যাট্রিক্স রূপান্তর যে কোনও সিস্টেমের জন্য কাজ করবে, এটি কেবল গণিত। পার্থক্য কেবল স্বরলিপি হতে পারে। আমি যতদূর বলতে পারি, সিএসএস ম্যাট্রিক্স রূপান্তরটি এসভিজির জন্য একই স্বরলিপি ব্যবহার করে, সুতরাং সেই ক্রমে একই ছয়টি সংখ্যা কাজ করা উচিত।
পিটার কলিংগ্রিজ

1
কেবল স্পষ্ট করার জন্য, সিক্স এবং সাইকে আপনার স্কেলিংয়ের বাক্সটির কেন্দ্রের অফসেট হওয়া দরকার This এটি আমাকে সিএসএস বক্সের মডেলগুলিতে ভাবছিলাম বলে কিছুটা ছড়িয়ে দিল। নীচে তার উত্তরে @ ফরস্টো এটিকে জবাব দেয়।
জেসন ফার্নসওয়ার্থ

22

যদি আপনি একটি স্থির মান ("কেন্দ্র" বা "50%" নয়) ব্যবহার করতে পারেন তবে আপনি পরিবর্তে সিএসএস ব্যবহার করতে পারেন:

-moz-transform-origin: 25px 25px;
-ms-transform-origin:  25px 25px;
-o-transform-origin: 25px 25px;
-webkit-transform-origin:  25px 25px;
transform-origin: 25px 25px;

কিছু ব্রাউজার (যেমন ফায়ারফক্স) আপেক্ষিক মানগুলি সঠিকভাবে পরিচালনা করবে না।


1
কি দারুন. আমি + পারলে +10 করতাম। এটা আমার দিন বাঁচায়! ধন্যবাদ।
কুলুব

এটি কীভাবে জাভাস্ক্রিপ্টে করা যায়?
অ্যান্ড্রু এস

পছন্দ element.setAttribute('transform-origin', '25px 25px')?
নিক্ক ওয়াং

13

আপনি যদি আমার মতো হন এবং প্যান করতে চান এবং ট্রান্সফর্ম-অরিজিন দিয়ে জুম করতে চান তবে আপনার আরও কিছুটা প্রয়োজন।

// <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/


আপনার
গিথুব

হ্যালো @ নিউক্লিয়ার পিওন, এটি দুর্দান্ত but যে এসভিজি উপাদানটি প্রয়োগ করতে চাই তা ইতিমধ্যে "মেইনগ্রিড" নামে একটি পরিবর্তনশীল। আমি "ভিউ" এর উদাহরণটি "মেইনগ্রিড" দিয়ে কোনও প্রভাব ছাড়াই প্রতিস্থাপন করার চেষ্টা করেছি। আমি কী মিস করছি? ধন্যবাদ!
পক্ষে

@ সেকফেরেটের জন্য সর্বাধিক সুস্পষ্ট বিষয় যাচাই করা হয় তা হ'ল idমিল getElementByIdএবং নথির id="..."বৈশিষ্ট্য। কোডটি না দেখে নিশ্চিতভাবে জানা শক্ত। আপনি একটি তাই প্রশ্ন যেমন পোষ্ট করতে না চান তাহলে, আপনি যতক্ষণ না এটি কাজ করে আপনার গুণের নাম ব্যবহার সহজ উদাহরণ তৈরি করার চেষ্টা করুন / আপনার সমস্যা খুঁজে পেতে পারেন, তারপর বিশ্রাম ফিরে যোগ করুন।
NuclearPeon

12

matrixরূপান্তরটি ব্যবহার না করেই স্কেলিংয়ের জন্য :

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

এবং এটি এটি সিএসএসে রয়েছে:

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

0

দেখে মনে হচ্ছে আমরা সকলেই এখানে একটি কৌশল মিস করেছি: transform-box: fill-box

ব্যবহার transform-box: fill-boxকরা কোনও এসভিজির মধ্যে একটি উপাদানকে একটি সাধারণ এইচটিএমএল উপাদান হিসাবে আচরণ করবে। তারপরে আপনি transform-origin: centerসাধারণত (যেমন অন্য কিছু) আবেদন করতে পারেন

এটি ঠিক, transform-box: fill-boxকোনও জটিল ম্যাট্রিক্স স্টাফের প্রয়োজন নেই


-1

আমারও একি দশা. তবে আমি আমার উপাদানগুলি অবস্থান করতে ডি 3 ব্যবহার করছিলাম এবং সিএসএস দ্বারা রুপান্তররূপান্তরটি পরিচালনা করতে চেয়েছিলাম wanted এটি আমার আসল কোড যা আমি ক্রোমে working৫ তে কাজ করেছি:

//...
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উপরে থেকে একই পজিশনিং সূত্র ব্যবহার করে। আমি তখন যোগ করা circleমধ্যে gট্যাগ, এবং সেট তার 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,
  })

এই পরিবর্তনটি করার পরে, আমি আমার সিএসএস circleপরিবর্তে এর পরিবর্তে লক্ষ্যবস্তু করেছিলাম.dot করতে transform: scale(2)। আমার এমনকি ব্যবহারের প্রয়োজনও ছিল না transform-origin

মন্তব্য:

  1. আমি ব্যাবহার করছি d3-selection-multi দ্বিতীয় উদাহরণ । এটি আমাকে প্রতিটি বৈশিষ্ট্যের জন্য .attrsপুনরাবৃত্তি না .attrকরে কোনও বস্তুকে পাস করার অনুমতি দেয় ।

  2. আক্ষরিক স্ট্রিং টেম্পলেট ব্যবহার করার সময়, প্রথম উদাহরণে বর্ণিত লাইন-ব্রেক সম্পর্কে সচেতন হন। এটি আউটপুটে একটি নতুন লাইন অন্তর্ভুক্ত করবে এবং আপনার কোড ভঙ্গ করতে পারে।


2
আপনি যদি ট্রান্সফর্ম-বক্স সেট করেন: ফিল-বক্স; ফায়ারফক্স আপনি যেভাবে ইচ্ছা কাজ করত।
রবার্ট লঙ্গসন

যে চেষ্টা। কাজ মনে হচ্ছে না। ফায়ারফক্সের পৃষ্ঠায় আমি প্রিফ পরিবর্তন করার পরে এটি কাজ করেছিল । তবে ... এটি পর্যাপ্ত সমাধানের মতো বলে মনে হচ্ছে না। আমিও মধ্যে একটি অমিল পাওয়া এবং । svg:transform-origin.enabledabout:configtransform-origin: 50% 50%transform-origin: center center
জ্যামি এস

এসভিজি.টান্সফর্ম-অরিজিন.এনবেবল প্রেফ অনেক সংস্করণ আগে সরানো হয়েছিল। আপনি যদি খুব পুরানো সংস্করণ ব্যবহার না করেন তবে 50% এবং কেন্দ্রের মধ্যে কোনও পার্থক্য থাকতে হবে না। ফায়ারফক্স ৫৯ বা তার পরে এর মধ্যে কোনও পার্থক্য থাকলে একটি বগজিলা বাগ উত্সাহিত করুন
রবার্ট লঙ্গসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.