├── .gitignore
├── .npmignore
├── .npmrc
├── README.md
├── babel.config.js
├── dist
├── view-line.css
└── view-line.js
├── package.json
├── sample
├── index.ts
├── move.gif
├── resize.gif
└── tmp.html
├── src
├── constants.ts
├── index.less
├── index.ts
├── lines
│ ├── align.ts
│ ├── distance.ts
│ ├── label.ts
│ ├── lib.ts
│ ├── space.ts
│ └── store.ts
├── move.ts
├── resize.ts
└── types.ts
├── tsconfig.json
├── tslint.json
├── webpack.base.config.js
├── webpack.dev.config.js
└── webpack.prod.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | .project
3 |
4 | # Github defaults only below this comment
5 |
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 |
11 | # Runtime data
12 | pids
13 | *.pid
14 | *.seed
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # node-waf configuration
23 | .lock-wscript
24 |
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 |
28 | # Dependency directory
29 | node_modules
30 | node_modules2
31 | # Optional npm cache directory
32 | .npm
33 |
34 |
35 | # Optional REPL history
36 | .node_repl_history
37 |
38 | # WebStorm
39 | .idea/
40 | .DS_Store
41 |
42 | # VsCode
43 | .vscode
44 |
45 | dist
46 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | src/
3 | tests/
4 | sample/
5 | __tests__/
6 | node_modules/
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 | package-lock.json*
11 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | # registry = https://registry.npm.taobao.org
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # view-line
2 |
3 | Use this library to add alignment lines, spacing blocks, adsorption to the free canvas
4 |
5 | ## 安装
6 | ```
7 | npm install view-line --save
8 | ```
9 | ## 使用
10 |
11 | Move view dom element:
12 |
13 | ```js
14 | import { moveByDom, resizeByDom, initLine } from 'view-line';
15 | import 'view-line/dist/view-line.css';
16 | moveByDom(view, top, left, function (top, left) {
17 | console.log(top, left);
18 | });
19 | ```
20 |
21 | Resize view dom element:
22 |
23 | ```js
24 | import { moveByDom, resizeByDom, initLine } from 'view-line';
25 | import 'view-line/dist/view-line.css';
26 | resizeByDom(view, top, left, height, width, function (top, left, height, width) {
27 | console.log(top, left, height, width);
28 | });
29 | ```
30 |
31 | ## API说明
32 |
33 | ### moveByDom(dom,top,left,onMoveEnd): Move elements to show alignment lines
34 |
35 | - dom: The dom element draged
36 | - top: The top value of the element relative to the container
37 | - left: The left value of the element relative to the container
38 | - onMoveEnd: Callback function for the end of the drag and drop, returning the last top and left
39 |
40 | ### resizeByDom(dom,top,left,height,width,onResizeEnd): Resize elements to show alignment lines
41 |
42 | - dom: The dom element resized
43 | - top: The top value of the element relative to the container
44 | - left: The left value of the element relative to the container
45 | - height: The height of element
46 | - width: The width of element
47 | - onResizeEnd: Callback function for the end of the drag and drop, returning the last top and left
48 |
49 |
50 | ## Example
51 |
52 | Run `npm run dev` under `sample` folder
53 |
54 | The rendering is as follows:
55 |
56 | Alignment line:
57 |
58 | 
59 |
60 | Spacing adsorption:
61 |
62 | 
63 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 |
4 | const presets = [
5 | ["@babel/preset-env",{
6 | targets:{
7 | browsers:'last 2 versions,ie >= 9'
8 | },
9 | modules:false,
10 | }],
11 | "@babel/preset-typescript"
12 | ];
13 | const plugins = [
14 | "@babel/plugin-transform-runtime",
15 | "@babel/plugin-proposal-class-properties",
16 | ];
17 |
18 | return {
19 | presets,
20 | plugins
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/dist/view-line.css:
--------------------------------------------------------------------------------
1 | .view__lines {
2 | display: none;
3 | pointer-events: none;
4 | }
5 | .view__lines i.line {
6 | position: absolute;
7 | }
8 | .view__lines .t {
9 | top: 0px;
10 | left: 0;
11 | right: 0;
12 | height: 0;
13 | width: auto;
14 | border: 0;
15 | border-top: 1px solid red;
16 | z-index: 10 ;
17 | }
18 | .view__lines .r {
19 | right: 0;
20 | top: 0;
21 | bottom: 0;
22 | width: 0;
23 | height: auto;
24 | border: 0;
25 | border-right: 1px solid red;
26 | z-index: 10 ;
27 | }
28 | .view__lines .b {
29 | bottom: 0;
30 | left: 0;
31 | right: 0;
32 | height: 0;
33 | width: auto;
34 | border: 0;
35 | border-bottom: 1px solid red;
36 | z-index: 10 ;
37 | }
38 | .view__lines .l {
39 | left: 0;
40 | top: 0;
41 | bottom: 0;
42 | height: auto;
43 | width: 0;
44 | border: 0;
45 | border-left: 1px solid red;
46 | z-index: 10 ;
47 | }
48 | .view__resize-label {
49 | position: fixed;
50 | height: 24px;
51 | padding: 0 5px;
52 | display: inline-block;
53 | line-height: 24px;
54 | font-size: 12px;
55 | z-index: 999;
56 | background: #FB7055;
57 | border-radius: 3px;
58 | color: #fff;
59 | transform: translateX(-50%);
60 | }
61 | .view__v-line {
62 | position: fixed;
63 | width: 0;
64 | border-left: 1px solid red;
65 | z-index: 999;
66 | pointer-events: none;
67 | }
68 | .view__h-line {
69 | position: fixed;
70 | height: 0;
71 | border-top: 1px solid red;
72 | z-index: 999;
73 | pointer-events: none;
74 | }
75 | .view__h-dist-line {
76 | position: fixed;
77 | height: 0;
78 | border-top: 1px dashed #adadad;
79 | z-index: 999;
80 | text-align: center;
81 | pointer-events: none;
82 | }
83 | .view__h-dist-line .label {
84 | position: absolute;
85 | left: 50%;
86 | top: -4px;
87 | height: 14px;
88 | display: inline-block;
89 | line-height: 14px;
90 | text-align: center;
91 | background: #FB7055;
92 | transform: translate(-50%, -100%);
93 | color: #fff;
94 | padding: 0 5px;
95 | pointer-events: none;
96 | border-radius: 7px;
97 | }
98 | .view__v-dist-line {
99 | position: fixed;
100 | width: 0;
101 | border-left: 1px dashed #adadad;
102 | z-index: 999;
103 | text-align: center;
104 | pointer-events: none;
105 | }
106 | .view__v-dist-line .label {
107 | position: absolute;
108 | top: 50%;
109 | left: -4px;
110 | height: 14px;
111 | display: inline-block;
112 | line-height: 14px;
113 | text-align: center;
114 | background: #FB7055;
115 | transform: translate(-100%, -50%);
116 | color: #fff;
117 | padding: 0 5px;
118 | border-radius: 7px;
119 | }
120 | .view__h-space-line {
121 | position: fixed;
122 | height: 0;
123 | z-index: 999;
124 | text-align: center;
125 | pointer-events: none;
126 | transform: translateY(-50%);
127 | background: #FB7055;
128 | opacity: 0.4;
129 | line-height: 100%;
130 | }
131 | .view__h-space-line .line {
132 | position: absolute;
133 | top: 50%;
134 | left: 0;
135 | right: 0;
136 | height: 0;
137 | pointer-events: none;
138 | }
139 | .view__v-space-line {
140 | position: fixed;
141 | z-index: 999;
142 | text-align: center;
143 | pointer-events: none;
144 | transform: translateX(-50%);
145 | background: #FB7055;
146 | opacity: 0.4;
147 | }
148 | .view__v-space-line .line {
149 | position: absolute;
150 | left: 50%;
151 | top: 0;
152 | bottom: 0;
153 | width: 0;
154 | pointer-events: none;
155 | }
156 |
157 |
--------------------------------------------------------------------------------
/dist/view-line.js:
--------------------------------------------------------------------------------
1 | (function webpackUniversalModuleDefinition(root, factory) {
2 | if(typeof exports === 'object' && typeof module === 'object')
3 | module.exports = factory();
4 | else if(typeof define === 'function' && define.amd)
5 | define([], factory);
6 | else if(typeof exports === 'object')
7 | exports["ViewLine"] = factory();
8 | else
9 | root["ViewLine"] = factory();
10 | })(window, function() {
11 | return /******/ (function(modules) { // webpackBootstrap
12 | /******/ // The module cache
13 | /******/ var installedModules = {};
14 | /******/
15 | /******/ // The require function
16 | /******/ function __webpack_require__(moduleId) {
17 | /******/
18 | /******/ // Check if module is in cache
19 | /******/ if(installedModules[moduleId]) {
20 | /******/ return installedModules[moduleId].exports;
21 | /******/ }
22 | /******/ // Create a new module (and put it into the cache)
23 | /******/ var module = installedModules[moduleId] = {
24 | /******/ i: moduleId,
25 | /******/ l: false,
26 | /******/ exports: {}
27 | /******/ };
28 | /******/
29 | /******/ // Execute the module function
30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31 | /******/
32 | /******/ // Flag the module as loaded
33 | /******/ module.l = true;
34 | /******/
35 | /******/ // Return the exports of the module
36 | /******/ return module.exports;
37 | /******/ }
38 | /******/
39 | /******/
40 | /******/ // expose the modules object (__webpack_modules__)
41 | /******/ __webpack_require__.m = modules;
42 | /******/
43 | /******/ // expose the module cache
44 | /******/ __webpack_require__.c = installedModules;
45 | /******/
46 | /******/ // define getter function for harmony exports
47 | /******/ __webpack_require__.d = function(exports, name, getter) {
48 | /******/ if(!__webpack_require__.o(exports, name)) {
49 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
50 | /******/ }
51 | /******/ };
52 | /******/
53 | /******/ // define __esModule on exports
54 | /******/ __webpack_require__.r = function(exports) {
55 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
56 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
57 | /******/ }
58 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
59 | /******/ };
60 | /******/
61 | /******/ // create a fake namespace object
62 | /******/ // mode & 1: value is a module id, require it
63 | /******/ // mode & 2: merge all properties of value into the ns
64 | /******/ // mode & 4: return value when already ns object
65 | /******/ // mode & 8|1: behave like require
66 | /******/ __webpack_require__.t = function(value, mode) {
67 | /******/ if(mode & 1) value = __webpack_require__(value);
68 | /******/ if(mode & 8) return value;
69 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
70 | /******/ var ns = Object.create(null);
71 | /******/ __webpack_require__.r(ns);
72 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
73 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
74 | /******/ return ns;
75 | /******/ };
76 | /******/
77 | /******/ // getDefaultExport function for compatibility with non-harmony modules
78 | /******/ __webpack_require__.n = function(module) {
79 | /******/ var getter = module && module.__esModule ?
80 | /******/ function getDefault() { return module['default']; } :
81 | /******/ function getModuleExports() { return module; };
82 | /******/ __webpack_require__.d(getter, 'a', getter);
83 | /******/ return getter;
84 | /******/ };
85 | /******/
86 | /******/ // Object.prototype.hasOwnProperty.call
87 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
88 | /******/
89 | /******/ // __webpack_public_path__
90 | /******/ __webpack_require__.p = "";
91 | /******/
92 | /******/
93 | /******/ // Load entry module and return exports
94 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.ts");
95 | /******/ })
96 | /************************************************************************/
97 | /******/ ({
98 |
99 | /***/ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js":
100 | /*!*****************************************************************!*\
101 | !*** ./node_modules/@babel/runtime/helpers/arrayLikeToArray.js ***!
102 | \*****************************************************************/
103 | /*! no static exports found */
104 | /***/ (function(module, exports) {
105 |
106 | function _arrayLikeToArray(arr, len) {
107 | if (len == null || len > arr.length) len = arr.length;
108 |
109 | for (var i = 0, arr2 = new Array(len); i < len; i++) {
110 | arr2[i] = arr[i];
111 | }
112 |
113 | return arr2;
114 | }
115 |
116 | module.exports = _arrayLikeToArray;
117 |
118 | /***/ }),
119 |
120 | /***/ "./node_modules/@babel/runtime/helpers/arrayWithHoles.js":
121 | /*!***************************************************************!*\
122 | !*** ./node_modules/@babel/runtime/helpers/arrayWithHoles.js ***!
123 | \***************************************************************/
124 | /*! no static exports found */
125 | /***/ (function(module, exports) {
126 |
127 | function _arrayWithHoles(arr) {
128 | if (Array.isArray(arr)) return arr;
129 | }
130 |
131 | module.exports = _arrayWithHoles;
132 |
133 | /***/ }),
134 |
135 | /***/ "./node_modules/@babel/runtime/helpers/defineProperty.js":
136 | /*!***************************************************************!*\
137 | !*** ./node_modules/@babel/runtime/helpers/defineProperty.js ***!
138 | \***************************************************************/
139 | /*! no static exports found */
140 | /***/ (function(module, exports) {
141 |
142 | function _defineProperty(obj, key, value) {
143 | if (key in obj) {
144 | Object.defineProperty(obj, key, {
145 | value: value,
146 | enumerable: true,
147 | configurable: true,
148 | writable: true
149 | });
150 | } else {
151 | obj[key] = value;
152 | }
153 |
154 | return obj;
155 | }
156 |
157 | module.exports = _defineProperty;
158 |
159 | /***/ }),
160 |
161 | /***/ "./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js":
162 | /*!*********************************************************************!*\
163 | !*** ./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js ***!
164 | \*********************************************************************/
165 | /*! no static exports found */
166 | /***/ (function(module, exports) {
167 |
168 | function _iterableToArrayLimit(arr, i) {
169 | if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
170 | var _arr = [];
171 | var _n = true;
172 | var _d = false;
173 | var _e = undefined;
174 |
175 | try {
176 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
177 | _arr.push(_s.value);
178 |
179 | if (i && _arr.length === i) break;
180 | }
181 | } catch (err) {
182 | _d = true;
183 | _e = err;
184 | } finally {
185 | try {
186 | if (!_n && _i["return"] != null) _i["return"]();
187 | } finally {
188 | if (_d) throw _e;
189 | }
190 | }
191 |
192 | return _arr;
193 | }
194 |
195 | module.exports = _iterableToArrayLimit;
196 |
197 | /***/ }),
198 |
199 | /***/ "./node_modules/@babel/runtime/helpers/nonIterableRest.js":
200 | /*!****************************************************************!*\
201 | !*** ./node_modules/@babel/runtime/helpers/nonIterableRest.js ***!
202 | \****************************************************************/
203 | /*! no static exports found */
204 | /***/ (function(module, exports) {
205 |
206 | function _nonIterableRest() {
207 | throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
208 | }
209 |
210 | module.exports = _nonIterableRest;
211 |
212 | /***/ }),
213 |
214 | /***/ "./node_modules/@babel/runtime/helpers/slicedToArray.js":
215 | /*!**************************************************************!*\
216 | !*** ./node_modules/@babel/runtime/helpers/slicedToArray.js ***!
217 | \**************************************************************/
218 | /*! no static exports found */
219 | /***/ (function(module, exports, __webpack_require__) {
220 |
221 | var arrayWithHoles = __webpack_require__(/*! ./arrayWithHoles */ "./node_modules/@babel/runtime/helpers/arrayWithHoles.js");
222 |
223 | var iterableToArrayLimit = __webpack_require__(/*! ./iterableToArrayLimit */ "./node_modules/@babel/runtime/helpers/iterableToArrayLimit.js");
224 |
225 | var unsupportedIterableToArray = __webpack_require__(/*! ./unsupportedIterableToArray */ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js");
226 |
227 | var nonIterableRest = __webpack_require__(/*! ./nonIterableRest */ "./node_modules/@babel/runtime/helpers/nonIterableRest.js");
228 |
229 | function _slicedToArray(arr, i) {
230 | return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
231 | }
232 |
233 | module.exports = _slicedToArray;
234 |
235 | /***/ }),
236 |
237 | /***/ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js":
238 | /*!***************************************************************************!*\
239 | !*** ./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js ***!
240 | \***************************************************************************/
241 | /*! no static exports found */
242 | /***/ (function(module, exports, __webpack_require__) {
243 |
244 | var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js");
245 |
246 | function _unsupportedIterableToArray(o, minLen) {
247 | if (!o) return;
248 | if (typeof o === "string") return arrayLikeToArray(o, minLen);
249 | var n = Object.prototype.toString.call(o).slice(8, -1);
250 | if (n === "Object" && o.constructor) n = o.constructor.name;
251 | if (n === "Map" || n === "Set") return Array.from(o);
252 | if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
253 | }
254 |
255 | module.exports = _unsupportedIterableToArray;
256 |
257 | /***/ }),
258 |
259 | /***/ "./src/constants.ts":
260 | /*!**************************!*\
261 | !*** ./src/constants.ts ***!
262 | \**************************/
263 | /*! exports provided: DIST */
264 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
265 |
266 | "use strict";
267 | __webpack_require__.r(__webpack_exports__);
268 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DIST", function() { return DIST; });
269 | var DIST = 6;
270 |
271 | /***/ }),
272 |
273 | /***/ "./src/index.less":
274 | /*!************************!*\
275 | !*** ./src/index.less ***!
276 | \************************/
277 | /*! no static exports found */
278 | /***/ (function(module, exports, __webpack_require__) {
279 |
280 | // extracted by mini-css-extract-plugin
281 |
282 | /***/ }),
283 |
284 | /***/ "./src/index.ts":
285 | /*!**********************!*\
286 | !*** ./src/index.ts ***!
287 | \**********************/
288 | /*! exports provided: moveByDom, resizeByDom, initLine */
289 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
290 |
291 | "use strict";
292 | __webpack_require__.r(__webpack_exports__);
293 | /* harmony import */ var _move__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./move */ "./src/move.ts");
294 | /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "moveByDom", function() { return _move__WEBPACK_IMPORTED_MODULE_0__["moveByDom"]; });
295 |
296 | /* harmony import */ var _resize__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./resize */ "./src/resize.ts");
297 | /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "resizeByDom", function() { return _resize__WEBPACK_IMPORTED_MODULE_1__["resizeByDom"]; });
298 |
299 | /* harmony import */ var _lines_store__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lines/store */ "./src/lines/store.ts");
300 | /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "initLine", function() { return _lines_store__WEBPACK_IMPORTED_MODULE_2__["initLine"]; });
301 |
302 | /* harmony import */ var _index_less__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./index.less */ "./src/index.less");
303 | /* harmony import */ var _index_less__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_index_less__WEBPACK_IMPORTED_MODULE_3__);
304 |
305 |
306 |
307 |
308 |
309 |
310 | /***/ }),
311 |
312 | /***/ "./src/lines/align.ts":
313 | /*!****************************!*\
314 | !*** ./src/lines/align.ts ***!
315 | \****************************/
316 | /*! exports provided: showAlignLine, hideAlignLine */
317 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
318 |
319 | "use strict";
320 | __webpack_require__.r(__webpack_exports__);
321 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showAlignLine", function() { return showAlignLine; });
322 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hideAlignLine", function() { return hideAlignLine; });
323 | /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js");
324 | /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
325 | /* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./store */ "./src/lines/store.ts");
326 | /* harmony import */ var _lib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib */ "./src/lines/lib.ts");
327 |
328 |
329 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
330 |
331 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
332 |
333 | /**
334 | * 对齐线
335 | */
336 |
337 |
338 | /**
339 | *
340 | * @param {string} direction 方向,v垂直方向,h水平方向
341 | * @param {*} top
342 | * @param {*} left
343 | * @param {*} height
344 | * @param {*} width
345 | */
346 |
347 | function getNearLine(direction, line) {
348 | // 获取两个方向的线数据
349 | // let line = calcLines(top, left, height, width);
350 | if (direction === 'v') {
351 | if (_store__WEBPACK_IMPORTED_MODULE_1__["Lines"].vLines.length == 0) {
352 | return;
353 | }
354 |
355 | if (line.v.length == 0) {
356 | return;
357 | }
358 |
359 | var nearLines = line.v.map(function (item) {
360 | return Object(_lib__WEBPACK_IMPORTED_MODULE_2__["findLine"])(item, _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].vLines);
361 | }).map(function (item, i) {
362 | return _objectSpread({
363 | val: Math.abs(item.pos - line.v[i].pos),
364 | from: line.v[i]
365 | }, item);
366 | }).sort(function (a, b) {
367 | return a.val - b.val;
368 | });
369 | return nearLines.map(function (tarLine, index) {
370 | var display = tarLine.val === 0;
371 |
372 | if (index === 0 && tarLine.val > 0) {
373 | display = true;
374 | }
375 |
376 | return {
377 | type: tarLine.type,
378 | display: display,
379 | pos: tarLine.pos,
380 | start: Math.min(tarLine.from.start, tarLine.start),
381 | end: Math.max(tarLine.from.end, tarLine.end),
382 | from: tarLine.from
383 | };
384 | });
385 | } else {
386 | if (_store__WEBPACK_IMPORTED_MODULE_1__["Lines"].hLines.length == 0) {
387 | return;
388 | }
389 |
390 | if (line.h.length == 0) {
391 | return;
392 | }
393 |
394 | var _nearLines = line.h.map(function (item) {
395 | return Object(_lib__WEBPACK_IMPORTED_MODULE_2__["findLine"])(item, _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].hLines);
396 | }).map(function (item, i) {
397 | return _objectSpread({
398 | val: Math.abs(item.pos - line.h[i].pos),
399 | from: line.h[i]
400 | }, item);
401 | }).sort(function (a, b) {
402 | return a.val - b.val;
403 | });
404 |
405 | return _nearLines.map(function (tarLine, index) {
406 | var display = tarLine.val === 0;
407 |
408 | if (index === 0 && tarLine.val > 0) {
409 | display = true;
410 | }
411 |
412 | return {
413 | type: tarLine.type,
414 | display: display,
415 | pos: tarLine.pos,
416 | start: Math.min(tarLine.from.start, tarLine.start),
417 | end: Math.max(tarLine.from.end, tarLine.end),
418 | from: tarLine.from
419 | };
420 | }); // return []
421 | }
422 | }
423 |
424 | function createSpaceLineRoot() {
425 | var id = "view__align-line-root";
426 | var dom = document.getElementById(id);
427 |
428 | if (!dom) {
429 | var div = document.createElement('div');
430 | div.id = id;
431 | document.body.appendChild(div);
432 | dom = div;
433 | }
434 |
435 | return dom;
436 | }
437 |
438 | function createVLines(key, _ref, offsetTop, offsetLeft) {
439 | var pos = _ref.pos,
440 | start = _ref.start,
441 | end = _ref.end,
442 | display = _ref.display;
443 | var id = 'view__v-line_' + key;
444 | var cls = 'view__v-line';
445 | var dom = document.getElementById(id);
446 | var root = createSpaceLineRoot();
447 |
448 | if (!dom) {
449 | var div = document.createElement('div');
450 | div.id = id;
451 | div.className = cls;
452 | root.appendChild(div);
453 | dom = div;
454 | }
455 |
456 | dom.style.display = display ? 'block' : 'none';
457 | dom.style.left = "".concat(pos + offsetLeft, "px");
458 | dom.style.top = "".concat(start + offsetTop, "px");
459 | dom.style.height = "".concat(end - start, "px");
460 | }
461 |
462 | function createHLines(key, _ref2, offsetTop, offsetLeft) {
463 | var pos = _ref2.pos,
464 | start = _ref2.start,
465 | end = _ref2.end,
466 | display = _ref2.display;
467 | var id = 'view__h-line_' + key;
468 | var cls = 'view__h-line';
469 | var dom = document.getElementById(id);
470 | var root = createSpaceLineRoot();
471 |
472 | if (!dom) {
473 | var div = document.createElement('div');
474 | div.id = id;
475 | div.className = cls;
476 | root.appendChild(div);
477 | dom = div;
478 | }
479 |
480 | dom.style.display = display ? 'block' : 'none';
481 | dom.style.left = "".concat(start + offsetLeft, "px");
482 | dom.style.top = "".concat(pos + offsetTop, "px");
483 | dom.style.width = "".concat(end - start, "px");
484 | }
485 | /**
486 | * 显示对齐线
487 | * @param {*} line
488 | * @param {*} offsetTop
489 | * @param {*} offsetLeft
490 | */
491 |
492 |
493 | function showAlignLine(line, offsetTop, offsetLeft) {
494 | var vResult = getNearLine('v', line);
495 | var hResult = getNearLine('h', line);
496 |
497 | if (vResult && vResult.length > 0) {
498 | // console.log(vResult)
499 | vResult.forEach(function (item, index) {
500 | createVLines(index, item, offsetTop, offsetLeft);
501 | });
502 | }
503 |
504 | if (hResult && hResult.length > 0) {
505 | // console.log(hResult)
506 | hResult.forEach(function (item, index) {
507 | createHLines(index, item, offsetTop, offsetLeft);
508 | });
509 | }
510 |
511 | if (!vResult && !hResult) {
512 | return null;
513 | }
514 |
515 | return {
516 | vLine: vResult ? vResult.find(function (p) {
517 | return p.display;
518 | }) : null,
519 | hLine: hResult ? hResult.find(function (p) {
520 | return p.display;
521 | }) : null
522 | };
523 | }
524 | /**
525 | * 隐藏
526 | */
527 |
528 | var hideAlignLine = function hideAlignLine() {
529 | var root = createSpaceLineRoot();
530 |
531 | if (root.parentNode) {
532 | root.parentNode.removeChild(root);
533 | }
534 | };
535 |
536 | /***/ }),
537 |
538 | /***/ "./src/lines/distance.ts":
539 | /*!*******************************!*\
540 | !*** ./src/lines/distance.ts ***!
541 | \*******************************/
542 | /*! exports provided: showDistLine, hideDistLine */
543 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
544 |
545 | "use strict";
546 | __webpack_require__.r(__webpack_exports__);
547 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showDistLine", function() { return showDistLine; });
548 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hideDistLine", function() { return hideDistLine; });
549 | /**
550 | * 距离线
551 | */
552 | function createSpaceLineRoot() {
553 | var id = "view__dist-line-root";
554 | var dom = document.getElementById(id);
555 |
556 | if (!dom) {
557 | var div = document.createElement('div');
558 | div.id = id;
559 | document.body.appendChild(div);
560 | dom = div;
561 | }
562 |
563 | return dom;
564 | }
565 | /**
566 | * 创建距离线
567 | * @param {*} param0
568 | * @param {*} offsetTop
569 | * @param {*} offsetLeft
570 | */
571 |
572 |
573 | function createHDistLine(_ref, offsetTop, offsetLeft) {
574 | var pos = _ref.pos,
575 | start = _ref.start,
576 | end = _ref.end;
577 | var id = 'view__h-dist-line';
578 | var dom = document.getElementById(id);
579 | var root = createSpaceLineRoot();
580 |
581 | if (!dom) {
582 | var div = document.createElement('div');
583 | div.id = id;
584 | div.className = id;
585 | root.appendChild(div);
586 | dom = div;
587 | }
588 |
589 | var l = start,
590 | r = end;
591 |
592 | if (start > end) {
593 | l = end, r = start;
594 | }
595 |
596 | dom.innerHTML = "
".concat(r - l, "
");
597 | dom.style.display = 'block';
598 | dom.style.left = "".concat(l + offsetLeft, "px");
599 | dom.style.top = "".concat(pos + offsetTop, "px");
600 | dom.style.width = "".concat(Math.abs(r - l), "px");
601 | }
602 |
603 | function createVDistLine(_ref2, offsetTop, offsetLeft) {
604 | var pos = _ref2.pos,
605 | start = _ref2.start,
606 | end = _ref2.end;
607 | var id = 'view__v-dist-line';
608 | var dom = document.getElementById(id);
609 | var root = createSpaceLineRoot();
610 |
611 | if (!dom) {
612 | var div = document.createElement('div');
613 | div.id = id;
614 | div.className = id;
615 | root.appendChild(div);
616 | dom = div;
617 | }
618 |
619 | var t = start,
620 | b = end;
621 |
622 | if (start > end) {
623 | t = end, b = start;
624 | }
625 |
626 | dom.innerHTML = "".concat(b - t, "
");
627 | dom.style.display = 'block';
628 | dom.style.left = "".concat(pos + offsetLeft, "px");
629 | dom.style.top = "".concat(t + offsetTop, "px");
630 | dom.style.height = "".concat(Math.abs(b - t), "px");
631 | }
632 | /**
633 | * 显示距离线
634 | */
635 |
636 |
637 | function showDistLine(direction, from, to, offsetTop, offsetLeft) {
638 | var start = from.start,
639 | end = from.end;
640 | var fromPos = from.pos,
641 | toPos = to.pos; // if (Math.abs(from.pos - to.pos) < 5) {
642 | // toPos = fromPos;
643 | // }
644 |
645 | if (direction === 'v') {
646 | var line = {
647 | start: fromPos,
648 | end: toPos,
649 | pos: (end + start) / 2
650 | }; // console.log(line)
651 |
652 | createHDistLine(line, offsetTop, offsetLeft);
653 | } else {
654 | var _line = {
655 | start: fromPos,
656 | end: toPos,
657 | pos: (end + start) / 2
658 | };
659 | createVDistLine(_line, offsetTop, offsetLeft);
660 | }
661 | }
662 | /**
663 | * 隐藏
664 | */
665 |
666 | var hideDistLine = function hideDistLine() {
667 | var root = createSpaceLineRoot();
668 |
669 | if (root.parentNode) {
670 | root.parentNode.removeChild(root);
671 | }
672 | };
673 |
674 | /***/ }),
675 |
676 | /***/ "./src/lines/label.ts":
677 | /*!****************************!*\
678 | !*** ./src/lines/label.ts ***!
679 | \****************************/
680 | /*! exports provided: hideLabel, showLabel */
681 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
682 |
683 | "use strict";
684 | __webpack_require__.r(__webpack_exports__);
685 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hideLabel", function() { return hideLabel; });
686 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showLabel", function() { return showLabel; });
687 | /**
688 | * size标签
689 | */
690 |
691 | /**
692 | * 隐藏label
693 | * @param {*} id
694 | */
695 | var hideLabel = function hideLabel() {
696 | var id = 'view__resize-label';
697 | var dom = document.getElementById(id);
698 |
699 | if (!dom) {
700 | return;
701 | }
702 |
703 | if (dom.parentNode) {
704 | dom.parentNode.removeChild(dom);
705 | }
706 | };
707 | function showLabel(view, content) {
708 | var id = 'view__resize-label';
709 | var rect = view.getBoundingClientRect();
710 | var dom = document.getElementById(id);
711 |
712 | if (!dom) {
713 | var div = document.createElement('div');
714 | div.id = id;
715 | div.className = id;
716 | document.body.appendChild(div);
717 | dom = div;
718 | }
719 |
720 | dom.style.display = 'block';
721 | dom.style.top = "".concat(rect.bottom + 5, "px");
722 | dom.style.left = "".concat(rect.left + rect.width / 2, "px");
723 | dom.innerHTML = content;
724 | }
725 |
726 | /***/ }),
727 |
728 | /***/ "./src/lines/lib.ts":
729 | /*!**************************!*\
730 | !*** ./src/lines/lib.ts ***!
731 | \**************************/
732 | /*! exports provided: findLine, calcLines, calcDirectionCreator, calcDirection, debounce, throttle */
733 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
734 |
735 | "use strict";
736 | __webpack_require__.r(__webpack_exports__);
737 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findLine", function() { return findLine; });
738 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "calcLines", function() { return calcLines; });
739 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "calcDirectionCreator", function() { return calcDirectionCreator; });
740 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "calcDirection", function() { return calcDirection; });
741 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return debounce; });
742 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return throttle; });
743 | /**
744 | * 寻找和tarLine邻近的线
745 | * @param {*} tarLine 源线
746 | * @param {*} lines 线的数组
747 | */
748 | function findLine(tarLine, lines) {
749 | // 可以使用二分查找
750 | var l = 0,
751 | r = lines.length - 1;
752 |
753 | while (l <= r) {
754 | var i = Math.round(r - (r - l) / 2);
755 |
756 | if (tarLine.pos < lines[i].pos) {
757 | r = i - 1;
758 | } else if (tarLine.pos > lines[i].pos) {
759 | l = i + 1;
760 | } else {
761 | return lines[i];
762 | }
763 | }
764 |
765 | if (l == r) {
766 | return lines[l];
767 | }
768 |
769 | if (l > r) {
770 | if (l >= lines.length) {
771 | return lines[r];
772 | }
773 |
774 | if (r < 0) {
775 | return lines[0];
776 | }
777 |
778 | var x1 = Math.abs(lines[r].pos - tarLine.pos);
779 | var x2 = Math.abs(lines[l].pos - tarLine.pos);
780 | return x1 < x2 ? lines[r] : lines[l];
781 | }
782 | }
783 | function calcLines(top, left, height, width) {
784 | return {
785 | v: [{
786 | type: 'vl',
787 | pos: left,
788 | start: top,
789 | end: top + height
790 | }, {
791 | type: 'vm',
792 | pos: left + width / 2,
793 | start: top,
794 | end: top + height
795 | }, {
796 | type: 'vr',
797 | pos: left + width,
798 | start: top,
799 | end: top + height
800 | }],
801 | h: [{
802 | type: 'ht',
803 | pos: top,
804 | start: left,
805 | end: left + width
806 | }, {
807 | type: 'hm',
808 | pos: top + height / 2,
809 | start: left,
810 | end: left + width
811 | }, {
812 | type: 'hb',
813 | pos: top + height,
814 | start: left,
815 | end: left + width
816 | }]
817 | };
818 | }
819 | function calcDirectionCreator() {
820 | var lastTop, lastLeft, lastDirection;
821 | return function (top, left) {
822 | if (!lastTop) {
823 | lastTop = top;
824 | }
825 |
826 | if (!lastLeft) {
827 | lastLeft = left;
828 | }
829 |
830 | var direction; // console.log(top, left, lastTop, lastLeft)
831 |
832 | var topOffset = Math.abs(top - lastTop),
833 | leftOffset = Math.abs(left - lastLeft);
834 |
835 | if (topOffset > leftOffset) {
836 | direction = 'v';
837 | } else if (topOffset < leftOffset) {
838 | direction = 'h';
839 | } else {
840 | direction = lastDirection;
841 | }
842 |
843 | lastTop = top;
844 | lastLeft = left;
845 | lastDirection = direction;
846 | return direction;
847 | };
848 | }
849 | var calcDirection = calcDirectionCreator();
850 | function debounce(fn, delay) {
851 | var timer = null;
852 | return function () {
853 | var args = arguments,
854 | context = this;
855 |
856 | if (timer) {
857 | clearTimeout(timer);
858 | timer = setTimeout(function () {
859 | fn.apply(context, args);
860 | }, delay);
861 | } else {
862 | timer = setTimeout(function () {
863 | fn.apply(context, args);
864 | }, delay);
865 | }
866 | };
867 | }
868 | function throttle(fn, delay) {
869 | var timer = null,
870 | remaining = 0,
871 | previous = Date.now();
872 | return function () {
873 | var args = arguments,
874 | context = this;
875 | var now = Date.now();
876 | remaining = now - previous;
877 |
878 | if (remaining >= delay) {
879 | if (timer) {
880 | clearTimeout(timer);
881 | }
882 |
883 | fn.apply(context, args);
884 | previous = now;
885 | } else {
886 | if (!timer) {
887 | timer = setTimeout(function () {
888 | fn.apply(context, args);
889 | previous = Date.now();
890 | }, delay - remaining);
891 | }
892 | }
893 | };
894 | }
895 |
896 | /***/ }),
897 |
898 | /***/ "./src/lines/space.ts":
899 | /*!****************************!*\
900 | !*** ./src/lines/space.ts ***!
901 | \****************************/
902 | /*! exports provided: createVSpaceLines, createHSpaceLines, showSpaceLine, calcSpaceLineList, hideSpaceLine */
903 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
904 |
905 | "use strict";
906 | __webpack_require__.r(__webpack_exports__);
907 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createVSpaceLines", function() { return createVSpaceLines; });
908 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createHSpaceLines", function() { return createHSpaceLines; });
909 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "showSpaceLine", function() { return showSpaceLine; });
910 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "calcSpaceLineList", function() { return calcSpaceLineList; });
911 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hideSpaceLine", function() { return hideSpaceLine; });
912 | /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "./node_modules/@babel/runtime/helpers/slicedToArray.js");
913 | /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
914 | /* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./store */ "./src/lines/store.ts");
915 |
916 |
917 | /**
918 | * 间距块
919 | */
920 |
921 |
922 | function createSpaceLineRoot(direction) {
923 | var id = "view__".concat(direction, "-dist-line-root");
924 | var dom = document.getElementById(id);
925 |
926 | if (!dom) {
927 | var div = document.createElement('div');
928 | div.id = id;
929 | document.body.appendChild(div);
930 | dom = div;
931 | }
932 |
933 | return dom;
934 | }
935 |
936 | function createHSpaceLine(_ref, offsetTop, offsetLeft) {
937 | var pos = _ref.pos,
938 | start = _ref.start,
939 | end = _ref.end,
940 | height = _ref.height;
941 | var id = 'view__h-space-line_' + start;
942 | var root = createSpaceLineRoot('h');
943 | var dom = document.getElementById(id);
944 |
945 | if (!dom) {
946 | var div = document.createElement('div');
947 | div.id = id;
948 | div.className = 'view__h-space-line';
949 | root.appendChild(div);
950 | dom = div;
951 | }
952 |
953 | var l = start,
954 | r = end;
955 |
956 | if (start > end) {
957 | l = end, r = start;
958 | }
959 |
960 | dom.innerHTML = "";
961 | dom.style.display = 'block';
962 | dom.style.left = "".concat(l + offsetLeft, "px");
963 | dom.style.top = "".concat(pos + offsetTop, "px");
964 | dom.style.width = "".concat(Math.abs(r - l), "px");
965 | dom.style.height = "".concat(height, "px");
966 | }
967 |
968 | function createVSpaceLine(_ref2, offsetTop, offsetLeft) {
969 | var pos = _ref2.pos,
970 | start = _ref2.start,
971 | end = _ref2.end,
972 | width = _ref2.width;
973 | var id = 'view__v-space-line_' + start;
974 | var root = createSpaceLineRoot('v');
975 | var dom = document.getElementById(id);
976 |
977 | if (!dom) {
978 | var div = document.createElement('div');
979 | div.id = id;
980 | div.className = 'view__v-space-line';
981 | root.appendChild(div);
982 | dom = div;
983 | }
984 |
985 | var t = start,
986 | b = end;
987 |
988 | if (start > end) {
989 | t = end, b = start;
990 | }
991 |
992 | dom.innerHTML = "";
993 | dom.style.display = 'block';
994 | dom.style.left = "".concat(pos + offsetLeft, "px");
995 | dom.style.top = "".concat(t + offsetTop, "px");
996 | dom.style.width = "".concat(width, "px");
997 | dom.style.height = "".concat(Math.abs(b - t), "px");
998 | }
999 |
1000 | function createVSpaceLines() {
1001 | var lineIndexPairs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1002 | var offsetTop = arguments.length > 1 ? arguments[1] : undefined;
1003 | var offsetLeft = arguments.length > 2 ? arguments[2] : undefined;
1004 | hideSpaceLine('v');
1005 | lineIndexPairs.forEach(function (item) {
1006 | var from = item.from,
1007 | to = item.to;
1008 | var l1 = from;
1009 | var l2 = to; // { pos, start, end }, offsetTop, offsetLeft
1010 |
1011 | var t = Math.min(l1.start, l2.start, l1.end, l2.end);
1012 | var b = Math.max(l1.start, l2.start, l1.end, l2.end);
1013 | var line = {
1014 | pos: (l1.start + l1.end) / 2,
1015 | start: l1.pos,
1016 | end: l2.pos,
1017 | height: b - t
1018 | };
1019 | createHSpaceLine(line, offsetTop, offsetLeft);
1020 | });
1021 | }
1022 | function createHSpaceLines() {
1023 | var lineIndexPairs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1024 | var offsetTop = arguments.length > 1 ? arguments[1] : undefined;
1025 | var offsetLeft = arguments.length > 2 ? arguments[2] : undefined;
1026 | hideSpaceLine('h');
1027 | lineIndexPairs.forEach(function (item) {
1028 | var from = item.from,
1029 | to = item.to;
1030 | var l1 = from;
1031 | var l2 = to; // { pos, start, end }, offsetTop, offsetLeft
1032 |
1033 | var l = Math.min(l1.start, l2.start, l1.end, l2.end);
1034 | var r = Math.max(l1.start, l2.start, l1.end, l2.end);
1035 | var line = {
1036 | pos: (l1.start + l1.end) / 2,
1037 | start: l1.pos,
1038 | end: l2.pos,
1039 | width: r - l
1040 | };
1041 | createVSpaceLine(line, offsetTop, offsetLeft);
1042 | });
1043 | }
1044 |
1045 | function calcAllSpaceLines(direction) {
1046 | var allLines = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
1047 | var tarLines = arguments.length > 2 ? arguments[2] : undefined;
1048 | // 计算vl,vr的间距,按顺序查找,确保vl>vr,连续的vl>vr的线
1049 | var i = 0,
1050 | j = 1,
1051 | results = [];
1052 | var l1type = direction === 'v' ? 'vr' : 'hb';
1053 | var l2type = direction === 'v' ? 'vl' : 'ht';
1054 | var mid = (tarLines[0].end - tarLines[0].start) / 2 + tarLines[0].start;
1055 | var lines = allLines.concat(tarLines).filter(function (line) {
1056 | // 父容器的线去除
1057 | if (line.start === 0) {
1058 | return false;
1059 | }
1060 |
1061 | if (line.type === 'vm' || line.type === 'hm') {
1062 | return false;
1063 | }
1064 |
1065 | if (line.start < mid && line.end > mid) {
1066 | return true;
1067 | }
1068 |
1069 | return false;
1070 | }).sort(function (a, b) {
1071 | return a.pos - b.pos;
1072 | });
1073 |
1074 | while (j < lines.length) {
1075 | if (lines[i].type === l1type) {
1076 | if (lines[j].type !== l2type) {
1077 | j++;
1078 | continue;
1079 | }
1080 |
1081 | if (lines[i].pos <= tarLines[0].pos && lines[j].pos >= tarLines[2].pos) {
1082 | i++;
1083 | continue;
1084 | } // i 是vr j是vl
1085 |
1086 |
1087 | results.push([i, j]);
1088 | }
1089 |
1090 | i++;
1091 | j++;
1092 | }
1093 |
1094 | return results.map(function (item) {
1095 | var _item = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(item, 2),
1096 | i = _item[0],
1097 | j = _item[1];
1098 |
1099 | return {
1100 | from: lines[i],
1101 | to: lines[j],
1102 | dist: lines[j].pos - lines[i].pos
1103 | };
1104 | });
1105 | }
1106 |
1107 | function findTarSpaceLine(spaceLines, tarLines) {
1108 | var left = tarLines[0];
1109 | var right = tarLines[2];
1110 | var leftTar, rightTar;
1111 |
1112 | if (spaceLines.length <= 1) {
1113 | return [];
1114 | }
1115 |
1116 | spaceLines.forEach(function (line, index) {
1117 | var from = line.from,
1118 | to = line.to;
1119 |
1120 | if (left.pos === to.pos) {
1121 | if (index < 1) {
1122 | return;
1123 | }
1124 |
1125 | var _line = spaceLines[index - 1];
1126 | var dist = _line.dist;
1127 | leftTar = from.pos + dist;
1128 | }
1129 |
1130 | if (right.pos === from.pos) {
1131 | if (index >= spaceLines.length - 1) {
1132 | return;
1133 | }
1134 |
1135 | var _line2 = spaceLines[index + 1];
1136 | var _dist = _line2.dist;
1137 | rightTar = to.pos - _dist;
1138 | }
1139 | });
1140 | return [leftTar, rightTar];
1141 | }
1142 | /**
1143 | *
1144 | *显示间距线,返回最近的间距块以及目标吸附位置
1145 | */
1146 |
1147 |
1148 | var showSpaceLine = function showSpaceLine(direction, line, offsetTop, offsetLeft) {
1149 | //判断是横向还是纵向,
1150 | //计算组件的间距,显示同一方向的间距,
1151 | // let results;
1152 | if (direction === 'h') {
1153 | var spaceLines = calcAllSpaceLines('h', _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].hLines, line.h);
1154 | createHSpaceLines(spaceLines, offsetTop, offsetLeft);
1155 | } else {
1156 | var _spaceLines = calcAllSpaceLines('v', _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].vLines, line.v);
1157 |
1158 | createVSpaceLines(_spaceLines, offsetTop, offsetLeft);
1159 | }
1160 | };
1161 | var calcSpaceLineList = function calcSpaceLineList(direction, line) {
1162 | var results, spaceLines;
1163 |
1164 | if (direction === 'h') {
1165 | spaceLines = calcAllSpaceLines('h', _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].hLines, line.h);
1166 | results = findTarSpaceLine(spaceLines, line.h);
1167 | } else {
1168 | spaceLines = calcAllSpaceLines('v', _store__WEBPACK_IMPORTED_MODULE_1__["Lines"].vLines, line.v);
1169 | results = findTarSpaceLine(spaceLines, line.v);
1170 | }
1171 |
1172 | return results;
1173 | };
1174 | /**
1175 | * 隐藏
1176 | * @param {string} direction 方向
1177 | */
1178 |
1179 | var hideSpaceLine = function hideSpaceLine(direction) {
1180 | var hdom = document.getElementById("view__".concat(direction, "-dist-line-root"));
1181 |
1182 | if (!hdom) {
1183 | return;
1184 | }
1185 |
1186 | hdom.remove();
1187 | };
1188 |
1189 | /***/ }),
1190 |
1191 | /***/ "./src/lines/store.ts":
1192 | /*!****************************!*\
1193 | !*** ./src/lines/store.ts ***!
1194 | \****************************/
1195 | /*! exports provided: Lines, initLine */
1196 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
1197 |
1198 | "use strict";
1199 | __webpack_require__.r(__webpack_exports__);
1200 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Lines", function() { return Lines; });
1201 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initLine", function() { return initLine; });
1202 | /* harmony import */ var _lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib */ "./src/lines/lib.ts");
1203 | /**
1204 | * 线的存储
1205 | */
1206 |
1207 | /**
1208 | * line 集合,{pos,type,start,end}
1209 | */
1210 |
1211 | var Lines = {
1212 | vLines: [],
1213 | hLines: []
1214 | };
1215 | /**
1216 | * 初始化容器内的线数据
1217 | */
1218 |
1219 | function initLine(childs, dragDom) {
1220 | var vLines = [],
1221 | hLines = [];
1222 |
1223 | for (var i = 0; i < childs.length; i++) {
1224 | var child = childs[i];
1225 |
1226 | if (child === dragDom) {
1227 | continue;
1228 | }
1229 |
1230 | var offsetTop = child.offsetTop,
1231 | offsetLeft = child.offsetLeft,
1232 | offsetHeight = child.offsetHeight,
1233 | offsetWidth = child.offsetWidth;
1234 | var l = Object(_lib__WEBPACK_IMPORTED_MODULE_0__["calcLines"])(offsetTop, offsetLeft, offsetHeight, offsetWidth);
1235 | vLines = vLines.concat(l.v);
1236 | hLines = hLines.concat(l.h);
1237 | }
1238 |
1239 | Lines.vLines = vLines.sort(function (a, b) {
1240 | return a.pos - b.pos;
1241 | });
1242 | Lines.hLines = hLines.sort(function (a, b) {
1243 | return a.pos - b.pos;
1244 | });
1245 | }
1246 |
1247 | /***/ }),
1248 |
1249 | /***/ "./src/move.ts":
1250 | /*!*********************!*\
1251 | !*** ./src/move.ts ***!
1252 | \*********************/
1253 | /*! exports provided: moveByDom */
1254 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
1255 |
1256 | "use strict";
1257 | __webpack_require__.r(__webpack_exports__);
1258 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "moveByDom", function() { return moveByDom; });
1259 | /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "./node_modules/@babel/runtime/helpers/slicedToArray.js");
1260 | /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
1261 | /* harmony import */ var _lines_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lines/lib */ "./src/lines/lib.ts");
1262 | /* harmony import */ var _lines_align__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lines/align */ "./src/lines/align.ts");
1263 | /* harmony import */ var _lines_distance__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lines/distance */ "./src/lines/distance.ts");
1264 | /* harmony import */ var _lines_space__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lines/space */ "./src/lines/space.ts");
1265 | /* harmony import */ var _lines_label__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lines/label */ "./src/lines/label.ts");
1266 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
1267 |
1268 |
1269 |
1270 |
1271 |
1272 |
1273 |
1274 |
1275 | function calcTarPos(top, left, height, width, vLine, hLine) {
1276 | var tarLeft = left,
1277 | tarTop = top;
1278 |
1279 | if (!vLine) {
1280 | tarLeft = left;
1281 | } else if (vLine.from.pos < vLine.pos + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && vLine.from.pos > vLine.pos - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1282 | if (vLine.from.type === 'vl') {
1283 | tarLeft = vLine.pos;
1284 | } else if (vLine.from.type === 'vm') {
1285 | tarLeft = vLine.pos - width / 2;
1286 | } else if (vLine.from.type === 'vr') {
1287 | tarLeft = vLine.pos - width;
1288 | }
1289 | }
1290 |
1291 | if (!hLine) {
1292 | tarTop = top;
1293 | } else if (hLine.from.pos < hLine.pos + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && hLine.from.pos > hLine.pos - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1294 | if (hLine.from.type === 'ht') {
1295 | tarTop = hLine.pos;
1296 | } else if (hLine.from.type === 'hm') {
1297 | tarTop = hLine.pos - height / 2;
1298 | } else if (hLine.from.type === 'hb') {
1299 | tarTop = hLine.pos - height;
1300 | }
1301 | }
1302 |
1303 | return {
1304 | top: tarTop,
1305 | left: tarLeft
1306 | };
1307 | }
1308 |
1309 | function showSapceLines(direction, tarLine, _ref, offsetTop, offsetLeft) {
1310 | var top = _ref.top,
1311 | left = _ref.left,
1312 | width = _ref.width,
1313 | height = _ref.height;
1314 | var tarLeft = left;
1315 | var tarTop = top;
1316 |
1317 | if (direction == 'h') {
1318 | var _calcSpaceLineList = Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["calcSpaceLineList"])('v', tarLine),
1319 | _calcSpaceLineList2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_calcSpaceLineList, 2),
1320 | spaceLeft = _calcSpaceLineList2[0],
1321 | spaceRight = _calcSpaceLineList2[1];
1322 |
1323 | if (tarLeft > spaceLeft - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && tarLeft < spaceLeft + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1324 | tarLeft = spaceLeft;
1325 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["showSpaceLine"])('v', Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
1326 | }
1327 |
1328 | if (tarLeft > spaceRight - width - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && tarLeft < spaceRight - width + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1329 | tarLeft = spaceRight - width;
1330 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["showSpaceLine"])('v', Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
1331 | }
1332 | } else {
1333 | var _calcSpaceLineList3 = Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["calcSpaceLineList"])('h', tarLine),
1334 | _calcSpaceLineList4 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_calcSpaceLineList3, 2),
1335 | spaceTop = _calcSpaceLineList4[0],
1336 | spaceBottom = _calcSpaceLineList4[1];
1337 |
1338 | if (tarTop > spaceTop - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && tarTop < spaceTop + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1339 | tarTop = spaceTop;
1340 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["showSpaceLine"])('h', Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
1341 | }
1342 |
1343 | if (tarTop > spaceBottom - height - _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"] && tarTop < spaceBottom - height + _constants__WEBPACK_IMPORTED_MODULE_6__["DIST"]) {
1344 | tarTop = spaceBottom - height;
1345 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["showSpaceLine"])('h', Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
1346 | }
1347 | }
1348 |
1349 | return {
1350 | top: tarTop,
1351 | left: tarLeft
1352 | };
1353 | }
1354 |
1355 | function showAlignLines(tarLine, _ref2, offsetTop, offsetLeft) {
1356 | var top = _ref2.top,
1357 | left = _ref2.left,
1358 | width = _ref2.width,
1359 | height = _ref2.height;
1360 | var nearLine = Object(_lines_align__WEBPACK_IMPORTED_MODULE_2__["showAlignLine"])(tarLine, offsetTop, offsetLeft);
1361 | var tarLeft = left,
1362 | tarTop = top;
1363 |
1364 | if (nearLine) {
1365 | var vLine = nearLine.vLine,
1366 | hLine = nearLine.hLine;
1367 | var tarPos = calcTarPos(top, left, height, width, vLine, hLine);
1368 | tarLeft = tarPos.left;
1369 | tarTop = tarPos.top;
1370 |
1371 | if (top != tarTop || left != tarLeft) {
1372 | Object(_lines_align__WEBPACK_IMPORTED_MODULE_2__["showAlignLine"])(Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
1373 | }
1374 |
1375 | var fromVLine = vLine.from;
1376 | var fromHLine = hLine.from;
1377 | var map = {
1378 | 'vl': 0,
1379 | 'vm': 1,
1380 | 'vr': 2,
1381 | 'ht': 0,
1382 | 'hm': 1,
1383 | 'hb': 2
1384 | };
1385 |
1386 | if (tarLeft != left || tarTop != top) {
1387 | var newLine = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(tarTop, tarLeft, height, width);
1388 | fromVLine = newLine.v[map[fromVLine.type]];
1389 | fromHLine = newLine.h[map[fromHLine.type]];
1390 | }
1391 |
1392 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_3__["showDistLine"])('v', fromVLine, vLine, offsetTop, offsetLeft);
1393 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_3__["showDistLine"])('h', fromHLine, hLine, offsetTop, offsetLeft);
1394 | }
1395 |
1396 | return {
1397 | top: tarTop,
1398 | left: tarLeft
1399 | };
1400 | }
1401 |
1402 | function hideLines() {
1403 | Object(_lines_align__WEBPACK_IMPORTED_MODULE_2__["hideAlignLine"])();
1404 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["hideSpaceLine"])('h');
1405 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_4__["hideSpaceLine"])('v');
1406 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_3__["hideDistLine"])();
1407 | Object(_lines_label__WEBPACK_IMPORTED_MODULE_5__["hideLabel"])();
1408 | }
1409 |
1410 | var moveDeb = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["debounce"])(function (cb) {
1411 | cb();
1412 | }, 1000);
1413 | var moveByDom = function moveByDom(dom, top, left, onMoveEnd) {
1414 | if (!dom) {
1415 | return;
1416 | }
1417 |
1418 | var cotainer = dom.parentNode.getBoundingClientRect();
1419 | var offsetTop = cotainer.top;
1420 | var offsetLeft = cotainer.left;
1421 | var rect = dom.getBoundingClientRect();
1422 | var height = rect.height,
1423 | width = rect.width;
1424 | var direction = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcDirection"])(top, left);
1425 | var tarLine = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_1__["calcLines"])(top, left, height, width);
1426 | var tarLeft = left,
1427 | tarTop = top;
1428 | var tarSpaceInfo = showSapceLines(direction, tarLine, {
1429 | top: tarTop,
1430 | left: tarLeft,
1431 | width: width,
1432 | height: height
1433 | }, offsetTop, offsetLeft);
1434 | tarTop = tarSpaceInfo.top;
1435 | tarLeft = tarSpaceInfo.left;
1436 | var alignLineInfo = showAlignLines(tarLine, {
1437 | top: tarTop,
1438 | left: tarLeft,
1439 | width: width,
1440 | height: height
1441 | }, offsetTop, offsetLeft);
1442 | tarTop = alignLineInfo.top;
1443 | tarLeft = alignLineInfo.left;
1444 | dom.style.left = "".concat(tarLeft, "px");
1445 | dom.style.top = "".concat(tarTop, "px");
1446 | Object(_lines_label__WEBPACK_IMPORTED_MODULE_5__["showLabel"])(dom, "X:".concat(tarLeft, ",Y:").concat(tarTop));
1447 | moveDeb(function () {
1448 | hideLines();
1449 |
1450 | if (onMoveEnd) {
1451 | onMoveEnd(tarTop, tarLeft);
1452 | }
1453 | });
1454 | };
1455 |
1456 | /***/ }),
1457 |
1458 | /***/ "./src/resize.ts":
1459 | /*!***********************!*\
1460 | !*** ./src/resize.ts ***!
1461 | \***********************/
1462 | /*! exports provided: resizeByDom */
1463 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
1464 |
1465 | "use strict";
1466 | __webpack_require__.r(__webpack_exports__);
1467 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resizeByDom", function() { return resizeByDom; });
1468 | /* harmony import */ var _lines_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lines/lib */ "./src/lines/lib.ts");
1469 | /* harmony import */ var _lines_align__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lines/align */ "./src/lines/align.ts");
1470 | /* harmony import */ var _lines_distance__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lines/distance */ "./src/lines/distance.ts");
1471 | /* harmony import */ var _lines_label__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lines/label */ "./src/lines/label.ts");
1472 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
1473 | /* harmony import */ var _lines_space__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lines/space */ "./src/lines/space.ts");
1474 |
1475 |
1476 |
1477 |
1478 |
1479 |
1480 |
1481 | function calcTarSize(top, left, height, width, vLine, hLine) {
1482 | var tarLeft = left,
1483 | tarTop = top,
1484 | tarHeight = height,
1485 | tarWidth = width;
1486 |
1487 | if (vLine) {
1488 | if (vLine.from.pos < vLine.pos + _constants__WEBPACK_IMPORTED_MODULE_4__["DIST"] && vLine.from.pos > vLine.pos - _constants__WEBPACK_IMPORTED_MODULE_4__["DIST"]) {
1489 | if (vLine.from.type === 'vl') {
1490 | tarLeft = vLine.pos;
1491 | tarWidth = width + (vLine.from.pos - vLine.pos);
1492 | } else if (vLine.from.type === 'vm') {// tarLeft = vLine.pos - width / 2;
1493 | } else if (vLine.from.type === 'vr') {
1494 | tarWidth = width + (vLine.pos - vLine.from.pos);
1495 | tarLeft = vLine.pos - tarWidth;
1496 | }
1497 | }
1498 | }
1499 |
1500 | if (hLine) {
1501 | if (hLine.from.pos < hLine.pos + _constants__WEBPACK_IMPORTED_MODULE_4__["DIST"] && hLine.from.pos > hLine.pos - _constants__WEBPACK_IMPORTED_MODULE_4__["DIST"]) {
1502 | if (hLine.from.type === 'ht') {
1503 | tarTop = hLine.pos;
1504 | tarHeight = height + (hLine.from.pos - hLine.pos);
1505 | } else if (hLine.from.type === 'hm') {
1506 | tarTop = hLine.pos - height / 2;
1507 | } else if (hLine.from.type === 'hb') {
1508 | tarHeight = height + (hLine.pos - hLine.from.pos);
1509 | tarTop = hLine.pos - tarHeight;
1510 | }
1511 | }
1512 | }
1513 |
1514 | return {
1515 | top: tarTop,
1516 | left: tarLeft,
1517 | height: tarHeight,
1518 | width: tarWidth
1519 | };
1520 | }
1521 |
1522 | var DIRECTION = {
1523 | 'tc': ['ht'],
1524 | 'bc': ['hb'],
1525 | 'rc': ['vr'],
1526 | 'lc': ['vl'],
1527 | 'tl': ['ht', 'vl'],
1528 | 'tr': ['ht', 'vr'],
1529 | 'br': ['hb', 'vr'],
1530 | 'bl': ['hb', 'vl']
1531 | };
1532 |
1533 | function getTarLine(line) {
1534 | var include = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
1535 | var v = line.v.filter(function (item) {
1536 | return include.indexOf(item.type) >= 0;
1537 | });
1538 | var h = line.h.filter(function (item) {
1539 | return include.indexOf(item.type) >= 0;
1540 | });
1541 | return {
1542 | v: v,
1543 | h: h
1544 | };
1545 | }
1546 |
1547 | var last;
1548 |
1549 | function caclHandType(top, left, height, width) {
1550 | if (!last) {
1551 | last = {
1552 | top: top,
1553 | left: left,
1554 | height: height,
1555 | width: width
1556 | };
1557 | return [];
1558 | }
1559 |
1560 | var lines = [];
1561 |
1562 | if (top !== last.top) {
1563 | lines.push('ht');
1564 | }
1565 |
1566 | if (left !== last.left) {
1567 | lines.push('vl');
1568 | }
1569 |
1570 | if (top === last.top && left === last.left && width !== last.width) {
1571 | lines.push('vr');
1572 | }
1573 |
1574 | if (top === last.top && left === last.left && height !== last.height) {
1575 | lines.push('hb');
1576 | }
1577 |
1578 | return lines;
1579 | }
1580 |
1581 | function hideLines() {
1582 | last = null;
1583 | Object(_lines_align__WEBPACK_IMPORTED_MODULE_1__["hideAlignLine"])();
1584 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_5__["hideSpaceLine"])('h');
1585 | Object(_lines_space__WEBPACK_IMPORTED_MODULE_5__["hideSpaceLine"])('v');
1586 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_2__["hideDistLine"])();
1587 | Object(_lines_label__WEBPACK_IMPORTED_MODULE_3__["hideLabel"])();
1588 | }
1589 |
1590 | var moveDeb = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_0__["debounce"])(function (cb) {
1591 | cb();
1592 | }, 1000);
1593 | var resizeByDom = function resizeByDom(dom, top, left, height, width, onMoveEnd) {
1594 | if (!dom) {
1595 | return;
1596 | }
1597 |
1598 | var cotainer = dom.parentNode.getBoundingClientRect();
1599 | var offsetTop = cotainer.top;
1600 | var offsetLeft = cotainer.left;
1601 | var handType = caclHandType(top, left, height, width);
1602 | console.log(handType);
1603 | var allLines = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_0__["calcLines"])(top, left, height, width);
1604 | var tarLine = getTarLine(allLines, handType);
1605 | var nearLine = Object(_lines_align__WEBPACK_IMPORTED_MODULE_1__["showAlignLine"])(tarLine, offsetTop, offsetLeft);
1606 | var tarLeft = left,
1607 | tarTop = top,
1608 | tarHeight = height,
1609 | tarWidth = width; // console.log(nearLine)
1610 |
1611 | if (nearLine) {
1612 | var vLine = nearLine.vLine,
1613 | hLine = nearLine.hLine;
1614 | var tarPos = calcTarSize(top, left, height, width, vLine, hLine);
1615 | tarLeft = tarPos.left;
1616 | tarTop = tarPos.top;
1617 | tarHeight = tarPos.height;
1618 | tarWidth = tarPos.width;
1619 |
1620 | if (left != tarLeft || top != tarTop || height != tarHeight || width != tarWidth) {
1621 | Object(_lines_align__WEBPACK_IMPORTED_MODULE_1__["showAlignLine"])(Object(_lines_lib__WEBPACK_IMPORTED_MODULE_0__["calcLines"])(tarTop, tarLeft, tarHeight, tarWidth), offsetTop, offsetLeft);
1622 | }
1623 |
1624 | var map = {
1625 | 'vl': 0,
1626 | 'vm': 1,
1627 | 'vr': 2,
1628 | 'ht': 0,
1629 | 'hm': 1,
1630 | 'hb': 2
1631 | };
1632 |
1633 | if (vLine) {
1634 | var fromVLine = vLine.from;
1635 |
1636 | if (tarLeft != left || tarWidth != width) {
1637 | var newLine = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_0__["calcLines"])(tarTop, tarLeft, tarHeight, tarWidth);
1638 | fromVLine = newLine.v[map[fromVLine.type]];
1639 | }
1640 |
1641 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_2__["showDistLine"])('v', fromVLine, vLine, offsetTop, offsetLeft);
1642 | }
1643 |
1644 | if (hLine) {
1645 | var fromHLine = hLine.from;
1646 |
1647 | if (tarTop != top || tarHeight != height) {
1648 | var _newLine = Object(_lines_lib__WEBPACK_IMPORTED_MODULE_0__["calcLines"])(tarTop, tarLeft, tarHeight, tarWidth);
1649 |
1650 | fromHLine = _newLine.h[map[fromHLine.type]];
1651 | }
1652 |
1653 | Object(_lines_distance__WEBPACK_IMPORTED_MODULE_2__["showDistLine"])('h', fromHLine, hLine, offsetTop, offsetLeft);
1654 | }
1655 | }
1656 |
1657 | dom.style.top = "".concat(tarTop, "px");
1658 | dom.style.left = "".concat(tarLeft, "px");
1659 | dom.style.height = "".concat(tarHeight, "px");
1660 | dom.style.width = "".concat(tarWidth, "px"); // showLabel(dom, rect.bottom + 3, rect.left + rect.width / 2, `W:${width},H:${height}`);
1661 |
1662 | Object(_lines_label__WEBPACK_IMPORTED_MODULE_3__["showLabel"])(dom, "W:".concat(width, ",H:").concat(height));
1663 | moveDeb(function () {
1664 | hideLines();
1665 |
1666 | if (onMoveEnd) {
1667 | onMoveEnd(tarTop, tarLeft, tarHeight, tarWidth);
1668 | }
1669 | });
1670 | };
1671 |
1672 | /***/ })
1673 |
1674 | /******/ });
1675 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "view-line",
3 | "version": "1.0.0",
4 | "description": "为自由画布加入对齐线、间距块、吸附能功能",
5 | "main": "dist/view-line.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --config webpack.prod.config.js",
9 | "dev": "webpack-dev-server --config webpack.dev.config.js --open"
10 | },
11 | "repository": {},
12 | "author": "",
13 | "license": "ISC",
14 | "dependencies": {},
15 | "peerDependencies": {},
16 | "devDependencies": {
17 | "typescript": "^3.8.3",
18 | "@babel/core": "^7.2.2",
19 | "@babel/plugin-proposal-class-properties": "^7.2.3",
20 | "@babel/plugin-transform-runtime": "^7.2.0",
21 | "@babel/preset-env": "^7.2.3",
22 | "@babel/preset-typescript": "^7.9.0",
23 | "@babel/runtime": "^7.2.0",
24 | "autoprefixer": "^9.7.6",
25 | "babel-loader": "^8.1.0",
26 | "babel-plugin-external-helpers": "^6.22.0",
27 | "babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
28 | "babel-plugin-transform-es3-property-literals": "^6.22.0",
29 | "css-loader": "^3.5.0",
30 | "file-loader": "^6.0.0",
31 | "html-webpack-plugin": "^4.0.4",
32 | "less": "^3.11.1",
33 | "less-loader": "^5.0.0",
34 | "mini-css-extract-plugin": "^0.9.0",
35 | "postcss-loader": "^3.0.0",
36 | "url-loader": "^4.0.0",
37 | "webpack": "^4.28.4",
38 | "webpack-bundle-analyzer": "^3.6.1",
39 | "webpack-cli": "^3.2.1",
40 | "webpack-dev-server": "^3.10.3",
41 | "webpack-merge": "^4.2.2"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sample/index.ts:
--------------------------------------------------------------------------------
1 | import { moveByDom, resizeByDom, initLine } from '../src/index';
2 |
3 | import $ from 'jquery';
4 |
5 | $(function () {
6 | let isDraging = false, isResizing = false;
7 | let offset = { top: 0, left: 0 }
8 | $('.view').mousedown((e) => {
9 | let os = e.target.getBoundingClientRect();
10 | offset.top = e.clientY - os.top;
11 | offset.left = e.clientX - os.left;
12 | isDraging = true;
13 | let childs = (e.target as HTMLElement).parentNode.querySelectorAll('.view') as any;
14 | initLine(childs, e.target);
15 | })
16 | $('.view').mousemove((e) => {
17 | if (!isDraging) {
18 | return;
19 | }
20 |
21 | let parentRect = e.target.parentNode.getBoundingClientRect();
22 | let left = e.clientX - offset.left - parentRect.left;
23 | let top = e.clientY - offset.top - parentRect.top;
24 | // $(e.target).css('top', top).css('left', left);
25 | moveByDom(e.target, top, left, function (top, left) {
26 | console.log(top, left);
27 | });
28 | })
29 | $('.view').mouseup(() => {
30 | isDraging = false;
31 |
32 | })
33 | $('.hand').mousedown((e: Event) => {
34 | e.stopPropagation();
35 | isResizing = true;
36 |
37 | let view = e.currentTarget.parentNode;
38 |
39 | let childs = view.parentNode.querySelectorAll('.view') as any;
40 | initLine(childs, view);
41 |
42 | let parentRect = view.parentNode.getBoundingClientRect();
43 | let rect = view.getBoundingClientRect();
44 |
45 | let type = e.target.className;
46 | console.log(type)
47 |
48 | $(document).on('mousemove', function (e) {
49 | e.stopPropagation();
50 | if (!isResizing) {
51 | return;
52 | }
53 |
54 | let left, top, width, height;
55 | switch (type) {
56 | case 'br':
57 | left = rect.left - parentRect.left;
58 | top = rect.top - parentRect.top;
59 | width = e.clientX - rect.left;
60 | height = e.clientY - rect.top;
61 | break;
62 | case 'tl':
63 | left = e.clientX - parentRect.left;
64 | top = e.clientY - parentRect.top;
65 | width = rect.left + rect.width - e.clientX;
66 | height = rect.top + rect.height - e.clientY;
67 | break;
68 | case 'tr':
69 | left = rect.left - parentRect.left;
70 | top = e.clientY - parentRect.top;
71 | width = e.clientX - rect.left;
72 | height = rect.bottom - e.clientY;
73 | break;
74 | case 'bl':
75 | left = e.clientX - parentRect.left;
76 | top = rect.top - parentRect.top;
77 | width = rect.right - e.clientX;
78 | height = e.clientY- rect.top;
79 | break;
80 | }
81 |
82 | resizeByDom(view, top, left, height, width, function (top, left, height, width) {
83 | console.log(top, left, height, width);
84 | });
85 | })
86 | $(document).mouseup(() => {
87 | isDraging = false;
88 | $(document).off();
89 | })
90 | })
91 |
92 |
93 | })
94 |
--------------------------------------------------------------------------------
/sample/move.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hongyin163/view-line/b4ef3293d0e8ba9edfe92a5db56983fa72b7615e/sample/move.gif
--------------------------------------------------------------------------------
/sample/resize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hongyin163/view-line/b4ef3293d0e8ba9edfe92a5db56983fa72b7615e/sample/resize.gif
--------------------------------------------------------------------------------
/sample/tmp.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Document
9 |
10 |
42 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const DIST = 6;
2 |
--------------------------------------------------------------------------------
/src/index.less:
--------------------------------------------------------------------------------
1 | .view{
2 | &__lines{
3 | display: none;
4 | pointer-events: none;
5 | i.line{ position: absolute;}
6 | .t{top: 0px;left: 0;right: 0;height: 0;width: auto;border: 0; border-top: 1px solid red;z-index:10 ;}
7 | .r{right: 0;top: 0;bottom: 0;width: 0;height: auto;border: 0; border-right: 1px solid red;z-index:10 ;}
8 | .b{bottom: 0;left: 0;right: 0;height: 0;width: auto;border: 0; border-bottom: 1px solid red;z-index:10 ;}
9 | .l{left: 0;top: 0;bottom: 0;height: auto;width:0;border: 0; border-left: 1px solid red;z-index:10 ;}
10 | }
11 |
12 | &__resize-label{
13 | position: fixed;
14 | height: 24px;
15 | padding: 0 5px;
16 | display: inline-block;
17 | line-height: 24px;
18 | font-size: 12px;
19 | z-index: 999;
20 | background: #FB7055;
21 | border-radius: 3px;
22 | color: #fff;
23 | transform: translateX(-50%);
24 | // display: none;
25 |
26 | }
27 | &__v-line{
28 | position: fixed;
29 | width: 0;
30 | border-left: 1px solid red;
31 | z-index: 999;
32 | pointer-events: none;
33 | }
34 | &__h-line{
35 | position: fixed;
36 | height: 0;
37 | border-top: 1px solid red;
38 | z-index: 999;
39 | pointer-events: none;
40 | }
41 | &__h-dist-line{
42 | position: fixed;
43 | height: 0;
44 | border-top: 1px dashed #adadad;
45 | z-index: 999;
46 | text-align: center;
47 | pointer-events: none;
48 | .label{
49 | position: absolute;
50 | left: 50%;
51 | top:-4px;
52 | height: 14px;
53 | display: inline-block;
54 | line-height: 14px;
55 | text-align: center;
56 | background: #FB7055;
57 | transform: translate(-50%,-100%);
58 | color: #fff;
59 | padding: 0 5px;
60 | pointer-events: none;
61 | border-radius: 7px;
62 | }
63 | }
64 | &__v-dist-line{
65 |
66 | position: fixed;
67 | width: 0;
68 | border-left: 1px dashed #adadad;
69 | z-index: 999;
70 | text-align: center;
71 | pointer-events: none;
72 | .label{
73 | position: absolute;
74 | top: 50%;
75 | left: -4px;
76 | height: 14px;
77 | display: inline-block;
78 | line-height: 14px;
79 | text-align: center;
80 | background: #FB7055;
81 | transform: translate(-100%,-50%);
82 | color: #fff;
83 | padding: 0 5px;
84 | border-radius: 7px;
85 | }
86 | }
87 | &__h-space-line{
88 | position: fixed;
89 | height: 0;
90 | z-index: 999;
91 | text-align: center;
92 | pointer-events: none;
93 | transform: translateY(-50%);
94 | background: #FB7055;
95 | opacity: 0.4;
96 | line-height: 100%;
97 | .line{
98 | position: absolute;
99 | top:50%;
100 | left: 0;
101 | right: 0;
102 | // border-bottom: 1px dashed #fff;
103 | height: 0;
104 | pointer-events: none;
105 | }
106 | }
107 | &__v-space-line{
108 | position: fixed;
109 | z-index: 999;
110 | text-align: center;
111 | pointer-events: none;
112 | transform: translateX(-50%);
113 | background: #FB7055;
114 | opacity: 0.4;
115 | .line{
116 | position: absolute;
117 | left: 50%;
118 | top:0;
119 | bottom: 0;
120 | width: 0;
121 | // border-right: 1px dashed #fff;
122 | pointer-events: none;
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { moveByDom } from './move';
2 | import { resizeByDom } from './resize';
3 | import { initLine } from './lines/store';
4 |
5 | import './index.less';
6 |
7 | export {
8 | moveByDom,
9 | resizeByDom,
10 | initLine,
11 | }
12 |
--------------------------------------------------------------------------------
/src/lines/align.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 对齐线
3 | */
4 | import { Lines } from './store';
5 | import { findLine } from './lib'
6 |
7 | /**
8 | *
9 | * @param {string} direction 方向,v垂直方向,h水平方向
10 | * @param {*} top
11 | * @param {*} left
12 | * @param {*} height
13 | * @param {*} width
14 | */
15 | function getNearLine(direction, line) {
16 | // 获取两个方向的线数据
17 | // let line = calcLines(top, left, height, width);
18 | if (direction === 'v') {
19 | if (Lines.vLines.length == 0) {
20 | return;
21 | }
22 | if (line.v.length == 0) {
23 | return;
24 | }
25 | let nearLines = line.v.map((item) => {
26 | return findLine(item, Lines.vLines);
27 | }).map((item, i) => {
28 | return {
29 | val: Math.abs(item.pos - line.v[i].pos),
30 | from: line.v[i],
31 | ...item,
32 | }
33 | }).sort((a, b) => a.val - b.val);
34 |
35 | return nearLines.map((tarLine, index) => {
36 | let display = tarLine.val === 0;
37 | if (index === 0 && tarLine.val > 0) {
38 | display = true;
39 | }
40 | return {
41 | type: tarLine.type,
42 | display,
43 | pos: tarLine.pos,
44 | start: Math.min(tarLine.from.start, tarLine.start),
45 | end: Math.max(tarLine.from.end, tarLine.end),
46 | from: tarLine.from,
47 | }
48 | })
49 |
50 | } else {
51 | if (Lines.hLines.length == 0) {
52 | return;
53 | }
54 | if (line.h.length == 0) {
55 | return;
56 | }
57 | let nearLines = line.h.map((item) => {
58 | return findLine(item, Lines.hLines);
59 | }).map((item, i) => {
60 | return {
61 | val: Math.abs(item.pos - line.h[i].pos),
62 | from: line.h[i],
63 | ...item,
64 | }
65 | }).sort((a, b) => a.val - b.val);
66 |
67 | return nearLines.map((tarLine, index) => {
68 | let display = tarLine.val === 0;
69 | if (index === 0 && tarLine.val > 0) {
70 | display = true;
71 | }
72 | return {
73 | type: tarLine.type,
74 | display,
75 | pos: tarLine.pos,
76 | start: Math.min(tarLine.from.start, tarLine.start),
77 | end: Math.max(tarLine.from.end, tarLine.end),
78 | from: tarLine.from,
79 | }
80 | })
81 | // return []
82 | }
83 | }
84 |
85 | function createSpaceLineRoot() {
86 | let id = `view__align-line-root`;
87 | let dom = document.getElementById(id);
88 | if (!dom) {
89 | let div = document.createElement('div');
90 | div.id = id;
91 | document.body.appendChild(div);
92 | dom = div;
93 | }
94 | return dom;
95 | }
96 |
97 |
98 | function createVLines(key, { pos, start, end, display }, offsetTop, offsetLeft) {
99 | let id = 'view__v-line_' + key;
100 | let cls = 'view__v-line';
101 | let dom = document.getElementById(id);
102 | let root = createSpaceLineRoot();
103 | if (!dom) {
104 | let div = document.createElement('div');
105 | div.id = id;
106 | div.className = cls;
107 | root.appendChild(div);
108 | dom = div;
109 | }
110 | dom.style.display = display ? 'block' : 'none';
111 | dom.style.left = `${pos + offsetLeft}px`;
112 | dom.style.top = `${start + offsetTop}px`;
113 | dom.style.height = `${end - start}px`;
114 | }
115 |
116 | function createHLines(key, { pos, start, end, display }, offsetTop, offsetLeft) {
117 | let id = 'view__h-line_' + key;
118 | let cls = 'view__h-line';
119 | let dom = document.getElementById(id);
120 | let root = createSpaceLineRoot();
121 | if (!dom) {
122 | let div = document.createElement('div');
123 | div.id = id;
124 | div.className = cls;
125 | root.appendChild(div);
126 | dom = div;
127 | }
128 | dom.style.display = display ? 'block' : 'none';
129 | dom.style.left = `${start + offsetLeft}px`;
130 | dom.style.top = `${pos + offsetTop}px`;
131 | dom.style.width = `${end - start}px`;
132 | }
133 |
134 | /**
135 | * 显示对齐线
136 | * @param {*} line
137 | * @param {*} offsetTop
138 | * @param {*} offsetLeft
139 | */
140 | export function showAlignLine(line, offsetTop, offsetLeft) {
141 |
142 | let vResult = getNearLine('v', line);
143 | let hResult = getNearLine('h', line);
144 |
145 | if (vResult && vResult.length > 0) {
146 | // console.log(vResult)
147 | vResult.forEach((item, index) => {
148 | createVLines(index, item, offsetTop, offsetLeft);
149 | })
150 | }
151 | if (hResult && hResult.length > 0) {
152 | // console.log(hResult)
153 | hResult.forEach((item, index) => {
154 | createHLines(index, item, offsetTop, offsetLeft);
155 | })
156 | }
157 |
158 | if (!vResult && !hResult) {
159 | return null;
160 | }
161 | return {
162 | vLine: vResult ? vResult.find(p => p.display) : null,
163 | hLine: hResult ? hResult.find(p => p.display) : null,
164 | }
165 | }
166 |
167 | /**
168 | * 隐藏
169 | */
170 | export const hideAlignLine = () => {
171 | let root = createSpaceLineRoot();
172 | if (root.parentNode) {
173 | root.parentNode.removeChild(root);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/lines/distance.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 距离线
3 | */
4 |
5 | function createSpaceLineRoot() {
6 | let id = `view__dist-line-root`;
7 | let dom = document.getElementById(id);
8 | if (!dom) {
9 | let div = document.createElement('div');
10 | div.id = id;
11 | document.body.appendChild(div);
12 | dom = div;
13 | }
14 | return dom;
15 | }
16 |
17 |
18 | /**
19 | * 创建距离线
20 | * @param {*} param0
21 | * @param {*} offsetTop
22 | * @param {*} offsetLeft
23 | */
24 | function createHDistLine({ pos, start, end }, offsetTop, offsetLeft) {
25 | let id = 'view__h-dist-line';
26 | let dom = document.getElementById(id);
27 | let root = createSpaceLineRoot();
28 | if (!dom) {
29 | let div = document.createElement('div');
30 | div.id = id;
31 | div.className = id;
32 | root.appendChild(div);
33 | dom = div;
34 | }
35 | let l = start, r = end;
36 | if (start > end) {
37 | l = end, r = start
38 | }
39 | dom.innerHTML = `${r - l}
`;
40 | dom.style.display = 'block';
41 | dom.style.left = `${l + offsetLeft}px`;
42 | dom.style.top = `${pos + offsetTop}px`;
43 | dom.style.width = `${Math.abs(r - l)}px`;
44 | }
45 |
46 | function createVDistLine({ pos, start, end }, offsetTop, offsetLeft) {
47 | let id = 'view__v-dist-line';
48 | let dom = document.getElementById(id);
49 | let root = createSpaceLineRoot();
50 | if (!dom) {
51 | let div = document.createElement('div');
52 | div.id = id;
53 | div.className = id;
54 | root.appendChild(div);
55 | dom = div;
56 | }
57 | let t = start, b = end;
58 | if (start > end) {
59 | t = end, b = start
60 | }
61 | dom.innerHTML = `${b - t}
`;
62 | dom.style.display = 'block';
63 | dom.style.left = `${pos + offsetLeft}px`;
64 | dom.style.top = `${t + offsetTop}px`;
65 | dom.style.height = `${Math.abs(b - t)}px`;
66 | }
67 |
68 |
69 | /**
70 | * 显示距离线
71 | */
72 | export function showDistLine(direction, from, to, offsetTop, offsetLeft) {
73 | let {
74 | start, end,
75 | } = from;
76 | let fromPos = from.pos, toPos = to.pos;
77 | // if (Math.abs(from.pos - to.pos) < 5) {
78 | // toPos = fromPos;
79 | // }
80 | if (direction === 'v') {
81 | let line = {
82 | start: fromPos,
83 | end: toPos,
84 | pos: (end + start) / 2,
85 | }
86 | // console.log(line)
87 | createHDistLine(line, offsetTop, offsetLeft);
88 | } else {
89 | let line = {
90 | start: fromPos,
91 | end: toPos,
92 | pos: (end + start) / 2
93 | }
94 | createVDistLine(line, offsetTop, offsetLeft);
95 | }
96 |
97 |
98 | }
99 |
100 | /**
101 | * 隐藏
102 | */
103 | export const hideDistLine = () => {
104 | let root = createSpaceLineRoot();
105 | if (root.parentNode) {
106 | root.parentNode.removeChild(root);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/lines/label.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * size标签
3 | */
4 |
5 |
6 |
7 | /**
8 | * 隐藏label
9 | * @param {*} id
10 | */
11 | export const hideLabel = () => {
12 | let id = 'view__resize-label';
13 | let dom = document.getElementById(id);
14 | if (!dom) {
15 | return;
16 | }
17 | if (dom.parentNode) {
18 | dom.parentNode.removeChild(dom);
19 | }
20 | }
21 |
22 | export function showLabel(view: HTMLElement, content) {
23 | let id = 'view__resize-label';
24 | let rect = view.getBoundingClientRect();
25 | let dom = document.getElementById(id);
26 | if (!dom) {
27 | let div = document.createElement('div');
28 | div.id = id;
29 | div.className = id;
30 | document.body.appendChild(div);
31 | dom = div;
32 | }
33 | dom.style.display = 'block';
34 | dom.style.top = `${rect.bottom + 5}px`;
35 | dom.style.left = `${rect.left + rect.width / 2}px`;
36 | dom.innerHTML = content;
37 | }
38 |
--------------------------------------------------------------------------------
/src/lines/lib.ts:
--------------------------------------------------------------------------------
1 | import { ILine } from '../types';
2 | /**
3 | * 寻找和tarLine邻近的线
4 | * @param {*} tarLine 源线
5 | * @param {*} lines 线的数组
6 | */
7 | export function findLine(tarLine: ILine, lines: ILine[]) {
8 | // 可以使用二分查找
9 | let l = 0, r = lines.length - 1;
10 |
11 | while (l <= r) {
12 | let i = Math.round(((r - (r - l) / 2)));
13 | if (tarLine.pos < lines[i].pos) {
14 | r = i - 1;
15 | } else if (tarLine.pos > lines[i].pos) {
16 | l = i + 1;
17 | } else {
18 | return lines[i];
19 | }
20 | }
21 | if (l == r) {
22 | return lines[l];
23 | }
24 |
25 | if (l > r) {
26 | if (l >= lines.length) {
27 | return lines[r];
28 | }
29 | if (r < 0) {
30 | return lines[0];
31 | }
32 | let x1 = Math.abs(lines[r].pos - tarLine.pos);
33 | let x2 = Math.abs(lines[l].pos - tarLine.pos);
34 | return x1 < x2 ? lines[r] : lines[l];
35 | }
36 | }
37 |
38 |
39 | export function calcLines(top: number, left: number, height: number, width: number) {
40 | return {
41 | v: [
42 | { type: 'vl', pos: left, start: top, end: top + height },
43 | { type: 'vm', pos: left + width / 2, start: top, end: top + height },
44 | { type: 'vr', pos: left + width, start: top, end: top + height }],
45 | h: [
46 | { type: 'ht', pos: top, start: left, end: left + width },
47 | { type: 'hm', pos: top + height / 2, start: left, end: left + width },
48 | { type: 'hb', pos: top + height, start: left, end: left + width },
49 | ]
50 | }
51 | }
52 |
53 |
54 |
55 | export function calcDirectionCreator() {
56 | let lastTop, lastLeft, lastDirection;
57 | return function (top, left) {
58 | if (!lastTop) {
59 | lastTop = top;
60 | }
61 | if (!lastLeft) {
62 | lastLeft = left;
63 | }
64 |
65 | let direction;
66 | // console.log(top, left, lastTop, lastLeft)
67 | let topOffset = Math.abs(top - lastTop),
68 | leftOffset = Math.abs(left - lastLeft);
69 | if (topOffset > leftOffset) {
70 | direction = 'v';
71 | } else if (topOffset < leftOffset) {
72 | direction = 'h';
73 | } else {
74 | direction = lastDirection;
75 | }
76 | lastTop = top;
77 | lastLeft = left;
78 | lastDirection = direction;
79 | return direction;
80 | }
81 | }
82 |
83 | export const calcDirection = calcDirectionCreator();
84 |
85 |
86 |
87 | export function debounce(fn, delay) {
88 | let timer: any = null;
89 | return function () {
90 | let args = arguments,
91 | context = this;
92 | if (timer) {
93 | clearTimeout(timer);
94 |
95 | timer = setTimeout(() => {
96 | fn.apply(context, args);
97 | }, delay);
98 | } else {
99 | timer = setTimeout(() => {
100 | fn.apply(context, args);
101 | }, delay);
102 | }
103 | };
104 | }
105 |
106 | export function throttle(fn, delay) {
107 | let timer: any = null,
108 | remaining = 0,
109 | previous = Date.now();
110 |
111 | return function () {
112 | let args = arguments,
113 | context = this;
114 | let now = Date.now();
115 | remaining = now - previous;
116 |
117 | if (remaining >= delay) {
118 | if (timer) {
119 | clearTimeout(timer);
120 | }
121 |
122 | fn.apply(context, args);
123 | previous = now;
124 | } else {
125 | if (!timer) {
126 | timer = setTimeout(() => {
127 | fn.apply(context, args);
128 | previous = Date.now()
129 | }, delay - remaining);
130 | }
131 | }
132 | };
133 | }
134 |
--------------------------------------------------------------------------------
/src/lines/space.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 间距块
3 | */
4 | import { ISpace, IDirection } from '../types';
5 | import { Lines } from './store';
6 | import { ILine } from 'src/types';
7 |
8 | function createSpaceLineRoot(direction) {
9 | let id = `view__${direction}-dist-line-root`;
10 | let dom = document.getElementById(id);
11 | if (!dom) {
12 | let div = document.createElement('div');
13 | div.id = id;
14 | document.body.appendChild(div);
15 | dom = div;
16 | }
17 | return dom;
18 | }
19 |
20 | function createHSpaceLine({ pos, start, end, height }, offsetTop, offsetLeft) {
21 | let id = 'view__h-space-line_' + start;
22 | let root = createSpaceLineRoot('h');
23 | let dom = document.getElementById(id);
24 | if (!dom) {
25 | let div = document.createElement('div');
26 | div.id = id;
27 | div.className = 'view__h-space-line';
28 | root.appendChild(div);
29 | dom = div;
30 | }
31 | let l = start, r = end;
32 | if (start > end) {
33 | l = end, r = start
34 | }
35 | dom.innerHTML = ``;
36 | dom.style.display = 'block';
37 | dom.style.left = `${l + offsetLeft}px`;
38 | dom.style.top = `${pos + offsetTop}px`;
39 | dom.style.width = `${Math.abs(r - l)}px`;
40 | dom.style.height = `${height}px`;
41 | }
42 |
43 |
44 | function createVSpaceLine({ pos, start, end, width }, offsetTop, offsetLeft) {
45 | let id = 'view__v-space-line_' + start;
46 | let root = createSpaceLineRoot('v');
47 | let dom = document.getElementById(id);
48 | if (!dom) {
49 | let div = document.createElement('div');
50 | div.id = id;
51 | div.className = 'view__v-space-line';
52 | root.appendChild(div);
53 | dom = div;
54 | }
55 | let t = start, b = end;
56 | if (start > end) {
57 | t = end, b = start
58 | }
59 | dom.innerHTML = ``;
60 | dom.style.display = 'block';
61 | dom.style.left = `${pos + offsetLeft}px`;
62 | dom.style.top = `${t + offsetTop}px`;
63 | dom.style.width = `${width}px`;
64 | dom.style.height = `${Math.abs(b - t)}px`;
65 | }
66 |
67 | export function createVSpaceLines(lineIndexPairs: ISpace[] = [], offsetTop, offsetLeft) {
68 | hideSpaceLine('v');
69 | lineIndexPairs.forEach((item) => {
70 | let { from, to } = item;
71 | let l1 = from as ILine;
72 | let l2 = to as ILine;
73 | // { pos, start, end }, offsetTop, offsetLeft
74 | let t = Math.min(l1.start, l2.start, l1.end, l2.end);
75 | let b = Math.max(l1.start, l2.start, l1.end, l2.end);
76 | let line = {
77 | pos: (l1.start + l1.end) / 2,
78 | start: l1.pos,
79 | end: l2.pos,
80 | height: b - t,
81 | };
82 |
83 | createHSpaceLine(line, offsetTop, offsetLeft);
84 | });
85 | }
86 |
87 |
88 | export function createHSpaceLines(lineIndexPairs: ISpace[] = [], offsetTop, offsetLeft) {
89 | hideSpaceLine('h');
90 | lineIndexPairs.forEach((item) => {
91 | let { from, to } = item;
92 | let l1 = from as ILine;
93 | let l2 = to as ILine;
94 | // { pos, start, end }, offsetTop, offsetLeft
95 | let l = Math.min(l1.start, l2.start, l1.end, l2.end);
96 | let r = Math.max(l1.start, l2.start, l1.end, l2.end);
97 | let line = {
98 | pos: (l1.start + l1.end) / 2,
99 | start: l1.pos,
100 | end: l2.pos,
101 | width: r - l,
102 | };
103 | createVSpaceLine(line, offsetTop, offsetLeft);
104 | });
105 | }
106 |
107 | function calcAllSpaceLines(direction: IDirection, allLines: ILine[] = [], tarLines: ILine): Array {
108 | // 计算vl,vr的间距,按顺序查找,确保vl>vr,连续的vl>vr的线
109 | let i: number = 0, j: number = 1, results: Array> = [];
110 | let l1type = direction === 'v' ? 'vr' : 'hb';
111 | let l2type = direction === 'v' ? 'vl' : 'ht';
112 | let mid = (tarLines[0].end - tarLines[0].start) / 2 + tarLines[0].start;
113 |
114 | let lines: ILine[] = allLines.concat(tarLines).filter((line: ILine) => {
115 | // 父容器的线去除
116 | if (line.start === 0) {
117 | return false;
118 | }
119 | if (line.type === 'vm' || line.type === 'hm') {
120 | return false;
121 | }
122 | if (line.start < mid && line.end > mid) {
123 | return true;
124 | }
125 | return false;
126 | }).sort((a: ILine, b: ILine) => a.pos - b.pos);
127 |
128 | while (j < lines.length) {
129 | if (lines[i].type === l1type) {
130 | if (lines[j].type !== l2type) {
131 | j++;
132 | continue;
133 | }
134 | if (lines[i].pos <= tarLines[0].pos && lines[j].pos >= tarLines[2].pos) {
135 | i++;
136 | continue;
137 | }
138 | // i 是vr j是vl
139 | results.push([i, j]);
140 | }
141 |
142 | i++; j++;
143 | }
144 |
145 | return results.map((item) => {
146 | let [i, j] = item;
147 | return {
148 | from: lines[i],
149 | to: lines[j],
150 | dist: lines[j].pos - lines[i].pos,
151 | }
152 | })
153 | }
154 |
155 | function findTarSpaceLine(spaceLines, tarLines) {
156 | let left = tarLines[0];
157 | let right = tarLines[2];
158 | let leftTar, rightTar;
159 | if (spaceLines.length <= 1) {
160 | return []
161 | }
162 | spaceLines.forEach((line, index) => {
163 | let { from, to } = line;
164 | if (left.pos === to.pos) {
165 | if (index < 1) {
166 | return;
167 | }
168 | let line = spaceLines[index - 1];
169 | let dist = line.dist;
170 | leftTar = from.pos + dist;
171 | }
172 | if (right.pos === from.pos) {
173 | if (index >= spaceLines.length - 1) {
174 | return;
175 | }
176 | let line = spaceLines[index + 1];
177 | let dist = line.dist;
178 | rightTar = to.pos - dist;
179 | }
180 | })
181 | return [leftTar, rightTar]
182 | }
183 |
184 | /**
185 | *
186 | *显示间距线,返回最近的间距块以及目标吸附位置
187 | */
188 | export const showSpaceLine = (direction: IDirection, line, offsetTop, offsetLeft) => {
189 | //判断是横向还是纵向,
190 | //计算组件的间距,显示同一方向的间距,
191 | // let results;
192 | if (direction === 'h') {
193 | let spaceLines = calcAllSpaceLines('h', Lines.hLines, line.h);
194 | createHSpaceLines(spaceLines, offsetTop, offsetLeft);
195 | } else {
196 | let spaceLines = calcAllSpaceLines('v', Lines.vLines, line.v);
197 | createVSpaceLines(spaceLines, offsetTop, offsetLeft)
198 | }
199 | }
200 |
201 | export const calcSpaceLineList = (direction, line) => {
202 | let results, spaceLines;
203 | if (direction === 'h') {
204 | spaceLines = calcAllSpaceLines('h', Lines.hLines, line.h);
205 | results = findTarSpaceLine(spaceLines, line.h);
206 | } else {
207 | spaceLines = calcAllSpaceLines('v', Lines.vLines, line.v);
208 | results = findTarSpaceLine(spaceLines, line.v);
209 | }
210 | return results;
211 | }
212 |
213 |
214 | /**
215 | * 隐藏
216 | * @param {string} direction 方向
217 | */
218 | export const hideSpaceLine = (direction:IDirection) => {
219 | let hdom = document.getElementById(`view__${direction}-dist-line-root`);
220 | if (!hdom) {
221 | return;
222 | }
223 | hdom.remove();
224 | }
225 |
--------------------------------------------------------------------------------
/src/lines/store.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 线的存储
3 | */
4 | import { ILineStore, ILine } from '../types';
5 |
6 | import {
7 | calcLines
8 | } from './lib';
9 | /**
10 | * line 集合,{pos,type,start,end}
11 | */
12 | export const Lines: ILineStore = {
13 | vLines: [],
14 | hLines: []
15 | }
16 |
17 | /**
18 | * 初始化容器内的线数据
19 | */
20 | export function initLine(childs: HTMLElement[], dragDom: HTMLElement) {
21 |
22 | let vLines: Array = [], hLines: Array = [];
23 |
24 | for (let i = 0; i < childs.length; i++) {
25 | const child = childs[i] as HTMLElement;
26 | if (child === dragDom) {
27 | continue;
28 | }
29 | let {
30 | offsetTop,
31 | offsetLeft,
32 | offsetHeight,
33 | offsetWidth
34 | } = child;
35 | let l = calcLines(offsetTop, offsetLeft, offsetHeight, offsetWidth);
36 | vLines = vLines.concat(l.v);
37 | hLines = hLines.concat(l.h);
38 | }
39 |
40 | Lines.vLines = vLines.sort((a, b) => a.pos - b.pos);
41 | Lines.hLines = hLines.sort((a, b) => a.pos - b.pos);
42 | }
43 |
--------------------------------------------------------------------------------
/src/move.ts:
--------------------------------------------------------------------------------
1 | import {
2 | calcLines,
3 | calcDirection,
4 | debounce,
5 | } from './lines/lib';
6 | import {
7 | showAlignLine,
8 | hideAlignLine
9 | } from './lines/align';
10 | import {
11 | showDistLine,
12 | hideDistLine
13 | } from './lines/distance';
14 | import {
15 | showSpaceLine,
16 | calcSpaceLineList,
17 | hideSpaceLine
18 | } from './lines/space';
19 |
20 | import {
21 | showLabel, hideLabel
22 | } from './lines/label';
23 |
24 | import { DIST } from './constants'
25 |
26 | function calcTarPos(top, left, height, width, vLine, hLine) {
27 | let tarLeft = left, tarTop = top;
28 | if (!vLine) {
29 | tarLeft = left
30 | } else if (vLine.from.pos < vLine.pos + DIST && vLine.from.pos > vLine.pos - DIST) {
31 | if (vLine.from.type === 'vl') {
32 | tarLeft = vLine.pos;
33 | } else if (vLine.from.type === 'vm') {
34 | tarLeft = vLine.pos - width / 2;
35 | } else if (vLine.from.type === 'vr') {
36 | tarLeft = vLine.pos - width;
37 | }
38 | }
39 | if (!hLine) {
40 | tarTop = top
41 | } else if (hLine.from.pos < hLine.pos + DIST && hLine.from.pos > hLine.pos - DIST) {
42 | if (hLine.from.type === 'ht') {
43 | tarTop = hLine.pos;
44 | } else if (hLine.from.type === 'hm') {
45 | tarTop = hLine.pos - height / 2;
46 | } else if (hLine.from.type === 'hb') {
47 | tarTop = hLine.pos - height;
48 | }
49 | }
50 | return {
51 | top: tarTop,
52 | left: tarLeft,
53 | }
54 | }
55 |
56 |
57 | function showSapceLines(direction, tarLine, { top, left, width, height }, offsetTop, offsetLeft) {
58 | let tarLeft = left;
59 | let tarTop = top;
60 |
61 | if (direction == 'h') {
62 |
63 | let [spaceLeft, spaceRight] = calcSpaceLineList('v', tarLine);
64 |
65 | if (tarLeft > spaceLeft - DIST && tarLeft < spaceLeft + DIST) {
66 | tarLeft = spaceLeft;
67 | showSpaceLine('v', calcLines(tarTop, tarLeft, height, width), offsetTop, offsetLeft)
68 | }
69 |
70 | if (tarLeft > spaceRight - width - DIST && tarLeft < spaceRight - width + DIST) {
71 | tarLeft = spaceRight - width;
72 | showSpaceLine('v', calcLines(tarTop, tarLeft, height, width), offsetTop, offsetLeft)
73 | }
74 | } else {
75 |
76 | let [spaceTop, spaceBottom] = calcSpaceLineList('h', tarLine);
77 |
78 | if (tarTop > spaceTop - DIST && tarTop < spaceTop + DIST) {
79 | tarTop = spaceTop;
80 | showSpaceLine('h', calcLines(tarTop, tarLeft, height, width), offsetTop, offsetLeft)
81 | }
82 |
83 | if (tarTop > spaceBottom - height - DIST && tarTop < spaceBottom - height + DIST) {
84 | tarTop = spaceBottom - height;
85 | showSpaceLine('h', calcLines(tarTop, tarLeft, height, width), offsetTop, offsetLeft)
86 | }
87 | }
88 | return {
89 | top: tarTop,
90 | left: tarLeft,
91 | }
92 | }
93 |
94 | function showAlignLines(tarLine, { top, left, width, height }, offsetTop, offsetLeft) {
95 | let nearLine = showAlignLine(tarLine, offsetTop, offsetLeft);
96 |
97 | let tarLeft = left, tarTop = top;
98 | if (nearLine) {
99 | let {
100 | vLine,
101 | hLine
102 | } = nearLine;
103 |
104 | let tarPos = calcTarPos(top, left, height, width, vLine, hLine);
105 |
106 | tarLeft = tarPos.left;
107 | tarTop = tarPos.top;
108 |
109 | if (top != tarTop || left != tarLeft) {
110 | showAlignLine(calcLines(tarTop, tarLeft, height, width), offsetTop, offsetLeft);
111 | }
112 |
113 | let fromVLine = vLine.from;
114 | let fromHLine = hLine.from;
115 | let map = { 'vl': 0, 'vm': 1, 'vr': 2, 'ht': 0, 'hm': 1, 'hb': 2 };
116 | if (tarLeft != left || tarTop != top) {
117 | let newLine = calcLines(tarTop, tarLeft, height, width);
118 | fromVLine = newLine.v[map[fromVLine.type]]
119 | fromHLine = newLine.h[map[fromHLine.type]]
120 | }
121 | showDistLine('v', fromVLine, vLine, offsetTop, offsetLeft);
122 | showDistLine('h', fromHLine, hLine, offsetTop, offsetLeft);
123 | }
124 | return {
125 | top: tarTop,
126 | left: tarLeft
127 | }
128 | }
129 |
130 |
131 | function hideLines() {
132 | hideAlignLine();
133 | hideSpaceLine('h');
134 | hideSpaceLine('v');
135 | hideDistLine();
136 | hideLabel()
137 | }
138 |
139 | const moveDeb: any = debounce((cb) => {
140 | cb();
141 | }, 1000);
142 |
143 | export const moveByDom = (dom, top, left, onMoveEnd) => {
144 |
145 | if (!dom) {
146 | return;
147 | }
148 | let cotainer = dom.parentNode.getBoundingClientRect();
149 | let offsetTop = cotainer.top;
150 | let offsetLeft = cotainer.left;
151 |
152 | let rect = dom.getBoundingClientRect();
153 | let {
154 | height, width,
155 | } = rect;
156 |
157 | let direction = calcDirection(top, left);
158 | let tarLine = calcLines(top, left, height, width);
159 | let tarLeft = left, tarTop = top;
160 |
161 |
162 | let tarSpaceInfo = showSapceLines(direction, tarLine, { top: tarTop, left: tarLeft, width, height }, offsetTop, offsetLeft);
163 |
164 | tarTop = tarSpaceInfo.top;
165 | tarLeft = tarSpaceInfo.left;
166 |
167 | let alignLineInfo = showAlignLines(tarLine, { top: tarTop, left: tarLeft, width, height }, offsetTop, offsetLeft);
168 |
169 | tarTop = alignLineInfo.top;
170 | tarLeft = alignLineInfo.left;
171 |
172 |
173 | dom.style.left = `${tarLeft}px`;
174 | dom.style.top = `${tarTop}px`;
175 |
176 | showLabel(dom, `X:${tarLeft},Y:${tarTop}`);
177 |
178 | moveDeb(function () {
179 | hideLines();
180 | if (onMoveEnd) {
181 | onMoveEnd(tarTop, tarLeft);
182 | }
183 | })
184 | }
185 |
--------------------------------------------------------------------------------
/src/resize.ts:
--------------------------------------------------------------------------------
1 | import {
2 | calcLines, debounce,
3 | } from './lines/lib';
4 | import {
5 | showAlignLine, hideAlignLine
6 | } from './lines/align';
7 | import {
8 | showDistLine, hideDistLine
9 | } from './lines/distance';
10 |
11 | import {
12 | showLabel, hideLabel
13 | } from './lines/label'
14 |
15 | import { DIST } from './constants'
16 | import { hideSpaceLine } from './lines/space';
17 |
18 | function calcTarSize(top, left, height, width, vLine, hLine) {
19 | let tarLeft = left, tarTop = top, tarHeight = height, tarWidth = width;
20 | if (vLine) {
21 | if (vLine.from.pos < vLine.pos + DIST && vLine.from.pos > vLine.pos - DIST) {
22 | if (vLine.from.type === 'vl') {
23 | tarLeft = vLine.pos;
24 | tarWidth = width + (vLine.from.pos - vLine.pos);
25 | } else if (vLine.from.type === 'vm') {
26 | // tarLeft = vLine.pos - width / 2;
27 | } else if (vLine.from.type === 'vr') {
28 | tarWidth = width + (vLine.pos - vLine.from.pos);
29 | tarLeft = vLine.pos - tarWidth;
30 | }
31 | }
32 | }
33 | if (hLine) {
34 | if (hLine.from.pos < hLine.pos + DIST && hLine.from.pos > hLine.pos - DIST) {
35 | if (hLine.from.type === 'ht') {
36 | tarTop = hLine.pos;
37 | tarHeight = height + (hLine.from.pos - hLine.pos);
38 | } else if (hLine.from.type === 'hm') {
39 | tarTop = hLine.pos - height / 2;
40 | } else if (hLine.from.type === 'hb') {
41 | tarHeight = height + (hLine.pos - hLine.from.pos);
42 | tarTop = hLine.pos - tarHeight;
43 | }
44 | }
45 | }
46 | return {
47 | top: tarTop,
48 | left: tarLeft,
49 | height: tarHeight,
50 | width: tarWidth
51 | }
52 | }
53 |
54 | const DIRECTION = {
55 | 'tc': ['ht'],
56 | 'bc': ['hb'],
57 | 'rc': ['vr'],
58 | 'lc': ['vl'],
59 | 'tl': ['ht', 'vl'],
60 | 'tr': ['ht', 'vr'],
61 | 'br': ['hb', 'vr'],
62 | 'bl': ['hb', 'vl'],
63 | }
64 |
65 | function getTarLine(line, include:string[]=[]) {
66 | let v = line.v.filter((item) => {
67 | return include.indexOf(item.type) >= 0;
68 | });
69 | let h = line.h.filter((item) => {
70 | return include.indexOf(item.type) >= 0;
71 | });
72 | return {
73 | v, h
74 | }
75 | }
76 |
77 | let last;
78 | function caclHandType(top, left, height, width) {
79 | if (!last) {
80 | last = {
81 | top, left, height, width
82 | }
83 | return [];
84 | }
85 | let lines: string[] = [];
86 | if (top !== last.top) {
87 | lines.push('ht');
88 | }
89 |
90 | if (left !== last.left) {
91 | lines.push('vl');
92 | }
93 |
94 | if (top === last.top && left === last.left && width !== last.width) {
95 | lines.push('vr');
96 | }
97 |
98 | if (top === last.top && left === last.left && height !== last.height) {
99 | lines.push('hb');
100 | }
101 | return lines;
102 | }
103 |
104 | function hideLines() {
105 | last = null;
106 | hideAlignLine();
107 | hideSpaceLine('h');
108 | hideSpaceLine('v');
109 | hideDistLine();
110 | hideLabel()
111 | }
112 |
113 | const moveDeb: any = debounce((cb) => {
114 | cb();
115 | }, 1000);
116 |
117 | export const resizeByDom = (dom, top, left, height, width, onResizeEnd) => {
118 |
119 | if (!dom) {
120 | return;
121 | }
122 | let cotainer = dom.parentNode.getBoundingClientRect();
123 | let offsetTop = cotainer.top;
124 | let offsetLeft = cotainer.left;
125 | let handType = caclHandType(top, left, height, width);
126 | console.log(handType)
127 | let allLines = calcLines(top, left, height, width);
128 | let tarLine = getTarLine(allLines, handType);
129 | let nearLine = showAlignLine(tarLine, offsetTop, offsetLeft);
130 |
131 | let tarLeft = left, tarTop = top, tarHeight = height, tarWidth = width;
132 | // console.log(nearLine)
133 | if (nearLine) {
134 | let {
135 | vLine,
136 | hLine
137 | } = nearLine;
138 | let tarPos = calcTarSize(top, left, height, width, vLine, hLine);
139 | tarLeft = tarPos.left;
140 | tarTop = tarPos.top;
141 | tarHeight = tarPos.height;
142 | tarWidth = tarPos.width;
143 |
144 | if (left != tarLeft || top != tarTop || height != tarHeight || width != tarWidth) {
145 | showAlignLine(calcLines(tarTop, tarLeft, tarHeight, tarWidth), offsetTop, offsetLeft);
146 | }
147 |
148 | let map = { 'vl': 0, 'vm': 1, 'vr': 2, 'ht': 0, 'hm': 1, 'hb': 2 };
149 | if (vLine) {
150 | let fromVLine = vLine.from;
151 | if (tarLeft != left || tarWidth != width) {
152 | let newLine = calcLines(tarTop, tarLeft, tarHeight, tarWidth);
153 | fromVLine = newLine.v[map[fromVLine.type]];
154 | }
155 | showDistLine('v', fromVLine, vLine, offsetTop, offsetLeft);
156 | }
157 | if (hLine) {
158 | let fromHLine = hLine.from;
159 | if (tarTop != top || tarHeight != height) {
160 | let newLine = calcLines(tarTop, tarLeft, tarHeight, tarWidth);
161 | fromHLine = newLine.h[map[fromHLine.type]];
162 | }
163 | showDistLine('h', fromHLine, hLine, offsetTop, offsetLeft);
164 | }
165 | }
166 |
167 | dom.style.top = `${tarTop}px`;
168 | dom.style.left = `${tarLeft}px`;
169 | dom.style.height = `${tarHeight}px`;
170 | dom.style.width = `${tarWidth}px`;
171 |
172 | // showLabel(dom, rect.bottom + 3, rect.left + rect.width / 2, `W:${width},H:${height}`);
173 | showLabel(dom,`W:${width},H:${height}`);
174 |
175 |
176 | moveDeb(function () {
177 | hideLines();
178 | if (onResizeEnd) {
179 | onResizeEnd(tarTop, tarLeft, tarHeight, tarWidth)
180 | }
181 | })
182 | }
183 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 |
2 | export type TLineType = 'vl' | 'vm' | 'vr' | 'ht' | 'hm' | 'hb';
3 | export type IDirection = 'v' | 'h';
4 |
5 | export interface ILine {
6 | type: TLineType;
7 | pos: number;
8 | start: number;
9 | end: number;
10 | }
11 |
12 | export interface ISpace {
13 | from: ILine;
14 | to: ILine;
15 | dist: number;
16 |
17 | }
18 |
19 | export interface ILineStore {
20 | vLines: Array;
21 | hLines: Array;
22 | }
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "noImplicitAny": false,
5 | "strictFunctionTypes":true,
6 | "target":"es6",
7 | "jsx": "react",
8 | "allowJs":true,
9 | "module":"esnext",
10 | "moduleResolution": "node",
11 | "baseUrl":".",
12 | "declaration":false,
13 | "noUnusedParameters": true,
14 | "noUnusedLocals": true,
15 | "strictNullChecks": true,
16 | "paths": {
17 | },
18 | "allowSyntheticDefaultImports":true,
19 | "lib": [
20 | "es2016",
21 | "dom",
22 | "es5"
23 | ]
24 |
25 | },
26 | "include": ["src"],
27 | "exclude": ["node_modules", "lib", "es"]
28 | }
29 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "tslint:recommended",
4 | "tslint-config-prettier"
5 | ],
6 | "rules": {
7 | "class-name": true,
8 | "eofline": true,
9 | "forin": true,
10 | "jsdoc-format": false,
11 | "label-position": true,
12 | "member-ordering": [
13 | true,
14 | {
15 | "order": "statics-first"
16 | }
17 | ],
18 | "new-parens": true,
19 | "no-arg": true,
20 | "no-bitwise": true,
21 | "no-conditional-assignment": true,
22 | "no-consecutive-blank-lines": true,
23 | "no-console": [
24 | true,
25 | "debug",
26 | "info",
27 | "log",
28 | "time",
29 | "timeEnd",
30 | "trace"
31 | ],
32 | "no-construct": true,
33 | "no-debugger": true,
34 | "no-duplicate-variable": true,
35 | "no-eval": true,
36 | "no-internal-module": true,
37 | "no-multi-spaces": true,
38 | "no-namespace": true,
39 | "no-reference": true,
40 | "no-shadowed-variable": true,
41 | "no-string-literal": true,
42 | "no-trailing-whitespace": false,
43 | "no-unused-expression": true,
44 | "no-var-keyword": true,
45 | "object-literal-sort-keys":false,
46 | "interface-name":false,
47 | "one-variable-per-declaration":false,
48 | "prefer-const": [
49 | true,
50 | {
51 | "destructuring": "all"
52 | }
53 | ],
54 | "radix": true,
55 | "space-in-parens": true,
56 | "switch-default": true,
57 | "trailing-comma": [
58 | true,
59 | {
60 | "singleline": "never",
61 | "multiline": "always",
62 | "esSpecCompliant": true
63 | }
64 | ],
65 | "triple-equals": [
66 | true,
67 | "allow-null-check"
68 | ],
69 | "typedef-whitespace": [
70 | true,
71 | {
72 | "call-signature": "nospace",
73 | "index-signature": "nospace",
74 | "parameter": "nospace",
75 | "property-declaration": "nospace",
76 | "variable-declaration": "nospace"
77 | },
78 | {
79 | "call-signature": "onespace",
80 | "index-signature": "onespace",
81 | "parameter": "onespace",
82 | "property-declaration": "onespace",
83 | "variable-declaration": "onespace"
84 | }
85 | ],
86 | "use-isnan": true,
87 | "variable-name": [
88 | true,
89 | "allow-leading-underscore",
90 | "ban-keywords",
91 | "check-format",
92 | "allow-pascal-case"
93 | ],
94 | "jsx-no-lambda": false,
95 | "jsx-no-string-ref": false,
96 | "jsx-boolean-value": [
97 | true,
98 | "never"
99 | ],
100 | "jsx-no-multiline-js": false,
101 | "whitespace": [
102 | false,
103 | "check-branch",
104 | "check-decl",
105 | "check-operator",
106 | "check-module",
107 | "check-separator",
108 | "check-rest-spread",
109 | "check-type",
110 | "check-typecast",
111 | "check-type-operator",
112 | "check-preblock"
113 | ]
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/webpack.base.config.js:
--------------------------------------------------------------------------------
1 | let path = require('path');
2 | let webpack = require('webpack');
3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
4 | module.exports = function (options) {
5 | let {
6 | cdn,
7 | dist,
8 | root,
9 | src
10 | } = options;
11 | let publicPath = `${cdn}`;
12 | let distPath = path.resolve(root, dist);
13 | let def = {
14 | mode: 'development',
15 | entry: {
16 | 'view-line': path.resolve(root, src, 'index.ts'),
17 | },
18 | output: {
19 | path: distPath,
20 | filename: '[name].js',
21 | chunkFilename: '[name].chunk.js',
22 | publicPath: publicPath,
23 | // library: 'PropsEditor',
24 | // libraryTarget: 'umd'
25 | },
26 | module: {
27 | rules: [
28 | // or any other compile-to-css language
29 | {
30 | test: /\.less$/,
31 | use: [
32 | {
33 | loader: MiniCssExtractPlugin.loader,
34 | options: {
35 | // you can specify a publicPath here
36 | // by default it use publicPath in webpackOptions.output
37 | publicPath
38 | }
39 | },
40 | 'css-loader',
41 | {
42 | loader: 'postcss-loader',
43 | options: {
44 | plugins: function () {
45 | return [
46 | require('autoprefixer')
47 | ];
48 | }
49 | }
50 | }, {
51 | loader: 'less-loader',
52 | options: {
53 | javascriptEnabled: true,
54 | modifyVars: {
55 | '@primary-color': '#FB7055',
56 | '@border-radius-base': 0,
57 | '@border-radius-sm ': 0
58 | }
59 | }
60 | }
61 | ]
62 | },
63 | {
64 | test: /\.css$/,
65 | use: [
66 | {
67 | loader: MiniCssExtractPlugin.loader,
68 | options: {
69 | // you can specify a publicPath here
70 | // by default it use publicPath in webpackOptions.output
71 | publicPath
72 | }
73 | },
74 | 'css-loader',
75 | {
76 | loader: 'postcss-loader',
77 | options: {
78 | plugins: function () {
79 | return [
80 | require('autoprefixer')
81 | ];
82 | }
83 | }
84 | }
85 | ]
86 | },
87 | {
88 | test: /\.(js|jsx|ts|tsx)$/,
89 | exclude: /(node_modules|bower_components)/,
90 | use: [
91 | {
92 | loader: 'babel-loader'
93 | }
94 | ]
95 | },
96 | {
97 | test: /\.(jpg|png|gif)$/,
98 | use: [{
99 | loader: 'url-loader',
100 | options: {
101 | limit: 1,
102 | name: 'img/[path][name].[ext]'
103 | }
104 | }]
105 | },
106 | {
107 | test: /\.(eot|svg|ttf|woff)\??.*$/,
108 | use: [{
109 | loader: 'url-loader',
110 | options: {
111 | limit: 1,
112 | name: 'iconfont/[name].[ext]'
113 | }
114 | }]
115 | }
116 | ]
117 |
118 | },
119 | node: {
120 | // Mock Node.js modules that Babel require()s but that we don't
121 | // particularly care about.
122 | fs: 'empty',
123 | module: 'empty',
124 | net: 'empty'
125 | },
126 | cache: true,
127 | resolve: {
128 | alias: {
129 | '@': path.resolve(root, './src'),
130 | },
131 | extensions: ['.json', '.js', '.jsx','.ts','.tsx']
132 | },
133 | plugins: [
134 | // new webpack.IgnorePlugin({
135 | // resourceRegExp: /^\.\/locale$/,
136 | // contextRegExp: /moment$/
137 | // }),
138 |
139 | ]
140 | };
141 | return def;
142 | };
143 |
--------------------------------------------------------------------------------
/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | let webpack = require('webpack');
2 | let path = require('path');
3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 | let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
6 | let webpackBase = require('./webpack.base.config');
7 | let webpackMerge = require('webpack-merge');
8 | let options = {
9 | cdn: '',
10 | dist: 'sample/dist',
11 | root: __dirname,
12 | src: './src'
13 | }
14 | var config = webpackMerge(webpackBase(options), {
15 | mode: 'development',
16 | entry: {
17 | 'index': path.resolve(options.root, 'sample', 'index.ts'),
18 | },
19 | output: {
20 | filename: '[name].js',
21 | chunkFilename: '[name].chunk.js'
22 | },
23 | devServer: {
24 | contentBase: './sample',
25 | },
26 | // optimization: {
27 | // splitChunks: {
28 | // cacheGroups: {
29 | // styles: {
30 | // name: 'styles',
31 | // test: /\.less$|\.css$/,
32 | // chunks: 'all',
33 | // enforce: true
34 | // }
35 | // }
36 | // }
37 | // },
38 | externals: [
39 | {
40 | // 'react': 'React',
41 | // 'react-dom': 'ReactDOM',
42 | // 'react-redux': 'ReactRedux',
43 | // 'redux': 'Redux',
44 | // 'immutable': 'Immutable',
45 | 'jquery': 'jQuery',
46 | // 'esprima-fb': 'esprima',
47 | // 'draft-js': 'Draft',
48 | // 'lodash': '_',
49 | // 'react-router-dom': 'ReactRouterDOM'
50 | },
51 | ],
52 | plugins: [
53 | new webpack.DefinePlugin({
54 | 'process.env.NODE_ENV': JSON.stringify('development')
55 | }),
56 | new HtmlWebpackPlugin({
57 | template:path.resolve(options.root,'sample/tmp.html'),
58 | title: '属性编辑器',
59 | }),
60 | new MiniCssExtractPlugin({
61 | filename: "[name].css",
62 | }),
63 | new BundleAnalyzerPlugin({
64 | analyzerPort: 9999
65 | })
66 | ],
67 | devtool: 'inline-source-map',
68 | });
69 |
70 | console.log(config)
71 | module.exports = config;
72 |
--------------------------------------------------------------------------------
/webpack.prod.config.js:
--------------------------------------------------------------------------------
1 | let webpack = require('webpack');
2 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3 | let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
4 | let webpackBase = require('./webpack.base.config');
5 | let webpackMerge = require('webpack-merge');
6 | let options = {
7 | cdn: '',
8 | dist: 'dist',
9 | root: __dirname,
10 | src: './src'
11 | }
12 | var config = webpackMerge(webpackBase(options), {
13 | mode: 'development',
14 | output: {
15 | filename: '[name].js',
16 | chunkFilename: '[name].chunk.js',
17 | library: 'ViewLine',
18 | libraryTarget: 'umd'
19 | },
20 | externals: [
21 | {
22 | 'react': {
23 | commonjs: 'react',
24 | commonjs2: 'react',
25 | root: 'React'
26 | },
27 | 'react-dom': {
28 | commonjs: 'react-dom',
29 | commonjs2: 'react-dom',
30 | root: 'ReactDOM'
31 | },
32 | 'react-redux': {
33 | commonjs: 'react-redux',
34 | commonjs2: 'react-redux',
35 | root: 'ReactRedux'
36 | },
37 | 'redux': {
38 | commonjs: 'redux',
39 | commonjs2: 'redux',
40 | root: 'Redux'
41 | },
42 | 'immutable': {
43 | commonjs: 'immutable',
44 | commonjs2: 'immutable',
45 | root: 'Immutable'
46 | },
47 | 'jquery': {
48 | commonjs: 'jquery',
49 | commonjs2: 'jquery',
50 | root: 'jQuery'
51 | },
52 | 'esprima-fb': {
53 | commonjs: 'esprima-fb',
54 | commonjs2: 'esprima-fb',
55 | root: 'esprima'
56 | },
57 | 'draft-js': {
58 | commonjs: 'draft-js',
59 | commonjs2: 'draft-js',
60 | root: 'Draft'
61 | },
62 | 'lodash': {
63 | commonjs: 'lodash',
64 | commonjs2: 'lodash',
65 | amd: 'lodash',
66 | root: '_' // indicates global variable
67 | },
68 | 'bondjs': 'bondjs',
69 | 'react-router-dom': {
70 | commonjs: 'react-router-dom',
71 | commonjs2: 'react-router-dom',
72 | amd: 'react-router-dom',
73 | root: 'ReactRouterDOM' // indicates global variable
74 | },
75 | 'prop-types': {
76 | commonjs: 'prop-types',
77 | commonjs2: 'prop-types',
78 | amd: 'prop-types',
79 | root: 'PropTypes' // indicates global variable
80 | },
81 | 'tinycolor2': {
82 | commonjs: 'tinycolor2',
83 | commonjs2: 'tinycolor2',
84 | amd: 'tinycolor2',
85 | root: 'tinycolor2' // indicates global variable
86 | },
87 | 'SketchPicker': {
88 | commonjs: 'SketchPicker',
89 | amd: 'SketchPicker',
90 | root: 'ReactRouterDOM' // indicates global variable
91 | },
92 | 'react-color': {
93 | commonjs: 'react-color',
94 | commonjs2: 'react-color',
95 | amd: 'react-color',
96 | root: 'reactColor' // indicates global variable
97 | },
98 | 'axios': {
99 | commonjs: 'axios',
100 | commonjs2: 'axios',
101 | },
102 | 'add-dom-event-listener': {
103 | commonjs: 'add-dom-event-listener',
104 | commonjs2: 'add-dom-event-listener',
105 | },
106 | 'glamor': {
107 | commonjs: 'glamor',
108 | commonjs2: 'glamor',
109 | }
110 | },
111 | /^antd/,
112 | /^jssha/,
113 | function (context, request, callback) {
114 | if (/antd/.test(request)) {
115 | return callback(null, 'commonjs ' + request);
116 | }
117 | callback();
118 | }
119 | ],
120 | plugins: [
121 | new webpack.DefinePlugin({
122 | 'process.env.NODE_ENV': JSON.stringify('production')
123 | }),
124 | new MiniCssExtractPlugin({
125 | filename: "[name].css",
126 | }),
127 | // new BundleAnalyzerPlugin({
128 | // analyzerPort: 9999
129 | // })
130 | ],
131 | devtool: 'none'
132 | });
133 |
134 | module.exports = config;
135 |
--------------------------------------------------------------------------------