استفاده از SVG ها نسبتاً مستقیم است – تا زمانی که بخواهید فعل و انفعالات DOM و بردار را مخلوط کنید.

SVG ها سیستم مختصات خاص خود را در a تعریف می کنند viewBox صفت. مثلا:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">

این عرض از 800 واحد و ارتفاع 600 واحد را از ابتدا تعیین می کند 0,0. اینها واحد اندازه گیری های دلخواه برای اهداف ترسیم هستند ، و می توان از کسرهای یک واحد استفاده کرد. اگر این SVG را در یک قرار دهید 800 توسط 600 مساحت پیکسل ، هر واحد SVG باید مستقیماً روی یک پیکسل صفحه نقشه بکشید.

با این حال ، تصاویر برداری را می توان در هر اندازه کوچک کرد – به ویژه در یک طراحی پاسخگو. SVG شما را می توان به کوچک کرد 400 توسط 300 یا حتی فراتر از شناخت در یک 10 توسط 1000 فضا. اگر بخواهید آنها را با توجه به مکان نشانگر قرار دهید ، افزودن عناصر بیشتر به این SVG دشوارتر می شود.

توجه: به سارا سویدن مراجعه کنید viewport ، viewBox و protectionAspectRatio مقاله برای کسب اطلاعات بیشتر در مورد مختصات SVG.

از ترجمه هماهنگ خودداری کنید

شاید بتوانید از ترجمه کامل بین سیستم های مختصات جلوگیری کنید.

SVG های تعبیه شده در صفحه HTML (به جای تصویر یا پس زمینه CSS) به بخشی از DOM تبدیل می شوند و می توان آنها را به روشی مشابه سایر عناصر دستکاری کرد. به عنوان مثال ، یک SVG اساسی با یک دایره واحد بگیرید:

<svg id="mysvg" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 800 600" preserveAspectRatio="xMidYMid meet">
  <circle id="mycircle" cx="400" cy="300" r="50" />
<svg>

می توانید جلوه های CSS را به این مورد اعمال کنید:

circle {
  stroke-width: 5;
  stroke: #f00;
  fill: #ff0;
}

circle:hover {
  stroke: #090;
  fill: #fff;
}

همچنین می توانید کنترل کننده های رویداد را برای اصلاح ویژگی ها ضمیمه کنید:

const mycircle = document.getElementById('mycircle');

mycircle.addEventListener('click', (e) => {
  console.log('circle clicked - enlarging');
  mycircle.setAttribute('r', 60);
});

مثال زیر سی دایره تصادفی به یک تصویر SVG اضافه می کند ، یک اثر شناور در CSS اعمال می کند و از جاوا اسکریپت برای شعاع ده واحد با کلیک روی دایره استفاده می کند.

قلم را ببینید
تعامل SVG
توسط SitePoint (SitePoint)
بر CodePen.

ترجمه هماهنگ SVG به DOM

ممکن است لازم باشد یک عنصر DOM در بالای یک عنصر SVG قرار گیرد – به عنوان مثال ، یک منو یا جعبه اطلاعات در کشور فعال که در نقشه جهان نشان داده شده است. با فرض اینکه SVG در HTML جاسازی شده است ، عناصر بخشی از DOM می شوند ، بنابراین getBoundingClientRect () از روش می توان برای استخراج موقعیت و ابعاد استفاده کرد. (برای نشان دادن صفات جدید دایره کلیک شده به دنبال افزایش شعاع ، کنسول را در مثال بالا باز کنید.)

Element.getBoundingClientRect() در همه مرورگرها پشتیبانی می شود و یک را برمی گرداند DOMrect شی با مشخصات زیر در ابعاد پیکسل:

  • .x و .left: مختصات x ، نسبت به منشأ نمایش در سمت چپ عنصر
  • .right: مختصات x ، نسبت به منشأ نمایش در سمت راست عنصر
  • .y و .top: مختصات y ، نسبت به مبدا نمای در سمت بالای عنصر
  • .bottom: مختصات y ، نسبت به مبدا نمایش از سمت پایین عنصر
  • .width: عرض عنصر (در IE8 و پایین پشتیبانی نمی شود اما با یکسان است) .right منهای .left)
  • .height: ارتفاع عنصر (در IE8 و پایین پشتیبانی نمی شود اما یکسان است .bottom منهای .top)

همه مختصات مربوط به نمای مرورگر است و بنابراین با پیمایش صفحه تغییر می کند. با افزودن می توان مکان مطلق صفحه را محاسبه کرد window.scrollX به .left و window.scrollY به .top.

ترجمه مختصر DOM به SVG

این چالش برانگیزتر است. فرض کنید می خواهید یک عنصر SVG جدید را روی آن قرار دهید viewBox در محلی که یک رویداد کلیک اتفاق می افتد. شی hand کنترل کننده رویداد DOM را فراهم می کند .clientX و .clientY مختصات پیکسل ، اما اینها باید به واحدهای SVG ترجمه شوند.

وسوسه انگیز است اگر فکر کنید می توانید مختصات یک نقطه SVG را با استفاده از فاکتورهای ضرب محاسبه کنید. به عنوان مثال ، اگر یک SVG به عرض 1000 واحد در ظرفی با عرض 500 پیکسل قرار گیرد ، می توانید هر DOM را ضرب کنید x برای بدست آوردن موقعیت SVG توسط دو نفر هماهنگ شوید. کار نمی کند! …

  • هیچ تضمینی وجود ندارد که SVG دقیقاً درون ظرف شما باشد.
  • اگر ابعاد عنصر تغییر کند – شاید در پاسخ به تغییر اندازه کاربر توسط مرورگر – فاکتورهای عرض و ارتفاع باید دوباره محاسبه شوند.
  • SVG یا یک یا چند عنصر می توانند در فضای دو بعدی یا سه بعدی تبدیل شوند.
  • حتی اگر این موانع را پشت سر بگذارید ، هرگز آنطور که انتظار دارید کاملاً جواب نمی دهد و اغلب یک خطای خطا وجود دارد.

خوشبختانه ، SVG سازوکارهای فاکتورهای ماتریسی خود را برای ترجمه مختصات ارائه می دهند. اولین قدم ایجاد یک نقطه در SVG با استفاده از createSVGPoint() روش و در صفحه / رویداد عبور کنید x و y مختصات:

const
  svg = document.getElementById('mysvg'),
  pt = svg.createSVGPoint();

pt.x = 100;
pt.y = 200;

سپس می توانید یک تغییر شکل ماتریس ایجاد کنید که از وارون SVG ایجاد شده است .getScreenCTM() روش ، که واحدهای SVG را برای نمایش مختصات نقشه می کشد:

const svgP = pt.matrixTransform( svg.getScreenCTM().inverse() );

svgP اکنون دارد .x و .y خصوصیات ، مختصات موجود در SVG را فراهم می کند viewBox.

کد زیر یک دایره را در یک نقطه کلیک کرده روی بوم SVG قرار می دهد:


const
  svg = document.getElementById('mysvg'),
  NS = svg.getAttribute('xmlns');


svg.addEventListener('click', (e) => {

  const pt = svg.createSVGPoint();

  
  pt.x = e.clientX;
  pt.y = e.clientY;

  
  const svgP = pt.matrixTransform( svg.getScreenCTM().inverse() );

  
  const circle = document.createElementNS(NS, 'circle');
  circle.setAttribute('cx', svgP.x);
  circle.setAttribute('cy', svgP.y);
  circle.setAttribute('r', 10);

  svg.appendChild(circle);

});

توجه داشته باشید که createElementNS() متدها با DOM استاندارد یکسان است createElement() روش ، با این تفاوت که آن را مشخص می کند فضای نام XML URI. به عبارت دیگر ، این یک سند SVG عمل می کند تا HTML.

ترجمه به مختصات SVG تبدیل شده

یک عارضه دیگر نیز وجود دارد. SVG یا عناصر منفرد را می توان با ترجمه ، مقیاس گذاری ، چرخش و / یا کج شدن تغییر داد ، که این مختصات SVG حاصل را تحت تأثیر قرار می دهد. به عنوان مثال ، موارد زیر <g> لایه 4 برابر بزرگتر از واحدهای استاندارد SVG است ، بنابراین مختصات یک چهارم از SVG حاوی خواهد بود:

<g id="transformed" transform="scale(4)">
  <rect x="50" y="50" width="100" height="100" />
</g>

مستطیل حاصل ظاهر می شود داشتن یک 400 عرض و ارتفاع واحد در موقعیت 200, 200.

خوشبختانه ، .getScreenCTM() روش را می توان برای هر عنصر و همچنین خود SVG اعمال کرد. ماتریس بدست آمده تمام تحولات را در نظر می گیرد بنابراین می توانید یک ساده ایجاد کنید svgPoint() عملکرد ترجمه:

const
  svg = document.getElementById('mysvg'),
  transformed = svg.getElementById('transformed');

console.log( svgPoint(svg, 10, 10) ); 
console.log( svgPoint(transformed, 10, 10) ); 


function svgPoint(element, x, y) {

  const pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;

  return pt.matrixTransform( element.getScreenCTM().inverse() );

}

نمایش زیر در همه مرورگرهای مدرن کار می کند ، (و اگر JavaScript را به ES5 تبدیل کنید در IE11 کار خواهد کرد!). با ضربه زدن / کلیک روی SVG ، یک دایره در نقطه نشانگر اضافه می شود.

این نیز هنگام تبدیل تبدیل می شود <g> بر روی منطقه کلیک می شود ، اما آن عنصر به جای SVG به خود منتقل می شود svgPoint() تابع برای اطمینان از محاسبه مختصات صحیح:

قلم را ببینید
ترجمه هماهنگ DOM به SVG
توسط کریگ باکلر (craigbuckler)
بر CodePen.

در حالت ایده آل ، بهترین کار این است که از ترجمه مختصات SVG به DOM خودداری کنید ، اما در صورت عدم امکان ، از روش های توضیح داده شده در بالا استفاده کنید تا اطمینان حاصل کنید که روند در همه ابعاد صفحه قوی است.