SVG(Scalable Vector Graphics)即為可升級矢量圖行,它是一種開放標準的文本式矢量圖形描述語言。使用SVG可以在網頁上顯示出各種各樣的高質量的矢量圖形。包括圖像處理中常見的許多功能,如圖形,文字、動畫、音頻、色彩、濾鏡效果等。最關鍵的是:SVG完全用普通文本來描述。也就是說,這是一種專門為網絡而設計的、基于文本的圖像格式。并且SVG是基于XML的語言,所以可擴展性很強,并能夠描述任意復雜的圖像。
SVG中元素的鼠標拖動是目前SVG圖形界面設計中常見的用戶需求。而要在一個復雜的系統中做到精確無誤的鼠標拖動,不僅要有恰當的SVG文檔結構設計,還要有鼠標拖動對象時準確的坐標計算公式。在目前的SVG1.1或SVG1.2標準規范中并沒有給出相關示范樣例,而網絡上流傳的許多鼠標拖動范例程序有很大的局限性,特別是其拖動時的坐標計算公式并不具備通用性,當移植到復雜的大中型的SVG系統當中時很容易發生拖動的失敗或錯誤移動。究其根本,無非是因為沒有深入理解分析SVG中的坐標系轉換(Coordinate system transformations)。
本文在深入了解SVG文檔結構和其坐標系轉換的基礎上,設計了一個規范的SVG鼠標拖動模型,然后通過嚴謹的數學證明計算出適用于任何SVG系統的坐標計算公式。實現了在不同SVG系統中準確無誤的鼠標拖動,并給出了源程序和效果示例圖。
1 SVG文檔結構設計
1.1 SVG文檔設計
SVG文檔的所有內容都是在一個二維空間無限的背景幕布上的,不過在其上還有一個有限的矩形區域用來放置文檔內容。這個有限的矩形區域即SVG視窗(viewport),用戶正是通過這個視窗看到了SVG圖形。設置好視窗之后,SVG用戶代理(SVG user agent)需要建立兩個坐標系統:視窗坐標系和用戶坐標系。而本文討論的鼠標拖動的坐標計算與這兩個坐標系統之間的轉換默契關聯。
視窗坐標系由SVG用戶代理根據SVG文檔的具體環境和設置進行計算而自動建立。它與用戶坐標系的原點都是SVG視窗的坐標原點,用戶坐標系中的一個單位必需等于一個屏幕像素。在此我們關注的是用戶坐標系的建立以及它與視窗坐標系之間的轉換。建立一個新的用戶坐標系只需要在SVG文檔中任意位置用轉換矩陣的形式進行坐標轉換,也可以用簡單的坐標轉換操作如:translate, scale, skew, rotate來實現。通過坐標系轉換來建立新的用戶坐標系是二維圖形的基本操作,也是控制圖形位置、大小、角度的通用方法。
在坐標轉換的原理基礎上,為了準確地實現鼠標拖動SVG圖形,本文制定了以下SVG文檔結構的設計模型:
(1) 對需要被拖動的元素dragTarget不要設置”transform”屬性,而是給dragTarget設置一個用元素構造的父結點,然后把”transform”屬性整體遷移到父結點元素中。這樣既能達到坐標轉換的要求,也不會影響到本文后面的坐標轉換公式的計算。
(2) 拖動對象的任意祖先結點可以隨意設置”transform”屬性,SVG根結點也可以設置”viewBox”屬性進行坐標轉換,毫無限制。這正是目前網絡上各種鼠標拖動方法所不能滿足的要求。
(3) 拖動對象必需有一個足夠大的背景區域(Background Rectangle)鋪在拖動對象圖層之下,以便讓用戶實施拖動操作,超出此背景區域則用戶不能正確拖動此對象。這是SVG鼠標拖動的技巧,是一種強制要求,否則不能實現恰當的鼠標拖動。
(4) 響應鼠標拖動事件的元素必須是拖動對象和背景區域的共同父結點或祖先結點(也可以是SVG文檔的根結點)。給這個祖先結點添加mousedown, mousemove, mouseup三個必不可少的事件。
如此,整個SVG文檔的模型初步建立。下面給出了試驗程序中的SVG文檔模型的代碼片斷。