javascript - Döndürülmüş bir SVG öğesinin ekran piksellerindeki sınırları nasıl alınır?
Rastgele bir SVG öğesinin ekran piksellerindeki sınırlayıcı kutusunu doğru bir şekilde bir HTML öğesi üzerine yerleştirmek için elde etmenin en iyi yolunu bulmaya çalışıyorum. Şu ana kadar olan yaklaşımım, nesnenin sınırlayıcı kutusunu ve dönüşüm matrisini almak için .getBBox() ve .getCTM() kullanmak ve ardından sınırlayıcı kutu noktalarına dönüşümü, bu soruya verilen kabul edilmiş cevapta açıklandığı şekilde uygulamaktı.
// get the element
var el = $(selector)[0],
pt = $(selector).closest('svg')[0].createSVGPoint();
// get the bounding box and matrix
var bbox = el.getBBox(),
matrix = el.getScreenCTM();
pt.x = bbox.x;
pt.y = bbox.y;
var nw = pt.matrixTransform(matrix);
pt.x += bbox.width;
pt.y += bbox.height;
var se = pt.matrixTransform(matrix);
// make a div in the screen space around the object
var $div = $('<div class="bbox"/>').css({
left: nw.x,
top: nw.y,
width: se.x - nw.x,
height: se.y - nw.y
})
.appendTo('body');
Testimi burada görebilirsiniz: http://jsfiddle.net/nrabinowitz/zr2jX/
Ancak, testlerin gösterdiği gibi, bu yaklaşım dönüşümde bir döndürme olduğunda başarısız oluyor gibi görünüyor - kutu, döndürme öncesinde hesaplanıyor gibi görünüyor, bu yüzden döndürülmüş sınırlayıcı kutunun köşelerini almak çalışmıyor.
Dönüştürülmüş öğelerin döndürülmemiş sınırlayıcı kutusunu nasıl doğru şekilde hesaplayabilirim?
Cevap #1
Biraz araştırmadan sonra bulduğum en iyi seçenekler şunlardır:
getBoundingClientRect()modern tarayıcılarda SVG elemanları için iyi çalışıyor gibi görünüyor ve oldukça hızlı, ancak sonuçlar platformdan platforma biraz değişebilir (özellikle kalın bir strokunuz varsa). Ancak, @Sergiu'nun belirttiği gibi, bu şekil değişikliklerini hesaba katmaz ve size döndürülmüş sınırlayıcı kutunun sınırlarını verir, gerçek yol veya nesneyi değil, bu yüzden oldukça hassas olmayabilir - eleştiriye buradan bakabilirsiniz. Örnek fiddle: http://jsfiddle.net/stevenbenner/6M5zf/Ana amacım, sınırlayıcı dikdörtgenin konumsal köşelerini ve orta noktalarını almaktı ve sonunda döndürülmüş sınırlayıcı kutuyu kullanmanın, döndürülmüş bir şeklin "gerçek" sınırlayıcı kutusuna göre daha tercih edilebilir olabileceğine karar verdim. Bunu yukarıdaki yaklaşımı kullanarak yapabildim ve ardından noktaları N, S, E, W pozisyonlarına olabildiğince yakın olacak şekilde döndürdüm. Örnek fiddle'ımı burada görebilirsiniz: http://jsfiddle.net/nrabinowitz/sPtzV/
Cevap #2
Bunun mümkün olduğunu sanmıyorum, çünkü kayma ve dönme profil değişikliğini içerir, yani şeklin iki eksendeki projeksiyonlarının nasıl göründüğüyle ilgilidir.
CTM'nin dönüşüm kısmını görmezden gelecek dönüşüm matrisini hesaplayabilirsiniz, ancak o zaman yeni BBox'un hâlâ döndürülmüş elemanınızı kapsayacağına dair herhangi bir garanti vermezsiniz. Örneğin, bir daireniz varsa, dönüşüm sınırlayıcı kutunun boyutlarını etkilemez. Öte yandan, temel yol olarak bir elmasınız varsa ve bunu 45 derece döndürürseniz, sonunda sadece bir kare olacak, sınırlayıcı kutu farklıdır: başlangıçta diyagonali ölçüyordunuz ve şimdi kenar uzunluğunu ölçen bir sınırlayıcı kutu elde etmeniz gerekiyor. CTM'yi nasıl kullanırsanız kullanın, şekil değişikliğini hesaba katamazsınız.
Yani, dönüş gerçekten oldukça önemli, onu görmezden gelmek bir seçenek değil; ama sadece yerel sınırlayıcı kutu ve dönüşüm matrisi, şekil profilinin döndürüldüğünde nasıl değiştiği hakkında hiçbir şey söylemez.