2010-02-01 36 views
22

Các trình duyệt đã triển khai các phần của thông số SVG (Firefox vv) thực hiện kiểm tra hit miễn phí - nếu tôi đính kèm một trình lắng nghe mousedown vào đối tượng SVG, tôi sẽ được thông báo bất cứ khi nào hình được nhấp. Điều này thật tuyệt vời, đặc biệt là đối với các hình đa giác phức tạp.Thử nghiệm hình SVG?

Tôi tự hỏi nếu có cách nào tôi có thể sử dụng tính năng này để kiểm tra lần truy cập nhiều hơn một chút. Tôi muốn biết nếu một hình chữ nhật cụ thể cắt bất kỳ hình dạng SVG nào của tôi.

Ví dụ: tôi thêm 3 đa giác phức tạp vào phần tử của mình. Bây giờ tôi muốn biết nếu hình chữ nhật (40, 40, 100, 100) cắt nhau. Có ai có một ý tưởng làm thế nào tôi có thể có thể móc vào sự hỗ trợ hit thử nghiệm đã tuyệt vời có sẵn, thay vì thêm tất cả các mã này bản thân mình?

Cảm ơn

Trả lời

13

Tôi không biết cách nào để giao cắt toàn bộ hình chữ nhật. Nhưng bạn có thể giao nhau một điểm, vì vậy bạn có thể xây dựng một kiểm tra phức tạp hơn về điều đó:

var el= document.elementFromPoint(x, y); 

sẽ cung cấp cho bạn phần tử được xếp chồng cao nhất tại một tọa độ tương đối trang cụ thể. Bạn sẽ nhận được phần tử <svg> nếu không có hình dạng nào bên trong SVG được nhấn.

Đây là một phi tiêu chuẩn Mozilla extension, nhưng nó cũng hoạt động trên WebKit. Thật không may, mặc dù nó tồn tại trong Opera, nó sẽ không nhìn vào bên trong <svg>, do đó trên trình duyệt đó phần tử sẽ luôn là SVGSVGElement.

+2

Cảm ơn bạn đã chỉ ra rằng giải pháp của bạn không phải là tiêu chuẩn vào thời điểm đó. Nó vẫn là một bản thảo làm việc nhưng may mắn thay phương pháp này đã biến nó thành một đặc tả CSSOM (rất tiện dụng!): Http://dev.w3.org/csswg/cssom-view/#dom-document-elementfrompoint – natevw

+0

nhiều người cảm ơn vì điều này ... – Sudarshan

+0

Các tọa độ được sử dụng trong elementFromPoint() là tuyệt đối, vì vậy trừ khi SVG của bạn bắt đầu ở 0,0, bạn sẽ cần điều chỉnh giữa các tọa độ tuyệt đối và tương đối –

21

Các SVG 1.1 DOM có chỉ là phương pháp đúng (tiếc là nó chưa thực hiện trong mozilla):

var nodelist = svgroot.getIntersectionList(hitrect, null); 

Đối với một ví dụ làm việc toàn thấy here.

+0

tuyệt vời! Vì vậy, giữa chúng tôi, chúng tôi đã có tất cả các trình duyệt chính. Vâng, ngoại trừ * một *, rõ ràng là ... – bobince

+0

Ok vì vậy chúng tôi chỉ phải chờ đợi điều này được thực hiện trong webkit, sau đó safari và chrome sau đó cần phải phát hành một phiên bản mới được xây dựng dựa trên những thay đổi này. – user246114

+1

Bài đăng blog đã biến mất. –

0

getIntersectionList hoạt động tốt trong Opera. Vấn đề của tôi là các hàm trong đặc tả đầy đủ của SVG 1.1 liên quan đến điều này đòi hỏi các phần tử phải được trả về (và có thể nhắm mục tiêu cho các sự kiện con trỏ) để được phát hiện là hit. Thật không may, điều này làm cho các chức năng này trở nên vô ích khi thử nghiệm hit trong một thế giới trò chơi, nơi chỉ một phần của thế giới hiện có thể nhìn thấy được.

+2

'độ mờ: 0' hoặc' hiển thị: ẩn' vẫn có nghĩa là các phần tử được đề cập được hiển thị theo svg, nhưng các phần tử sẽ ẩn. Bạn sẽ có thể điều chỉnh 'pointer-events' để áp dụng tốt cho các phần tử vô hình này. –

0

Phiên bản CheckIntersection (và getIntersectionList) của Chrome kiểm tra các hộp giới hạn phần tử, chứ không phải chính các phần tử. Tôi đã có thể viết checkIntersection của riêng tôi hoạt động trên chrome bằng cách sử dụng canvas với cách tiếp cận khá có liên quan này có vẻ hoạt động tốt cho hình chữ nhật nhỏ và sẽ chậm đối với hình chữ nhật lớn, vì vậy rất tốt cho thử nghiệm lượt truy cập. Kỹ thuật này sẽ hoạt động như một polyfill cho checkIntersection trong Chrome, đối với các hình chữ nhật nhỏ và có thể các trình duyệt khác đã phá vỡ việc triển khai checkIntersection.

  1. Tạo hình ảnh sử dụng URI dữ liệu chứa thẻ bên ngoài SVG của bạn (có thể bạn cũng cần bao gồm các quy tắc kiểu), như so (hình này không nằm trong trang). Bạn có thể sử dụng một trình xử lý sự kiện onload để xác định khi nào nó được nạp nếu bạn cần.
  2. Tạo một khung hình chữ nhật để sử dụng cho hit-test của bạn (vải này không cần phải được trong trang)

Để kiểm tra xem một hình chữ nhật cắt với bất kỳ hình dạng của bạn, làm điều này:

  1. Hãy chắc chắn rằng bức tranh có kích thước tương tự như hình chữ nhật của bạn (thiết lập chiều rộng và chiều cao của nó)
  2. Xóa vải sử dụng bối cảnh vải clearRect() phương pháp
  3. Vẽ SVG trên vải tại -x, -y để rằng phần của hình ảnh chồng chéo lên canvas tương ứng với khu vực bạn muốn thử nghiệm bằng cách sử dụng drawImage()
  4. Tìm nạp ImageData của canvas bằng cách sử dụng ngữ cảnh getImageData(). Mỗi phần tử thứ 4 của mảng dữ liệu là byte alpha và giá trị nonzero có nghĩa là một phần của SVG trùng lặp hình chữ nhật. Nếu tất cả các byte thứ 4 là 0, thì SVG của bạn không giao nhau với hình chữ nhật.
Các vấn đề liên quan