生活随笔
收集整理的這篇文章主要介紹了
原生js实现简单的svg编辑器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原生js實現簡單的svg編輯器
簡單的實現了rect、circle、ellipse、line四個簡單的基礎圖形的創建和編輯,這篇文章對于JavaScript中Dom操作和svg基礎學習有很大幫助。
項目在線預覽:http://coolxiang.top/svgeditor
編輯器預覽圖(做了只丑兔子花了我好長時間):
接下來說一下實現原理和代碼講解。
頁面樣式和布局
HTML和CSS相對來說比較簡單,這里我不多介紹了。只是說一下這個頁面使用rem和flexible自適應布局。另外通過flex實現左邊工具欄固定rem寬度,右側自適應大小寬度。
工具欄使用input滑動條和color選擇器控制圖形。
開始介紹js
首先聲明一些數據,比如每個圖形的屬性默認值
有一些私有的屬性和公有的,我們區分開
const XMLNS = 'http://www.w3.org/2000/svg';
const privateAttrs
= {
rect
: {x
:10,y
:10,width
:200,height
:100,rx
:0,ry
:0},
circle
: {cx
:200,cy
:200,r
:50},
ellipse
: {cx
:200,cy
:200,rx
:80,ry
:30},
line
: {x1
:100,y1
:100,x2
:200,y2
:200}
}
const publicAttrs
= {
fill
: '#ffffff',
stroke
: '#ff0000'
}
我們可以先統計以下我們需要實現哪些功能
- 點擊創建工具欄事件,創建圖形,并且生成形狀和外觀工具欄。
- 改變形狀工具欄中的滑動條,修改右側圖形形狀(私有屬性)。
- 改變外觀工具欄中的滑動條或選擇器,修改圖形顏色外觀(公有屬性)。
- 點擊svg圖形,選中圖形生成對應的工具欄并且同步數據。
- 考慮到右側畫板為自適應大小,因此滑動條中設置坐標的最大值應跟隨頁面大小變化,這里再添加一個resize事件。
以上就是這個編輯器的主要功能,根據這些功能我們開始一步一步實現。
獲取DOM對象
const editorMap = document.querySelector('.editor-map');
const createTools = document.querySelector('.create');
const figureTools = document.querySelector('.figure ul');
const appearanceTools = document.querySelector('.appearance ul');
const svg = createSVG();
let selected = null;
根據上一步需求,首先需要創建svg 創建的同時我們也需要給svg添加點擊事件,這里使用事件委托的形式,通過e.target獲取觸發事件的dom對象即點擊圖形,后邊同理。
function createSVG() {const svg = document.createElementNS(XMLNS, 'svg');svg.setAttribute('width', '100%');svg.setAttribute('height', '100%');editorMap.appendChild(svg);svg.addEventListener('click', (e) => {if (privateAttrs[e.target.tagName.toLowerCase()]) {selectFigure(e.target); }})return svg;
}
這時候我們有需要實現一個選擇圖形的方法function selectFigure(figure) {selected = figure;let parent = selected.parentNode;parent.removeChild(figure);parent.appendChild(figure);figureTools.innerHTML = '';appearanceTools.innerHTML = '';for (let attr in privateAttrs[selected.tagName.toLowerCase()]) {let value = selected.getAttribute(attr)initFigureTools(attr, value); }initAppearanceTools();
}
分局以上需求,我們有需要完成兩個方法,但是根據順序,創建圖形的函數還未實現,我們可以先實現創建函數創建工具點擊事件createTools.addEventListener('click', (e) => {if (e.target.tagName.toLowerCase() === 'button') {createFigure(e.target.name); }
})
需要實現創建圖形的函數createFigurefunction createFigure(type) {const figure = document.createElementNS(XMLNS, type);for (let attr in privateAttrs[type]) {figure.setAttribute(attr, privateAttrs[type][attr]);}for (let attr in publicAttrs) {figure.setAttribute(attr, publicAttrs[attr]);}figure.setAttribute('stroke-width', 3);svg.appendChild(figure);selectFigure(figure);
}
這里我們又用到selectFigure方法,因為創建時默認選中。
現在我們的編輯器就可以實現創建圖形了。繼續第4步實現創建工具欄方法
function initFigureTools(attr, value) {let options = {x: editorMap.clientWidth,y: editorMap.clientHeight,cx: editorMap.clientWidth,cy: editorMap.clientHeight,width: editorMap.clientWidth,height: editorMap.clientHeight,rx: editorMap.clientWidth,ry: editorMap.clientHeight,r: editorMap.clientHeight,x1: editorMap.clientWidth,x2: editorMap.clientWidth,y1: editorMap.clientHeight,y2: editorMap.clientHeight}
const li = document.createElement('li');const span = document.createElement('span');const input = document.createElement('input');span.innerHTML = attr;input.setAttribute('type', 'range');input.setAttribute('min', 0);input.setAttribute('max', options[attr]);input.setAttribute('name', attr);input.setAttribute('value', value);li.appendChild(span);li.appendChild(input);figureTools.appendChild(li);
}
function initAppearanceTools() {const html = `<li class="color"><label><span>填充</span><input type="color" value="${selected.getAttribute('fill') || publicAttrs.fill}" name="fill"></label></li><li class="color"><label><span>描邊</span><input name="stroke" value="${selected.getAttribute('stroke') || publicAttrs.stroke}" type="color"></label><input type="range" value="${selected.getAttribute('stroke-width') || 1}" min="0" max="50" name="stroke-width"></li>`appearanceTools.innerHTML = html;
}
圖形和工具欄已經創建完成了,接下來就是通過工具欄改變圖形屬性了。我們同樣使用事件委托,綁定事件。
figureTools.addEventListener('input', (e) => {if (e.target.tagName.toLowerCase() === 'input') {updateFigure(e.target);}
})
appearanceTools.addEventListener('input', (e) => {if (e.target.tagName.toLowerCase() === 'input') {updateFigure(e.target);}
})
需要實現更新圖形屬性的方法updateFigure()function updateFigure(input) {let attr = input.name;selected.setAttribute(attr, input.value);
}
到這里我們的編輯器已經基本完成了~!最后我們要實現的是根據頁面窗口大小更新設置工具欄window.addEventListener('resize', (e) => {selectFigure(selected);
})
總結
以上是生活随笔為你收集整理的原生js实现简单的svg编辑器的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。