背景
對(duì)于我的一個(gè)項(xiàng)目,我需要實(shí)現(xiàn)一個(gè)草圖墊。瀏覽谷歌的想法,很快我想出了一個(gè)基于畫布的畫板。但是它缺少幾個(gè)功能,我不確定它們是否容易在 canvas 平臺(tái)上實(shí)現(xiàn):
- 將繪圖另存為圖像,以便外部工具可以使用它,而無(wú)需特殊渲染器
- 存儲(chǔ)注意事項(xiàng) - 即使是 PNG 圖像也會(huì)很大
- 能夠在未來(lái)修改圖像。
- 選擇現(xiàn)有對(duì)象進(jìn)行微調(diào)。
因此,在下一次迭代中,我決定在 SVG 技術(shù) ( svg.html) 的基礎(chǔ)上繪制草圖。它似乎解決了我在畫布上遇到的所有問題。
使用代碼
要使用代碼,只需包含?editor.js
?文件并初始化為常規(guī) ?jQuery
?插件。
下面的示例代碼創(chuàng)建了?(#content
) ?一個(gè)??具有所需尺寸區(qū)域的簡(jiǎn)單?<div/>
? 。然后在 ?jQuerydocument.ready
?函數(shù)中創(chuàng)建一個(gè) jQuery 對(duì)象并附加 ?change
?事件處理程序。在此處理程序中,它使用 ?Scribble
?的對(duì)象?toText
?函數(shù)將繪圖作為 svg 文本字符串,并將預(yù)覽 ?#res
?元素的值設(shè)置為該 svg。
此外,它還獲取繪圖的 PNG 值并將預(yù)覽圖像設(shè)置為該值。由于圖像加載不是在瀏覽器中的即時(shí)操作,因此當(dāng)圖像準(zhǔn)備好時(shí),將調(diào)用作為函數(shù)參數(shù)提供的事件處理程序。
<div id="content"
style='position:absolute; width:600px; height:400px; left:100px; border:solid;'></div>
<script src="Editor.js"></script>
<script>
$(document).ready(function() {
$('#content').Scribble().change(function() {
$('#res').html($(this).Scribble('toText', 'svg'));
$(this).Scribble('toText', 'png', function(img) {
$('#img').attr('src', img);
});
});
});
</script>
<img id='img' style='border:solid;position:absolute; top:450px; left:5px; width:200px; height:130px;'>
<div id='res' style='border:solid;position:absolute; top:450px; left:210px;'></div>
這里有三種有趣的方法:
- ?
onchange
?事件 - 每次更改圖像時(shí)生成 - ?
toText(type, onLoad)
? 方法 - 一種將當(dāng)前 SVG 值作為不同格式的字符串返回的方法。可能的格式:
○ ?svg
?- 返回值作為 SVG 字符串
○ ?base64
?- SVG base64 編碼的值
○ ?mix
?- 如果 SVG 包含 unicode 字符 (emojii),則使用 base64 編碼,否則返回非編碼值
○ ?png
?、?jpeg
?或任何其他沒有“imamge/”部分的圖像 mime 類型。調(diào)用時(shí),返回值是 base64 編碼值。圖像將在 OnLoad 方法中返回(此處需要)
- ?
fromText(val)
?- 使用toText上面的() 函數(shù)生成的提供的 SVG 字符串加載編輯器的值。如果容器元素將 <textarea/> 作為子元素隱藏,則此 textarea 的值將用作編輯器的初始值。如果未找到此文本區(qū)域,則會(huì)創(chuàng)建空的隱藏文本區(qū)域。文本區(qū)域?qū)⒃谌魏胃臅r(shí)使用 SVG 內(nèi)容進(jìn)行更新。這是我用來(lái)在瀏覽器和后端 ASP.NET WebForms 應(yīng)用程序之間傳遞值的技巧。
支持的工具
- 線 - 允許創(chuàng)建線
- 矩形 - 允許創(chuàng)建矩形
- Arrow - 允許創(chuàng)建箭頭
- 鉛筆 - 自由形式繪圖。最初的實(shí)現(xiàn)是記住所有的鼠標(biāo)移動(dòng)點(diǎn)。然而,這會(huì)導(dǎo)致彎曲的線條和很多點(diǎn)。所以如果沒有按下shift,最終版本會(huì)畫直線。您可以按 shift 鍵或暫停半秒以放下錨點(diǎn)或在繪制時(shí)按住 shift 以跟隨 mosemove 事件。
- 文本 - 允許文本/表情符號(hào)輸入。
- 圖像 - 要求插入圖像。圖像也可以拖/放或粘貼到繪圖區(qū)域的頂部
- 移動(dòng) - 從對(duì)象創(chuàng)建切換到移動(dòng)/調(diào)整大小模式。
- 顏色 - 更改選定/創(chuàng)建對(duì)象的顏色
- 寬度 - 更改選定/創(chuàng)建對(duì)象的筆畫寬度
- 旋轉(zhuǎn) - 為簡(jiǎn)單起見,我只允許 90 度旋轉(zhuǎn)一次
興趣點(diǎn)
Base64 編碼
在某些時(shí)候?qū)ψ罱K產(chǎn)品進(jìn)行故障排除,我遇到了 emojii 無(wú)法正確重新加載的問題。我花了一段時(shí)間才意識(shí)到我的數(shù)據(jù)庫(kù)列是 varchar(max) 并且不存儲(chǔ) unicode。由于其他項(xiàng)目使用相同的數(shù)據(jù)庫(kù),因此我決定將SVG編碼為base 64,而不是更改列類型。不幸的是,瀏覽器中的btoa函數(shù)有問題,因此需要一些時(shí)間才能找到解決方案。
SVG 加載/兼容性
SVG 是一種完整的語(yǔ)言。我從來(lái)沒有打算能夠支持 SVG 規(guī)范中定義的所有功能,只是為了能夠加載我之前創(chuàng)建的文檔。請(qǐng)不要僅使用隨機(jī)的 SVG 文檔來(lái)嘗試它 - 它很可能不起作用。