UNPKG

slices

Version:

Node.js module for slicing given area into blocks with the given reference lines

224 lines (173 loc) 5.18 kB
'use strict'; var utils = require('./utils'); function Slices(width, height, lineXArray, lineYArray, options) { options = options || {}; this.width = width; this.height = height; lineXArray = lineXArray || []; lineYArray = lineYArray || []; // 生成参考线的 X Y 方向的边界 lineXArray.push(height); lineYArray.push(width); this.lineXArray = utils.sortAndUnique(lineXArray); this.lineYArray = utils.sortAndUnique(lineYArray); // instance properties this.options = {}; // extend instance properties with global defaults and initial properties utils.extend(this.options, this.defaults, options); // there are no reference lines if (!this.lineXArray.length && !this.lineYArray.length) { throw new Error('At least one reference line'); } return this; } Slices.prototype.defaults = { middleBoundaryMode: false }; Slices.prototype.slice = function() { var options = this.options; var lineXArray = this.lineXArray; var lineYArray = this.lineYArray; var width = this.width; // var height = this.height; var middleBoundaryMode = options.middleBoundaryMode; var lineXLength = lineXArray.length; var lineYLength = lineYArray.length; // 中间边界模式 // 这时会把 X 轴之间的空间作为一个父区块 // 并把第一和最后的 Y 轴之间的区块作为父区块的子级,同时生成边界信息 // Y 轴必须大于 2 根 if (middleBoundaryMode) { if (lineYLength < 3) { middleBoundaryMode = false; } } var previousX = 0; var previousY = 0; var curX, curY, x, y, xEnd, yEnd; // full row when is at middleBoundaryMode // 整行区块信息 var fullRow; // assign to child block info between the first Y line and the last Y line // when is at middleBoundaryMode // 中间边界模式时,第 1 根 与最后一根 Y 轴之间的子区块 var middleChildBlock; var parentBlockIndex = 0; var blocks = []; // 只有 X 轴或 Y 轴的情况 if (!lineYLength || !lineXLength) { return this.getChildBlocks(); } // 非中间边界模式 if (!middleBoundaryMode) { return this.getChildBlocks(); } // 循环 X 和 Y 轴上的参考线,得到区块信息 for (x = 0, xEnd = lineXLength; x < xEnd; x++) { curX = lineXArray[x]; previousY = lineYArray[0]; fullRow = { width: width, height: curX - previousX, x: 0, y: x === 0 ? 0 : previousX, children: [], // 需要抹擦去的图片区域 boundary: { leftTop: { x: lineYArray[0], y: x === 0 ? 0 : previousX }, rightBottom: { x: lineYArray[lineYLength - 2], y: curX } } }; blocks.push(fullRow); for (y = 1, yEnd = lineYLength - 1; y < yEnd; y++) { curY = lineYArray[y]; middleChildBlock = { width: curY - previousY, height: curX - previousX, x: previousY, y: x === 0 ? 0 : previousX }; // 子区块附加额外信息 // left: 距中间主区块左边界的绝对距离 // top: 距中间主区块上边界的绝对距离,由于一直靠着最顶部的位置,所以一直是 0 // parentBlockIndex: 子区块所属父区块的索引值 // index: 子区块在父区块范围之内的索引值 utils.extend(middleChildBlock, { left: y === 1 ? 0 : previousY - lineYArray[0], top: 0, parentBlockIndex: parentBlockIndex, index: y - 1 }); // 将子区块插入到父区块信息中 fullRow.children.push(middleChildBlock); previousY = curY; } parentBlockIndex++; previousX = curX; } return blocks; }; Slices.prototype.getChildBlocks = function() { var lineXArray = this.lineXArray; var lineYArray = this.lineYArray; var width = this.width; var height = this.height; var lineXLength = lineXArray.length; var lineYLength = lineYArray.length; var previousX = 0; var previousY = 0; var curX, curY, x, y, xEnd, yEnd; var blocks = []; // X 轴上有参考线 if (lineXLength) { for (x = 0, xEnd = lineXLength; x < xEnd; x++) { curX = lineXArray[x]; previousY = 0; // Y 轴上也有参考线 if (lineYLength) { for (y = 0, yEnd = lineYLength; y < yEnd; y++) { curY = lineYArray[y]; blocks.push({ width: curY - previousY, height: curX - previousX, x: previousY, y: x === 0 ? 0 : previousX }); previousY = curY; } } // 只有 X 轴的情况 else { blocks.push({ width: width, height: curX - previousX, x: 0, y: x === 0 ? 0 : previousX }); } previousX = curX; } } // 只有 Y 轴的情况 else { previousY = 0; for (y = 0, yEnd = lineYLength; y < yEnd; y++) { curY = lineYArray[y]; blocks.push({ width: curY - previousY, height: height, x: x === 0 ? 0 : previousY, y: 0 }); previousY = curY; } } return blocks; }; module.exports = Slices;