mirror of
https://github.com/sakitam-fdd/maptalks.plot.git
synced 2026-01-25 16:08:13 +00:00
# geometry editor
This commit is contained in:
parent
42bd28beed
commit
5d997d15b7
@ -16,6 +16,10 @@ module.exports = {
|
||||
],
|
||||
// add your custom rules here
|
||||
'rules': {
|
||||
// allow semi
|
||||
'semi': 0,
|
||||
// allow global require
|
||||
'global-require': 0,
|
||||
// allow paren-less arrow functions
|
||||
'arrow-parens': 0,
|
||||
// allow async-await
|
||||
|
||||
@ -7,11 +7,15 @@ const nodeResolve = require('rollup-plugin-node-resolve');
|
||||
const replace = require('rollup-plugin-replace');
|
||||
const eslint = require('rollup-plugin-eslint');
|
||||
const friendlyFormatter = require("eslint-friendly-formatter");
|
||||
const _package = require('../package.json')
|
||||
const eslintConfig = require('../.eslintrc')
|
||||
const year = new Date().getFullYear();
|
||||
const banner = `/*!\n * ${_package.name} v${_package.version}\n * LICENSE : ${_package.license}\n * (c) 2017-${year} ${_package.homepage}\n */`;
|
||||
|
||||
const _package = require('../package.json');
|
||||
const eslintConfig = require('../.eslintrc');
|
||||
const time = new Date();
|
||||
const year = time.getFullYear();
|
||||
const banner = `/*!\n * author: ${_package.author}
|
||||
* ${_package.name} v${_package.version}
|
||||
* build-time: ${year}-${time.getMonth()}-${time.getDay()} ${time.getHours()}:${time.getMinutes()}
|
||||
* LICENSE: ${_package.license}
|
||||
* (c) 2017-${year} ${_package.homepage}\n */`;
|
||||
const resolve = _path => path.resolve(__dirname, '../', _path)
|
||||
|
||||
const genConfig = (opts) => {
|
||||
@ -19,7 +23,13 @@ const genConfig = (opts) => {
|
||||
input: {
|
||||
input: resolve('src/index.js'),
|
||||
plugins: [
|
||||
eslint((eslintConfig => eslintConfig.formatter = friendlyFormatter)(eslintConfig)),
|
||||
eslint(Object.assign({}, eslintConfig, {
|
||||
formatter: friendlyFormatter,
|
||||
exclude: [
|
||||
resolve('package.json'),
|
||||
resolve('node_modules/**')
|
||||
]
|
||||
})),
|
||||
babel({
|
||||
exclude: 'node_modules/**' // only transpile our source code
|
||||
}),
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
<!--<script src="https://cdn.jsdelivr.net/npm/maptalks/dist/maptalks.js"></script>-->
|
||||
<script src="../dist/maptalks.plot.js"></script>
|
||||
<script type="text/javascript">
|
||||
var id = MaptalksPlot.utils.uuid();
|
||||
MaptalksPlot.utils.addClass(document.getElementById('map'), id);
|
||||
var map = new maptalks.Map('map', {
|
||||
center: [108.93, 34.27],
|
||||
zoom: 5,
|
||||
@ -37,7 +39,7 @@
|
||||
var drawTool = new MaptalksPlot.PlotDraw({
|
||||
mode: 'Curve'
|
||||
}).addTo(map).disable();
|
||||
var editor = new MaptalksPlot.PlotEditor();
|
||||
var editor = new MaptalksPlot.PlotEditor().addTo(map);
|
||||
editor.on('editStart', function (event) {
|
||||
console.log(event);
|
||||
});
|
||||
|
||||
15
package.json
15
package.json
@ -31,7 +31,8 @@
|
||||
"karma.tdd": "karma start build/karma.tdd.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"maptalks": "^0.37.0-alpha.1"
|
||||
"autosize": "^4.0.0",
|
||||
"maptalks": "^0.38.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
@ -68,17 +69,17 @@
|
||||
"karma-safari-launcher": "^1.0.0",
|
||||
"karma-sinon": "^1.0.5",
|
||||
"mocha": "^3.5.0",
|
||||
"rollup": "^0.50.0",
|
||||
"rollup-plugin-babel": "^3.0.2",
|
||||
"rollup-plugin-buble": "^0.16.0",
|
||||
"rollup-plugin-commonjs": "^8.2.6",
|
||||
"rollup": "^0.56.1",
|
||||
"rollup-plugin-babel": "^3.0.3",
|
||||
"rollup-plugin-buble": "^0.19.2",
|
||||
"rollup-plugin-commonjs": "^8.3.0",
|
||||
"rollup-plugin-eslint": "^4.0.0",
|
||||
"rollup-plugin-local-resolve": "^1.0.7",
|
||||
"rollup-plugin-node-resolve": "^3.0.0",
|
||||
"rollup-plugin-node-resolve": "^3.0.3",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"rollup-watch": "^4.3.1",
|
||||
"sinon": "^3.2.1",
|
||||
"uglify-js": "^3.1.2"
|
||||
"uglify-js": "^3.3.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
|
||||
@ -8,8 +8,7 @@ export const ZERO_TOLERANCE = 0.0001
|
||||
export const TWO_PI = Math.PI * 2
|
||||
export const BASE_LAYERNAME = 'maptalks-plot-vector-layer' // 矢量图层名,(唯一标识)
|
||||
export const BASE_HELP_CONTROL_POINT_ID = 'plot-helper-control-point-div' // 控制点要素的基类id
|
||||
export const BASE_HELP_HIDDEN = 'plot-helper-hidden-div' // 父类隐藏容器
|
||||
export const INTERNAL_LAYER_PREFIX = '_maptalks__internal_layer_'
|
||||
export const EDITOR_LAYERNAME = 'maptalks-plot-editor-vector-layer'
|
||||
export const DEF_TEXT_STYEL = { // 默认文本框样式
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '2px',
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import * as maptalks from 'maptalks'
|
||||
import {BASE_LAYERNAME} from '../Constants'
|
||||
import RegisterModes from '../geometry'
|
||||
import {merge} from '../utils/utils'
|
||||
import {merge, stopPropagation} from '../utils'
|
||||
|
||||
const _options = {
|
||||
'symbol': {
|
||||
@ -22,14 +22,6 @@ const _options = {
|
||||
'ignoreMouseleave': true
|
||||
}
|
||||
const registeredMode = {}
|
||||
const stopPropagation = function (e) {
|
||||
if (e.stopPropagation) {
|
||||
e.stopPropagation()
|
||||
} else {
|
||||
e.cancelBubble = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
class PlotDraw extends maptalks.MapTool {
|
||||
constructor (options = {}) {
|
||||
@ -336,8 +328,8 @@ class PlotDraw extends maptalks.MapTool {
|
||||
|
||||
/**
|
||||
* Set draw tool's symbol
|
||||
* @param {Object} symbol - symbol set
|
||||
* @returns {DrawTool} this
|
||||
* @param symbol
|
||||
* @returns {PlotDraw}
|
||||
*/
|
||||
setSymbol (symbol) {
|
||||
if (!symbol) {
|
||||
|
||||
@ -1,12 +1,43 @@
|
||||
import * as maptalks from 'maptalks'
|
||||
|
||||
import { isNumber } from '../utils'
|
||||
import {BASE_HELP_CONTROL_POINT_ID, EDITOR_LAYERNAME} from '../Constants'
|
||||
const Class = maptalks.Class
|
||||
const EventAble = maptalks.Eventable
|
||||
|
||||
const key = '_plot_editor';
|
||||
|
||||
class PlotEditor extends EventAble(Class) {
|
||||
constructor (geometry, opts) {
|
||||
super(opts)
|
||||
|
||||
/**
|
||||
* geometry
|
||||
*/
|
||||
this._geometry = geometry
|
||||
|
||||
/**
|
||||
* map pan
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.mapDragPan = true
|
||||
|
||||
/**
|
||||
* 存放控制点
|
||||
* @type {Array}
|
||||
*/
|
||||
this.controlPoints = []
|
||||
|
||||
/**
|
||||
* is dragging
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.isDragging = false
|
||||
|
||||
/**
|
||||
* 创建图层名称
|
||||
* @type {string}
|
||||
*/
|
||||
this.layerName = ((opts && opts['layerName']) ? opts['layerName'] : EDITOR_LAYERNAME)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -14,18 +45,280 @@ class PlotEditor extends EventAble(Class) {
|
||||
* @param plot
|
||||
*/
|
||||
activate (plot) {
|
||||
this.deactivate()
|
||||
this._geometry = plot
|
||||
console.log(plot, this)
|
||||
this.initControlPoints()
|
||||
this.fire('editStart', {
|
||||
geometry: this._geometry
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消激活工具
|
||||
*/
|
||||
deactivate () {
|
||||
console.log(this)
|
||||
this.removeControlPoints()
|
||||
delete this._geometry
|
||||
this.controlPoints = []
|
||||
}
|
||||
|
||||
initControlPoints () {
|
||||
this.controlPoints = []
|
||||
let controlPoints = PlotEditor.getControlPoints(this._geometry)
|
||||
if (controlPoints && Array.isArray(controlPoints) && controlPoints.length > 0) {
|
||||
if (controlPoints.length > this.options['limitControlPoints'] &&
|
||||
this.options.hasOwnProperty('limitControlPoints') &&
|
||||
this.options['limitControlPoints'] > 2) {
|
||||
// TODO 这里其中 `limitControlPoints` 必须包含起止点,所以这里处理了一下
|
||||
const _n = Math.floor(controlPoints.length / (this.options['limitControlPoints'] - 2)) || 1
|
||||
for (let i = 0; i < this.options['limitControlPoints'] - 2; i++) {
|
||||
const _index = (i + 1) * _n - 1
|
||||
this._addControlPoint(controlPoints, _index)
|
||||
}
|
||||
this._addControlPoint(controlPoints, 0)
|
||||
this._addControlPoint(controlPoints, controlPoints.length - 1)
|
||||
} else {
|
||||
for (let i = 0; i < controlPoints.length; i++) {
|
||||
this._addControlPoint(controlPoints, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove control points
|
||||
*/
|
||||
removeControlPoints () {
|
||||
const _layer = this._getDrawLayer(this.layerName)
|
||||
for (let i = 0; i < this.controlPoints.length; i++) {
|
||||
if (this.controlPoints[i]) {
|
||||
_layer.removeGeometry(this.controlPoints[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加控制点
|
||||
* @param points
|
||||
* @param _index
|
||||
* @private
|
||||
*/
|
||||
_addControlPoint (points, _index) {
|
||||
const id = BASE_HELP_CONTROL_POINT_ID + '-' + _index
|
||||
const _marker = new maptalks.Marker(
|
||||
points[_index],
|
||||
{
|
||||
id: id,
|
||||
draggable: true,
|
||||
symbol: {
|
||||
'markerType': 'ellipse',
|
||||
'markerFill': '#ffffff',
|
||||
'markerFillOpacity': 1,
|
||||
'markerLineColor': '#000',
|
||||
'markerLineWidth': 1,
|
||||
'markerLineOpacity': 1,
|
||||
'markerLineDasharray': [],
|
||||
'markerWidth': 10,
|
||||
'markerHeight': 10,
|
||||
'markerDx': 0,
|
||||
'markerDy': 0,
|
||||
'markerOpacity': 0.6
|
||||
},
|
||||
properties: {
|
||||
index: _index
|
||||
}
|
||||
}
|
||||
)
|
||||
if (this.getMap()) {
|
||||
_marker.addTo(this._getDrawLayer(this.layerName))
|
||||
_marker.on('dragstart', this._handleDragStart, this)
|
||||
_marker.on('dragging', this._handleDragging, this)
|
||||
_marker.on('dragend', this._handleDragEnd, this)
|
||||
}
|
||||
this.controlPoints.push(_marker)
|
||||
}
|
||||
|
||||
_handleDragStart (event) {
|
||||
this.isDragging = true
|
||||
}
|
||||
|
||||
_handleDragging (event) {
|
||||
if (this.isDragging && event.target) {
|
||||
const _index = event.target.getProperties() && event.target.getProperties()['index']
|
||||
const sourcePoints = this._geometry.getPoints()
|
||||
if (isNumber(_index) && sourcePoints.length > _index) {
|
||||
sourcePoints[_index] = event.coordinate
|
||||
this._geometry.setPoints(sourcePoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleDragEnd (event) {
|
||||
this.isDragging = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建矢量图层
|
||||
* @param layerName
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
_getDrawLayer (layerName) {
|
||||
const _map = this.getMap()
|
||||
if (!_map) return
|
||||
let drawToolLayer = _map.getLayer(layerName)
|
||||
if (!drawToolLayer) {
|
||||
drawToolLayer = new maptalks.VectorLayer(layerName, {
|
||||
'enableSimplify': false
|
||||
})
|
||||
_map.addLayer(drawToolLayer)
|
||||
}
|
||||
return drawToolLayer
|
||||
}
|
||||
|
||||
/**
|
||||
* add plot editor to map
|
||||
* @param map
|
||||
* @returns {PlotEditor}
|
||||
*/
|
||||
addTo (map) {
|
||||
if (!map) {
|
||||
return this;
|
||||
}
|
||||
this._map = map;
|
||||
if (map[key]) {
|
||||
map[key].disable();
|
||||
}
|
||||
if (this.onAdd) {
|
||||
this.onAdd();
|
||||
}
|
||||
this.enable();
|
||||
map[key] = this;
|
||||
this.fire('add');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map it added to.
|
||||
* @return {Map} map
|
||||
*/
|
||||
getMap () {
|
||||
return this._map;
|
||||
}
|
||||
|
||||
/**
|
||||
* enable plot editor
|
||||
* @returns {PlotEditor}
|
||||
*/
|
||||
enable () {
|
||||
const map = this._map;
|
||||
if (!map || this._enabled) {
|
||||
return this;
|
||||
}
|
||||
this._enabled = true;
|
||||
if (this.onEnable) {
|
||||
this.onEnable();
|
||||
}
|
||||
this.fire('enable');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* disable plot editor
|
||||
* @returns {PlotEditor}
|
||||
*/
|
||||
disable () {
|
||||
if (!this._enabled || !this._map) {
|
||||
return this;
|
||||
}
|
||||
this._enabled = false;
|
||||
if (this.onDisable) {
|
||||
this.onDisable();
|
||||
}
|
||||
this.fire('disable');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* check is enable
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEnabled () {
|
||||
if (!this._enabled) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove from map
|
||||
* @returns {PlotEditor}
|
||||
*/
|
||||
remove () {
|
||||
if (!this._map) {
|
||||
return this;
|
||||
}
|
||||
this.disable();
|
||||
if (this._map) {
|
||||
delete this._map[key];
|
||||
delete this._map;
|
||||
}
|
||||
this.fire('remove');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活地图的拖拽平移
|
||||
*/
|
||||
enableMapDragPan () {
|
||||
const _map = this.getMap()
|
||||
if (!_map) return
|
||||
_map.config({
|
||||
'draggable': this.mapDragPan
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁止地图的拖拽平移
|
||||
*/
|
||||
disableMapDragPan () {
|
||||
const _map = this.getMap()
|
||||
if (!_map) return
|
||||
this.mapDragPan = _map.options['draggable']
|
||||
_map.config({
|
||||
'draggable': false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要素的控制点
|
||||
* @returns {Array}
|
||||
*/
|
||||
static getControlPoints (plot) {
|
||||
let points = []
|
||||
if (plot) {
|
||||
points = plot.getPoints()
|
||||
}
|
||||
return points
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据控制点个数生成控制点
|
||||
* @param points
|
||||
* @param limit
|
||||
* @returns {Array}
|
||||
*/
|
||||
static getLimitControlPoints (points, limit) {
|
||||
const _coordinates = []
|
||||
if (points && points.length > 0) {
|
||||
const _n = Math.floor(points.length / limit) || 1
|
||||
for (let i = 0; i < limit; i++) {
|
||||
_coordinates.push(points[(i + 1) * _n - 1])
|
||||
}
|
||||
}
|
||||
return _coordinates
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
const TextArea = 'TextArea' // 文本标绘(特殊)
|
||||
const TEXTAREA = 'TextArea' // 文本标绘(特殊)
|
||||
const ARC = 'Arc'
|
||||
const CURVE = 'Curve'
|
||||
const GATHERING_PLACE = 'GatheringPlace'
|
||||
@ -26,7 +26,7 @@ const RECTFLAG = 'RectFlag'
|
||||
const TRIANGLEFLAG = 'TriangleFlag'
|
||||
const CURVEFLAG = 'CurveFlag'
|
||||
export {
|
||||
TextArea,
|
||||
TEXTAREA,
|
||||
ARC,
|
||||
CURVE,
|
||||
GATHERING_PLACE,
|
||||
|
||||
449
src/geometry/Text/PlotTextBox.js
Normal file
449
src/geometry/Text/PlotTextBox.js
Normal file
@ -0,0 +1,449 @@
|
||||
import * as maptalks from 'maptalks'
|
||||
import autosize from 'autosize'
|
||||
import {DEF_TEXT_STYEL} from '../../Constants'
|
||||
import { merge, on, off, hasClass, setStyle, getStyle } from '../../utils'
|
||||
|
||||
const _options = {
|
||||
'autoPan': true,
|
||||
'autoCloseOn': null,
|
||||
'autoOpenOn': 'click',
|
||||
'width': 300,
|
||||
'minHeight': 120,
|
||||
'custom': false,
|
||||
'title': null,
|
||||
'content': null
|
||||
}
|
||||
|
||||
class PlotTextBox extends maptalks.UIComponent {
|
||||
constructor (options = {}) {
|
||||
const $options = merge(_options, options)
|
||||
super()
|
||||
this.options = $options
|
||||
/**
|
||||
* 地图交互
|
||||
* @type {undefined}
|
||||
*/
|
||||
this.mapDragPan = undefined
|
||||
|
||||
/**
|
||||
* is click
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isClick_ = false
|
||||
|
||||
/**
|
||||
* 是否处于拖拽状态
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.dragging_ = false
|
||||
|
||||
/**
|
||||
* 当前气泡是否获取焦点
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isFocus_ = false
|
||||
|
||||
/**
|
||||
* 当前配置信息
|
||||
* @type {{}}
|
||||
* @private
|
||||
*/
|
||||
this.options_ = options
|
||||
|
||||
/**
|
||||
* 当前气泡位置
|
||||
* @type {Array}
|
||||
* @private
|
||||
*/
|
||||
this._position = (options['position'] && options['position'].length > 0) ? options['position'] : []
|
||||
|
||||
/**
|
||||
* 防抖延时
|
||||
* @type {null}
|
||||
* @private
|
||||
*/
|
||||
this.handleTimer_ = null
|
||||
|
||||
/**
|
||||
* 每次鼠标按下的位置
|
||||
* @type {Array}
|
||||
* @private
|
||||
*/
|
||||
this.currentPixel_ = []
|
||||
|
||||
/**
|
||||
* 创建text content
|
||||
*/
|
||||
this.createTextContent(options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文本框父容器
|
||||
* @param options
|
||||
*/
|
||||
createTextContent (options) {
|
||||
const _className = options.className || 'maptalks-plot-text-editor'
|
||||
const content = document.createElement('textarea')
|
||||
content.className = _className
|
||||
content.style.width = options['width'] + 'px'
|
||||
content.style.height = options['height'] + 'px'
|
||||
content.style.minHeight = options['minHeight'] + 'px'
|
||||
content.setAttribute('id', options['id'])
|
||||
content.setAttribute('autofocus', true)
|
||||
on(content, 'focus', this.handleFocus_, this)
|
||||
on(content, 'blur', this.handleBlur_, this)
|
||||
on(content, 'click', this.handleClick_, this)
|
||||
on(content, 'mousedown', this.handleDragStart_, this)
|
||||
on(window, 'mouseup', this.handleDragEnd_, this)
|
||||
this.set('isPlotText', true)
|
||||
this.setElement(content)
|
||||
this.createCloseButton(options)
|
||||
this.createResizeButton(options)
|
||||
this.setPosition(this._position)
|
||||
this.fire('textBoxDrawEnd', {
|
||||
overlay: this,
|
||||
element: content,
|
||||
uuid: options['id']
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本框
|
||||
* @returns {string}
|
||||
* @private
|
||||
*/
|
||||
getTextAreaFromContent_ () {
|
||||
let _node = ''
|
||||
const childrens_ = Array.prototype.slice.call((this.element && this.element.children), 0)
|
||||
if (childrens_.length > 0) {
|
||||
childrens_.every(ele => {
|
||||
if (ele.nodeType === 1 && ele.nodeName.toLowerCase() === 'textarea') {
|
||||
_node = ele
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
return _node
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建关闭按钮
|
||||
* @param options
|
||||
*/
|
||||
createCloseButton (options) {
|
||||
const _closeSpan = document.createElement('span')
|
||||
_closeSpan.className = 'maptalks-plot-text-editor-close'
|
||||
_closeSpan.setAttribute('data-id', options['id'])
|
||||
off(_closeSpan, 'click', this.closeCurrentPlotText, this)
|
||||
on(_closeSpan, 'click', this.closeCurrentPlotText, this)
|
||||
this.element.appendChild(_closeSpan)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文本框大小调整按钮
|
||||
* @param options
|
||||
*/
|
||||
createResizeButton (options) {
|
||||
const _resizeSpan = document.createElement('span')
|
||||
_resizeSpan.className = 'maptalks-plot-text-editor-resize'
|
||||
_resizeSpan.setAttribute('data-id', options['id'])
|
||||
off(_resizeSpan, 'mousedown', this.handleResizeMouseDown_, this)
|
||||
off(_resizeSpan, 'mousemove', this.handleResizeMouseMove_, this)
|
||||
on(_resizeSpan, 'mousedown', this.handleResizeMouseDown_, this)
|
||||
on(_resizeSpan, 'mousemove', this.handleResizeMouseMove_, this)
|
||||
this.element.appendChild(_resizeSpan)
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整大小
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
resizeButtonMoveHandler_ (event) {
|
||||
const pixel_ = event.pixel
|
||||
const element_ = this.getTextAreaFromContent_()
|
||||
if (pixel_.length < 1 || this.currentPixel_.length < 1 || !element_) return
|
||||
const _offset = [pixel_[0] - this.currentPixel_[0], pixel_[1] - this.currentPixel_[1]]
|
||||
const _size = [element_.offsetWidth, element_.offsetHeight]
|
||||
const _width = _size[0] + _offset[0] * 2
|
||||
const _height = _size[1] + _offset[1] * 2
|
||||
setStyle(element_, 'width', _width + 'px')
|
||||
setStyle(element_, 'height', _height + 'px')
|
||||
this.currentPixel_ = pixel_
|
||||
this.getMap().render()
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理移动事件
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
handleResizeMouseMove_ (event) {
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理鼠标按下事件
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
handleResizeMouseDown_ (event) {
|
||||
if (!this.getMap()) return
|
||||
this.currentPixel_ = [event.x, event.y]
|
||||
this.getMap().on('pointermove', this.resizeButtonMoveHandler_, this)
|
||||
on(this.getMap().getViewport(), 'mouseup', this.handleResizeMouseUp_, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理鼠标抬起事件,移除所有事件监听
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
handleResizeMouseUp_ (event) {
|
||||
if (!this.getMap()) return
|
||||
this.getMap().un('pointermove', this.resizeButtonMoveHandler_, this)
|
||||
off(this.getMap().getViewport(), 'mouseup', this.handleResizeMouseUp_, this)
|
||||
this.currentPixel_ = []
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理关闭事件
|
||||
* @param event
|
||||
*/
|
||||
closeCurrentPlotText (event) {
|
||||
if (!this.getMap()) return
|
||||
if (event && hasClass(event.target, 'maptalks-plot-text-editor-close')) {
|
||||
let _id = event.target.getAttribute('data-id')
|
||||
if (_id) {
|
||||
const _overlay = this.getMap().getOverlayById(_id)
|
||||
if (_overlay) {
|
||||
this.getMap().removeOverlay(_overlay)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理获取焦点事件
|
||||
* @private
|
||||
*/
|
||||
handleFocus_ () {
|
||||
this.isFocus_ = true
|
||||
if (this.getMap()) {
|
||||
this.getMap().set('activeTextArea', this)
|
||||
this.getMap().dispatchEvent('activeTextArea')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理失去焦点事件
|
||||
* @private
|
||||
*/
|
||||
handleBlur_ () {
|
||||
this.isFocus_ = false
|
||||
if (this.getMap()) {
|
||||
this.getMap().set('activeTextArea', null)
|
||||
this.getMap().set('disActiveTextArea', this)
|
||||
this.getMap().dispatchEvent('disActiveTextArea')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理拖拽开始
|
||||
* @private
|
||||
*/
|
||||
handleDragStart_ (event) {
|
||||
if (!this.getMap()) return
|
||||
if (!this.dragging_ && this.isMoveModel() && this.isFocus_) {
|
||||
this.handleTimer_ = window.setTimeout(() => {
|
||||
window.clearTimeout(this.handleTimer_)
|
||||
this.handleTimer_ = null
|
||||
if (!this.isClick_) {
|
||||
this.dragging_ = true
|
||||
this.disableMapDragPan()
|
||||
this.preCursor_ = this.element.style.cursor
|
||||
on(this.getMap().getViewport(), 'mousemove', this.handleDragDrag_, this)
|
||||
on(this.element, 'mouseup', this.handleDragEnd_, this)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理拖拽
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
handleDragDrag_ (event) {
|
||||
if (this.dragging_) {
|
||||
this.element.style.cursor = 'move'
|
||||
this._position = this.getMap().getCoordinateFromPixel([event.clientX, event.clientY])
|
||||
this.setPosition(this._position)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理拖拽
|
||||
* @private
|
||||
*/
|
||||
handleDragEnd_ (event) {
|
||||
this.isClick_ = false
|
||||
window.clearTimeout(this.handleTimer_)
|
||||
this.handleTimer_ = null
|
||||
if (this.dragging_ && this.isFocus_) {
|
||||
this.dragging_ = false
|
||||
this.enableMapDragPan()
|
||||
this.element.style.cursor = this.preCursor_
|
||||
off(this.getMap().getViewport(), 'mousemove', this.handleDragDrag_, this)
|
||||
off(this.element, 'mouseup', this.handleDragEnd_, this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理点击事件
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
handleClick_ (event) {
|
||||
if (event.target === this.element) {
|
||||
this.isClick_ = true
|
||||
} else {
|
||||
this.isClick_ = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否处于选择模式
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMoveModel () {
|
||||
const range = window.getSelection().getRangeAt(0)
|
||||
return range.collapsed
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置样式
|
||||
* @param style
|
||||
*/
|
||||
setStyle (style = {}) {
|
||||
const _element = this.getTextAreaFromContent_()
|
||||
if (_element) {
|
||||
for (let key in style) {
|
||||
if (style[key]) {
|
||||
setStyle(_element, key, style[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前样式
|
||||
* @returns {CSSStyleDeclaration}
|
||||
*/
|
||||
getStyle () {
|
||||
const _style = {}
|
||||
const _element = this.getTextAreaFromContent_()
|
||||
if (_element) {
|
||||
for (let key in DEF_TEXT_STYEL) {
|
||||
_style[key] = getStyle(_element, key)
|
||||
}
|
||||
}
|
||||
return _style
|
||||
}
|
||||
|
||||
/**
|
||||
* set value
|
||||
* @param value
|
||||
*/
|
||||
setValue (value) {
|
||||
const _element = this.getTextAreaFromContent_()
|
||||
if (_element) {
|
||||
_element.value = value
|
||||
if (value) {
|
||||
autosize.update(_element)
|
||||
}
|
||||
this.getMap().render()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get value
|
||||
* @returns {*}
|
||||
*/
|
||||
getValue () {
|
||||
const _element = this.getTextAreaFromContent_()
|
||||
if (_element) {
|
||||
return _element.value
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取宽度
|
||||
* @returns {number}
|
||||
*/
|
||||
getWidth () {
|
||||
const element_ = this.getTextAreaFromContent_()
|
||||
if (element_ && element_.offsetWidth) {
|
||||
return element_.offsetWidth
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取高度
|
||||
* @returns {number}
|
||||
*/
|
||||
getHeight () {
|
||||
const element_ = this.getTextAreaFromContent_()
|
||||
if (element_ && element_.offsetHeight) {
|
||||
return element_.offsetHeight
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活地图的拖拽平移
|
||||
*/
|
||||
enableMapDragPan () {
|
||||
const _map = this.getMap()
|
||||
if (!_map) return
|
||||
_map.config({
|
||||
'draggable': this.mapDragPan
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁止地图的拖拽平移
|
||||
*/
|
||||
disableMapDragPan () {
|
||||
const _map = this.getMap()
|
||||
if (!_map) return
|
||||
this.mapDragPan = _map.options['draggable']
|
||||
_map.config({
|
||||
'draggable': false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* set map
|
||||
* @param map
|
||||
*/
|
||||
setMap (map) {
|
||||
maptalks.UIComponent.prototype.addTo.call(this, map)
|
||||
if (map && map instanceof maptalks.Map) {
|
||||
this.setStyle(merge(DEF_TEXT_STYEL, this.options_['style']))
|
||||
this.setValue(this.options_['value'])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default PlotTextBox
|
||||
@ -32,6 +32,8 @@ import FreePolygon from './Polygon/FreePolygon'
|
||||
import RectAngle from './Polygon/RectAngle'
|
||||
import GatheringPlace from './Polygon/GatheringPlace'
|
||||
|
||||
// import TextArea from './Text/PlotTextBox'
|
||||
|
||||
import * as PlotTypes from '../core/PlotTypes'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
const RegisterModes = {}
|
||||
@ -387,5 +389,19 @@ RegisterModes[PlotTypes.ELLIPSE] = {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
// RegisterModes[PlotTypes.TEXTAREA] = {
|
||||
// 'freehand': false,
|
||||
// 'limitClickCount': 2,
|
||||
// 'action': ['click', 'mousemove', 'click'],
|
||||
// 'create': function (path) {
|
||||
// return new RectAngle(path)
|
||||
// },
|
||||
// 'update': function (path, geometry) {
|
||||
// geometry.setPoints(path)
|
||||
// },
|
||||
// 'generate': function (geometry) {
|
||||
// return new TextArea()
|
||||
// }
|
||||
// }
|
||||
|
||||
export default RegisterModes
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import * as utils from './utils'
|
||||
import * as PlotTypes from './core/PlotTypes'
|
||||
import PlotDraw from './core/PlotDraw'
|
||||
import PlotEditor from './core/PlotEditor'
|
||||
|
||||
export {
|
||||
utils,
|
||||
PlotDraw,
|
||||
PlotEditor,
|
||||
PlotTypes
|
||||
|
||||
194
src/utils/dom.js
Normal file
194
src/utils/dom.js
Normal file
@ -0,0 +1,194 @@
|
||||
import { trim, camelCase } from './utils'
|
||||
|
||||
/**
|
||||
* create element
|
||||
* @param tagName
|
||||
* @param className
|
||||
* @param container
|
||||
* @param id
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
const create = function (tagName, className, container, id) {
|
||||
const el = document.createElement(tagName)
|
||||
if (id) el.id = id
|
||||
if (className) addClass(el, className)
|
||||
if (container) {
|
||||
container.appendChild(el)
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
/**
|
||||
* get element
|
||||
* @param selector
|
||||
* @returns {*}
|
||||
*/
|
||||
const getElement = function (selector) {
|
||||
const dom = (function () {
|
||||
let found
|
||||
return (document && /^#([\w-]+)$/.test(selector))
|
||||
? ((found = document.getElementById(RegExp.$1)) ? [found] : [])
|
||||
: Array.prototype.slice.call(/^\.([\w-]+)$/.test(selector)
|
||||
? document.getElementsByClassName(RegExp.$1)
|
||||
: /^[\w-]+$/.test(selector) ? document.getElementsByTagName(selector)
|
||||
: document.querySelectorAll(selector)
|
||||
)
|
||||
})()
|
||||
return dom
|
||||
}
|
||||
|
||||
/**
|
||||
* remove current element
|
||||
* @param node
|
||||
*/
|
||||
const remove = function (node) {
|
||||
return node && node.parentNode ? node.parentNode.removeChild(node) : null
|
||||
}
|
||||
|
||||
/**
|
||||
* clear element child
|
||||
* @param el
|
||||
*/
|
||||
const empty = function (el) {
|
||||
while (el.firstChild) {
|
||||
el.removeChild(el.firstChild)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create hidden element
|
||||
* @param tagName
|
||||
* @param parent
|
||||
* @param id
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
const createHidden = function (tagName, parent, id) {
|
||||
const element = document.createElement(tagName)
|
||||
element.style.display = 'none'
|
||||
if (id) {
|
||||
element.id = id
|
||||
}
|
||||
if (parent) {
|
||||
parent.appendChild(element)
|
||||
}
|
||||
return element
|
||||
}
|
||||
|
||||
/**
|
||||
* check element has class
|
||||
* @param el
|
||||
* @param cls
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasClass = (el, cls) => {
|
||||
if (!el || !cls) return false
|
||||
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.')
|
||||
if (el.classList) {
|
||||
return el.classList.contains(cls)
|
||||
} else {
|
||||
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add class for element
|
||||
* @param el
|
||||
* @param cls
|
||||
*/
|
||||
const addClass = (el, cls) => {
|
||||
if (!el) return
|
||||
let curClass = el.className
|
||||
let classes = (cls || '').split(' ')
|
||||
for (let i = 0, j = classes.length; i < j; i++) {
|
||||
let clsName = classes[i]
|
||||
if (!clsName) continue
|
||||
if (el.classList) {
|
||||
el.classList.add(clsName)
|
||||
} else if (!hasClass(el, clsName)) {
|
||||
curClass += ' ' + clsName
|
||||
}
|
||||
}
|
||||
if (!el.classList) {
|
||||
el.className = curClass
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove element class
|
||||
* @param el
|
||||
* @param cls
|
||||
*/
|
||||
const removeClass = (el, cls) => {
|
||||
if (!el || !cls) return
|
||||
const classes = cls.split(' ')
|
||||
let curClass = ' ' + el.className + ' '
|
||||
for (let i = 0, j = classes.length; i < j; i++) {
|
||||
let clsName = classes[i]
|
||||
if (!clsName) continue
|
||||
if (el.classList) {
|
||||
el.classList.remove(clsName)
|
||||
} else if (hasClass(el, clsName)) {
|
||||
curClass = curClass.replace(' ' + clsName + ' ', ' ')
|
||||
}
|
||||
}
|
||||
if (!el.classList) {
|
||||
el.className = trim(curClass)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get current element style
|
||||
* @param element
|
||||
* @param styleName
|
||||
* @returns {*}
|
||||
*/
|
||||
const getStyle = (element, styleName) => {
|
||||
if (!element || !styleName) return null
|
||||
styleName = camelCase(styleName)
|
||||
if (styleName === 'float') {
|
||||
styleName = 'cssFloat'
|
||||
}
|
||||
try {
|
||||
const computed = document.defaultView.getComputedStyle(element, '')
|
||||
return element.style[styleName] || computed ? computed[styleName] : null
|
||||
} catch (e) {
|
||||
return element.style[styleName]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set dom style
|
||||
* @param element
|
||||
* @param styleName
|
||||
* @param value
|
||||
*/
|
||||
const setStyle = (element, styleName, value) => {
|
||||
if (!element || !styleName) return
|
||||
if (typeof styleName === 'object') {
|
||||
for (let prop in styleName) {
|
||||
if (styleName.hasOwnProperty(prop)) {
|
||||
setStyle(element, prop, styleName[prop])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
styleName = camelCase(styleName)
|
||||
if (styleName === 'opacity') {
|
||||
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')'
|
||||
} else {
|
||||
element.style[styleName] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
create,
|
||||
getElement,
|
||||
remove,
|
||||
empty,
|
||||
createHidden,
|
||||
hasClass,
|
||||
addClass,
|
||||
removeClass,
|
||||
getStyle,
|
||||
setStyle
|
||||
}
|
||||
128
src/utils/events.js
Normal file
128
src/utils/events.js
Normal file
@ -0,0 +1,128 @@
|
||||
import { stamp } from './utils'
|
||||
|
||||
/**
|
||||
* 获取事件唯一标识
|
||||
* @param type
|
||||
* @param fn
|
||||
* @param context
|
||||
* @returns {string}
|
||||
*/
|
||||
const getDomEventKey = (type, fn, context) => {
|
||||
return '_dom_event_' + type + '_' + stamp(fn) + (context ? '_' + stamp(context) : '')
|
||||
}
|
||||
|
||||
/**
|
||||
* 对DOM对象添加事件监听
|
||||
* @param element
|
||||
* @param type
|
||||
* @param fn
|
||||
* @param context
|
||||
* @param isOnce
|
||||
* @returns {*}
|
||||
*/
|
||||
const addListener = function (element, type, fn, context, isOnce) {
|
||||
let eventKey = getDomEventKey(type, fn, context)
|
||||
let handler = element[eventKey]
|
||||
if (handler) {
|
||||
if (!isOnce) {
|
||||
handler.callOnce = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
handler = function (e) {
|
||||
return fn.call(context || element, e)
|
||||
}
|
||||
if ('addEventListener' in element) {
|
||||
element.addEventListener(type, handler, false)
|
||||
} else if ('attachEvent' in element) {
|
||||
element.attachEvent('on' + type, handler)
|
||||
}
|
||||
element[eventKey] = handler
|
||||
return this
|
||||
}
|
||||
|
||||
const on = addListener
|
||||
|
||||
/**
|
||||
* 移除DOM对象监听事件
|
||||
* @param element
|
||||
* @param type
|
||||
* @param fn
|
||||
* @param context
|
||||
* @returns {removeListener}
|
||||
*/
|
||||
const removeListener = function (element, type, fn, context) {
|
||||
let eventKey = getDomEventKey(type, fn, context)
|
||||
let handler = element[eventKey]
|
||||
if (!handler) {
|
||||
return this
|
||||
}
|
||||
if ('removeEventListener' in element) {
|
||||
element.removeEventListener(type, handler, false)
|
||||
} else if ('detachEvent' in element) {
|
||||
element.detachEvent('on' + type, handler)
|
||||
}
|
||||
element[eventKey] = null
|
||||
return this
|
||||
}
|
||||
|
||||
const off = removeListener
|
||||
|
||||
/**
|
||||
* attach events once
|
||||
* @param element
|
||||
* @param type
|
||||
* @param fn
|
||||
* @param context
|
||||
* @returns {*}
|
||||
*/
|
||||
const once = function (element, type, fn, context) {
|
||||
return addListener(element, type, fn, context, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent default behavior of the browser.
|
||||
* @param event
|
||||
* @returns {preventDefault}
|
||||
*/
|
||||
const preventDefault = function (event) {
|
||||
if (event.preventDefault) {
|
||||
event.preventDefault()
|
||||
} else {
|
||||
event.returnValue = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop browser event propagation
|
||||
* @param event
|
||||
* @returns {stopPropagation}
|
||||
*/
|
||||
const stopPropagation = function (event) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation()
|
||||
} else {
|
||||
event.cancelBubble = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents other listeners of the same event from being called.
|
||||
* @param event
|
||||
*/
|
||||
const stopImmediatePropagation = function (event) {
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
export {
|
||||
on,
|
||||
once,
|
||||
addListener,
|
||||
off,
|
||||
removeListener,
|
||||
preventDefault,
|
||||
stopPropagation,
|
||||
stopImmediatePropagation
|
||||
}
|
||||
4
src/utils/index.js
Normal file
4
src/utils/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './utils'
|
||||
export * from './dom'
|
||||
export * from './events'
|
||||
export { default as uuid } from './uuid'
|
||||
@ -1,14 +1,72 @@
|
||||
import uuid from './uuid'
|
||||
/* eslint no-useless-escape: "off" */
|
||||
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g
|
||||
const MOZ_HACK_REGEXP = /^moz([A-Z])/
|
||||
|
||||
const trim = function (string) {
|
||||
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* stamp string
|
||||
* @param obj
|
||||
* @returns {*}
|
||||
*/
|
||||
const stamp = function (obj) {
|
||||
let key = '_event_id_'
|
||||
obj[key] = obj[key] || (uuid())
|
||||
return obj[key]
|
||||
}
|
||||
|
||||
/**
|
||||
* check case
|
||||
* @param name
|
||||
* @returns {string}
|
||||
*/
|
||||
const camelCase = function (name) {
|
||||
return name.replace(SPECIAL_CHARS_REGEXP, function (_, separator, letter, offset) {
|
||||
return offset ? letter.toUpperCase() : letter
|
||||
}).replace(MOZ_HACK_REGEXP, 'Moz$1')
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为对象
|
||||
* @param value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isObject = value => {
|
||||
const isObject = value => {
|
||||
const type = typeof value
|
||||
return value !== null && (type === 'object' || type === 'function')
|
||||
}
|
||||
|
||||
export const merge = (a, b) => {
|
||||
/**
|
||||
* 判断是否为合法字符串
|
||||
* @param value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isString = (value) => {
|
||||
if (value == null) {
|
||||
return false
|
||||
}
|
||||
return typeof value === 'string' || (value.constructor !== null && value.constructor === String)
|
||||
}
|
||||
|
||||
/**
|
||||
* check is number
|
||||
* @param val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isNumber = (val) => {
|
||||
return typeof val === 'number' && !isNaN(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* merge
|
||||
* @param a
|
||||
* @param b
|
||||
* @returns {*}
|
||||
*/
|
||||
const merge = (a, b) => {
|
||||
for (const key in b) {
|
||||
if (isObject(b[key]) && isObject(a[key])) {
|
||||
merge(a[key], b[key])
|
||||
@ -18,3 +76,13 @@ export const merge = (a, b) => {
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
export {
|
||||
merge,
|
||||
trim,
|
||||
stamp,
|
||||
isString,
|
||||
isObject,
|
||||
camelCase,
|
||||
isNumber
|
||||
}
|
||||
|
||||
67
src/utils/uuid.js
Normal file
67
src/utils/uuid.js
Normal file
@ -0,0 +1,67 @@
|
||||
const byteToHex = []
|
||||
const rnds = new Array(16)
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
byteToHex[i] = (i + 0x100).toString(16).substr(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* form uuid
|
||||
* Convert array of 16 byte values to UUID string format of the form:
|
||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
* @param buf
|
||||
* @param offset
|
||||
* @returns {string}
|
||||
*/
|
||||
const bytesToUuid = (buf, offset) => {
|
||||
let i = offset || 0
|
||||
const bth = byteToHex
|
||||
return bth[buf[i++]] + bth[buf[i++]] +
|
||||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||
bth[buf[i++]] + bth[buf[i++]] +
|
||||
bth[buf[i++]] + bth[buf[i++]] +
|
||||
bth[buf[i++]] + bth[buf[i++]]
|
||||
}
|
||||
|
||||
/**
|
||||
* math rng
|
||||
* @returns {any[]}
|
||||
*/
|
||||
const mathRNG = () => {
|
||||
for (let i = 0, r; i < 16; i++) {
|
||||
if ((i & 0x03) === 0) r = Math.random() * 0x100000000
|
||||
rnds[i] = r >>> ((i & 0x03) << 3) & 0xff
|
||||
}
|
||||
return rnds
|
||||
}
|
||||
|
||||
/**
|
||||
* get uuid
|
||||
* @param options
|
||||
* @param buf
|
||||
* @param offset
|
||||
* @returns {*|string}
|
||||
*/
|
||||
const uuid = (options, buf, offset) => {
|
||||
/* eslint-disable */
|
||||
const i = buf && offset || 0
|
||||
if (typeof (options) === 'string') {
|
||||
buf = options === 'binary' ? new Array(16) : null
|
||||
options = null
|
||||
}
|
||||
options = options || {}
|
||||
const rnds = options.random || (options.rng || mathRNG)()
|
||||
rnds[6] = (rnds[6] & 0x0f) | 0x40
|
||||
rnds[8] = (rnds[8] & 0x3f) | 0x80
|
||||
// Copy bytes to buffer, if provided
|
||||
if (buf) {
|
||||
for (let ii = 0; ii < 16; ++ii) {
|
||||
buf[i + ii] = rnds[ii]
|
||||
}
|
||||
}
|
||||
return buf || bytesToUuid(rnds)
|
||||
}
|
||||
|
||||
export default uuid
|
||||
133
yarn.lock
133
yarn.lock
@ -17,22 +17,32 @@ accepts@1.3.3:
|
||||
mime-types "~2.1.11"
|
||||
negotiator "0.6.1"
|
||||
|
||||
acorn-jsx@^3.0.0, acorn-jsx@^3.0.1:
|
||||
acorn-dynamic-import@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "http://registry.npm.taobao.org/acorn-dynamic-import/download/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278"
|
||||
dependencies:
|
||||
acorn "^5.0.0"
|
||||
|
||||
acorn-jsx@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "http://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
|
||||
dependencies:
|
||||
acorn "^3.0.4"
|
||||
|
||||
acorn-object-spread@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "http://registry.npm.taobao.org/acorn-object-spread/download/acorn-object-spread-1.0.0.tgz#48ead0f4a8eb16995a17a0db9ffc6acaada4ba68"
|
||||
acorn-jsx@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "http://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
|
||||
dependencies:
|
||||
acorn "^3.1.0"
|
||||
acorn "^5.0.3"
|
||||
|
||||
acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0:
|
||||
acorn@^3.0.4:
|
||||
version "3.3.0"
|
||||
resolved "http://registry.npm.taobao.org/acorn/download/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
|
||||
|
||||
acorn@^5.0.0, acorn@^5.0.3, acorn@^5.4.1:
|
||||
version "5.4.1"
|
||||
resolved "http://registry.npm.taobao.org/acorn/download/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102"
|
||||
|
||||
acorn@^5.2.1:
|
||||
version "5.3.0"
|
||||
resolved "http://registry.npm.taobao.org/acorn/download/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
|
||||
@ -89,7 +99,7 @@ ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "http://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
ansi-styles@^3.1.0:
|
||||
ansi-styles@^3.1.0, ansi-styles@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "http://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
|
||||
dependencies:
|
||||
@ -218,6 +228,10 @@ atob@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "http://registry.npm.taobao.org/atob/download/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
|
||||
|
||||
autosize@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "http://registry.npm.taobao.org/autosize/download/autosize-4.0.0.tgz#7a0599b1ba84d73bd7589b0d9da3870152c69237"
|
||||
|
||||
aws-sign2@~0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "http://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
|
||||
@ -942,28 +956,22 @@ braces@^2.3.0:
|
||||
split-string "^3.0.2"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
browser-resolve@^1.11.0:
|
||||
version "1.11.2"
|
||||
resolved "http://registry.npm.taobao.org/browser-resolve/download/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
|
||||
dependencies:
|
||||
resolve "1.1.7"
|
||||
|
||||
browser-stdout@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "http://registry.npm.taobao.org/browser-stdout/download/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
||||
|
||||
buble@^0.16.0:
|
||||
version "0.16.0"
|
||||
resolved "http://registry.npm.taobao.org/buble/download/buble-0.16.0.tgz#1773e7b5a383f5c722af6b1b16b2ba49cb866a98"
|
||||
buble@^0.19.2:
|
||||
version "0.19.3"
|
||||
resolved "http://registry.npm.taobao.org/buble/download/buble-0.19.3.tgz#01e9412062cff1da6f20342b6ecd72e7bf699d02"
|
||||
dependencies:
|
||||
acorn "^3.3.0"
|
||||
acorn-jsx "^3.0.1"
|
||||
acorn-object-spread "^1.0.0"
|
||||
chalk "^1.1.3"
|
||||
magic-string "^0.14.0"
|
||||
acorn "^5.4.1"
|
||||
acorn-dynamic-import "^3.0.0"
|
||||
acorn-jsx "^4.1.1"
|
||||
chalk "^2.3.1"
|
||||
magic-string "^0.22.4"
|
||||
minimist "^1.2.0"
|
||||
os-homedir "^1.0.1"
|
||||
vlq "^0.2.2"
|
||||
vlq "^1.0.0"
|
||||
|
||||
build@^0.1.4:
|
||||
version "0.1.4"
|
||||
@ -1060,6 +1068,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^4.0.0"
|
||||
|
||||
chalk@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "http://registry.npm.taobao.org/chalk/download/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.2.0"
|
||||
|
||||
chardet@^0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "http://registry.npm.taobao.org/chardet/download/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
|
||||
@ -1191,9 +1207,9 @@ commander@2.9.0:
|
||||
dependencies:
|
||||
graceful-readlink ">= 1.0.0"
|
||||
|
||||
commander@~2.12.1:
|
||||
version "2.12.2"
|
||||
resolved "http://registry.npm.taobao.org/commander/download/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
|
||||
commander@~2.14.1:
|
||||
version "2.14.1"
|
||||
resolved "http://registry.npm.taobao.org/commander/download/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
@ -2170,6 +2186,10 @@ has-flag@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "http://registry.npm.taobao.org/has-flag/download/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "http://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
|
||||
has-unicode@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "http://registry.npm.taobao.org/has-unicode/download/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||
@ -3009,12 +3029,6 @@ lru-cache@^4.0.1:
|
||||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
magic-string@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "http://registry.npm.taobao.org/magic-string/download/magic-string-0.14.0.tgz#57224aef1701caeed273b17a39a956e72b172462"
|
||||
dependencies:
|
||||
vlq "^0.2.1"
|
||||
|
||||
magic-string@^0.22.4:
|
||||
version "0.22.4"
|
||||
resolved "http://registry.npm.taobao.org/magic-string/download/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff"
|
||||
@ -3047,9 +3061,9 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
maptalks@^0.37.0-alpha.1:
|
||||
version "0.37.0-alpha.1"
|
||||
resolved "http://registry.npm.taobao.org/maptalks/download/maptalks-0.37.0-alpha.1.tgz#e13f58e037101d184ae1f600cd3eac7ca580b508"
|
||||
maptalks@^0.38.2:
|
||||
version "0.38.2"
|
||||
resolved "http://registry.npm.taobao.org/maptalks/download/maptalks-0.38.2.tgz#8aff032d57227560a7e22af502495751c39791da"
|
||||
dependencies:
|
||||
simplify-js "^1.2.1"
|
||||
zousan "^2.3.3"
|
||||
@ -3868,7 +3882,7 @@ resolve-url@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "http://registry.npm.taobao.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
|
||||
resolve@1.1.7, resolve@1.1.x:
|
||||
resolve@1.1.x:
|
||||
version "1.1.7"
|
||||
resolved "http://registry.npm.taobao.org/resolve/download/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
|
||||
@ -3897,22 +3911,22 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.0, rimraf@^2.6.1:
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
rollup-plugin-babel@^3.0.2:
|
||||
rollup-plugin-babel@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-babel/download/rollup-plugin-babel-3.0.3.tgz#63adedc863130327512a4a9006efc2241c5b7c15"
|
||||
dependencies:
|
||||
rollup-pluginutils "^1.5.0"
|
||||
|
||||
rollup-plugin-buble@^0.16.0:
|
||||
version "0.16.0"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-buble/download/rollup-plugin-buble-0.16.0.tgz#3c66e2f4703527f5d27a4054f97d5eef463c5bb8"
|
||||
rollup-plugin-buble@^0.19.2:
|
||||
version "0.19.2"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-buble/download/rollup-plugin-buble-0.19.2.tgz#c0590c7d3d475b5ed59f129764ec93710cc6e8dd"
|
||||
dependencies:
|
||||
buble "^0.16.0"
|
||||
buble "^0.19.2"
|
||||
rollup-pluginutils "^2.0.1"
|
||||
|
||||
rollup-plugin-commonjs@^8.2.6:
|
||||
version "8.2.6"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-commonjs/download/rollup-plugin-commonjs-8.2.6.tgz#27e5b9069ff94005bb01e01bb46a1e4873784677"
|
||||
rollup-plugin-commonjs@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-commonjs/download/rollup-plugin-commonjs-8.3.0.tgz#91b4ba18f340951e39ed7b1901f377a80ab3f9c3"
|
||||
dependencies:
|
||||
acorn "^5.2.1"
|
||||
estree-walker "^0.5.0"
|
||||
@ -3931,11 +3945,10 @@ rollup-plugin-local-resolve@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-local-resolve/download/rollup-plugin-local-resolve-1.0.7.tgz#c486701716c15add2127565c2eaa101123320887"
|
||||
|
||||
rollup-plugin-node-resolve@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-node-resolve/download/rollup-plugin-node-resolve-3.0.0.tgz#8b897c4c3030d5001277b0514b25d2ca09683ee0"
|
||||
rollup-plugin-node-resolve@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "http://registry.npm.taobao.org/rollup-plugin-node-resolve/download/rollup-plugin-node-resolve-3.0.3.tgz#8f57b253edd00e5b0ad0aed7b7e9cf5982e98fa4"
|
||||
dependencies:
|
||||
browser-resolve "^1.11.0"
|
||||
builtin-modules "^1.1.0"
|
||||
is-module "^1.0.0"
|
||||
resolve "^1.1.6"
|
||||
@ -3970,9 +3983,9 @@ rollup-watch@^4.3.1:
|
||||
require-relative "0.8.7"
|
||||
rollup-pluginutils "^2.0.1"
|
||||
|
||||
rollup@^0.50.0:
|
||||
version "0.50.1"
|
||||
resolved "http://registry.npm.taobao.org/rollup/download/rollup-0.50.1.tgz#e4dafcbf8d2bb0d9f5589d0cc6f64d76b8815730"
|
||||
rollup@^0.56.1:
|
||||
version "0.56.1"
|
||||
resolved "http://registry.npm.taobao.org/rollup/download/rollup-0.56.1.tgz#87dd6295103da48c2376872836273785ffe0def3"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
@ -4353,6 +4366,12 @@ supports-color@^4.0.0:
|
||||
dependencies:
|
||||
has-flag "^2.0.0"
|
||||
|
||||
supports-color@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "http://registry.npm.taobao.org/supports-color/download/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
table@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "http://registry.npm.taobao.org/table/download/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
|
||||
@ -4518,11 +4537,11 @@ uglify-js@^2.6:
|
||||
optionalDependencies:
|
||||
uglify-to-browserify "~1.0.0"
|
||||
|
||||
uglify-js@^3.1.2:
|
||||
version "3.3.5"
|
||||
resolved "http://registry.npm.taobao.org/uglify-js/download/uglify-js-3.3.5.tgz#4c4143dfe08e8825746675cc49a6874a933b543e"
|
||||
uglify-js@^3.3.11:
|
||||
version "3.3.11"
|
||||
resolved "http://registry.npm.taobao.org/uglify-js/download/uglify-js-3.3.11.tgz#e9d058b20715138bb4e8e5cae2ea581686bdaae3"
|
||||
dependencies:
|
||||
commander "~2.12.1"
|
||||
commander "~2.14.1"
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-to-browserify@~1.0.0:
|
||||
@ -4607,10 +4626,14 @@ verror@1.10.0:
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vlq@^0.2.1, vlq@^0.2.2:
|
||||
vlq@^0.2.1:
|
||||
version "0.2.3"
|
||||
resolved "http://registry.npm.taobao.org/vlq/download/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
|
||||
|
||||
vlq@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "http://registry.npm.taobao.org/vlq/download/vlq-1.0.0.tgz#8101be90843422954c2b13eb27f2f3122bdcc806"
|
||||
|
||||
void-elements@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "http://registry.npm.taobao.org/void-elements/download/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user