UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

279 lines (278 loc) 8.52 kB
import WeakMap from "../../../zrender/lib/core/WeakMap.mjs"; import LRUCache from "../../../zrender/lib/core/LRU.mjs"; import { defaults, isArray, isString, isNumber, map } from "../../../zrender/lib/core/util.mjs"; import { getLeastCommonMultiple } from "./number.mjs"; import { createSymbol } from "./symbol.mjs"; import { brushSingle } from "../../../zrender/lib/canvas/graphic.mjs"; import { platformApi } from "../../../zrender/lib/core/platform.mjs"; var decalMap = new WeakMap(); var decalCache = new LRUCache(100); var decalKeys = ["symbol", "symbolSize", "symbolKeepAspect", "color", "backgroundColor", "dashArrayX", "dashArrayY", "maxTileWidth", "maxTileHeight"]; function createOrUpdatePatternFromDecal(decalObject, api) { if (decalObject === "none") { return null; } var dpr = api.getDevicePixelRatio(); var zr = api.getZr(); var isSVG = zr.painter.type === "svg"; if (decalObject.dirty) { decalMap["delete"](decalObject); } var oldPattern = decalMap.get(decalObject); if (oldPattern) { return oldPattern; } var decalOpt = defaults(decalObject, { symbol: "rect", symbolSize: 1, symbolKeepAspect: true, color: "rgba(0, 0, 0, 0.2)", backgroundColor: null, dashArrayX: 5, dashArrayY: 5, rotation: 0, maxTileWidth: 512, maxTileHeight: 512 }); if (decalOpt.backgroundColor === "none") { decalOpt.backgroundColor = null; } var pattern = { repeat: "repeat" }; setPatternnSource(pattern); pattern.rotation = decalOpt.rotation; pattern.scaleX = pattern.scaleY = isSVG ? 1 : 1 / dpr; decalMap.set(decalObject, pattern); decalObject.dirty = false; return pattern; function setPatternnSource(pattern2) { var keys = [dpr]; var isValidKey = true; for (var i = 0; i < decalKeys.length; ++i) { var value = decalOpt[decalKeys[i]]; if (value != null && !isArray(value) && !isString(value) && !isNumber(value) && typeof value !== "boolean") { isValidKey = false; break; } keys.push(value); } var cacheKey; if (isValidKey) { cacheKey = keys.join(",") + (isSVG ? "-svg" : ""); var cache = decalCache.get(cacheKey); if (cache) { isSVG ? pattern2.svgElement = cache : pattern2.image = cache; } } var dashArrayX = normalizeDashArrayX(decalOpt.dashArrayX); var dashArrayY = normalizeDashArrayY(decalOpt.dashArrayY); var symbolArray = normalizeSymbolArray(decalOpt.symbol); var lineBlockLengthsX = getLineBlockLengthX(dashArrayX); var lineBlockLengthY = getLineBlockLengthY(dashArrayY); var canvas = !isSVG && platformApi.createCanvas(); var svgRoot = isSVG && { tag: "g", attrs: {}, key: "dcl", children: [] }; var pSize = getPatternSize(); var ctx; if (canvas) { canvas.width = pSize.width * dpr; canvas.height = pSize.height * dpr; ctx = canvas.getContext("2d"); } brushDecal(); if (isValidKey) { decalCache.put(cacheKey, canvas || svgRoot); } pattern2.image = canvas; pattern2.svgElement = svgRoot; pattern2.svgWidth = pSize.width; pattern2.svgHeight = pSize.height; function getPatternSize() { var width = 1; for (var i2 = 0, xlen = lineBlockLengthsX.length; i2 < xlen; ++i2) { width = getLeastCommonMultiple(width, lineBlockLengthsX[i2]); } var symbolRepeats = 1; for (var i2 = 0, xlen = symbolArray.length; i2 < xlen; ++i2) { symbolRepeats = getLeastCommonMultiple(symbolRepeats, symbolArray[i2].length); } width *= symbolRepeats; var height = lineBlockLengthY * lineBlockLengthsX.length * symbolArray.length; return { width: Math.max(1, Math.min(width, decalOpt.maxTileWidth)), height: Math.max(1, Math.min(height, decalOpt.maxTileHeight)) }; } function brushDecal() { if (ctx) { ctx.clearRect(0, 0, canvas.width, canvas.height); if (decalOpt.backgroundColor) { ctx.fillStyle = decalOpt.backgroundColor; ctx.fillRect(0, 0, canvas.width, canvas.height); } } var ySum = 0; for (var i2 = 0; i2 < dashArrayY.length; ++i2) { ySum += dashArrayY[i2]; } if (ySum <= 0) { return; } var y = -lineBlockLengthY; var yId = 0; var yIdTotal = 0; var xId0 = 0; while (y < pSize.height) { if (yId % 2 === 0) { var symbolYId = yIdTotal / 2 % symbolArray.length; var x = 0; var xId1 = 0; var xId1Total = 0; while (x < pSize.width * 2) { var xSum = 0; for (var i2 = 0; i2 < dashArrayX[xId0].length; ++i2) { xSum += dashArrayX[xId0][i2]; } if (xSum <= 0) { break; } if (xId1 % 2 === 0) { var size = (1 - decalOpt.symbolSize) * 0.5; var left = x + dashArrayX[xId0][xId1] * size; var top_1 = y + dashArrayY[yId] * size; var width = dashArrayX[xId0][xId1] * decalOpt.symbolSize; var height = dashArrayY[yId] * decalOpt.symbolSize; var symbolXId = xId1Total / 2 % symbolArray[symbolYId].length; brushSymbol(left, top_1, width, height, symbolArray[symbolYId][symbolXId]); } x += dashArrayX[xId0][xId1]; ++xId1Total; ++xId1; if (xId1 === dashArrayX[xId0].length) { xId1 = 0; } } ++xId0; if (xId0 === dashArrayX.length) { xId0 = 0; } } y += dashArrayY[yId]; ++yIdTotal; ++yId; if (yId === dashArrayY.length) { yId = 0; } } function brushSymbol(x2, y2, width2, height2, symbolType) { var scale = isSVG ? 1 : dpr; var symbol = createSymbol(symbolType, x2 * scale, y2 * scale, width2 * scale, height2 * scale, decalOpt.color, decalOpt.symbolKeepAspect); if (isSVG) { var symbolVNode = zr.painter.renderOneToVNode(symbol); if (symbolVNode) { svgRoot.children.push(symbolVNode); } } else { brushSingle(ctx, symbol); } } } } } function normalizeSymbolArray(symbol) { if (!symbol || symbol.length === 0) { return [["rect"]]; } if (isString(symbol)) { return [[symbol]]; } var isAllString = true; for (var i = 0; i < symbol.length; ++i) { if (!isString(symbol[i])) { isAllString = false; break; } } if (isAllString) { return normalizeSymbolArray([symbol]); } var result = []; for (var i = 0; i < symbol.length; ++i) { if (isString(symbol[i])) { result.push([symbol[i]]); } else { result.push(symbol[i]); } } return result; } function normalizeDashArrayX(dash) { if (!dash || dash.length === 0) { return [[0, 0]]; } if (isNumber(dash)) { var dashValue = Math.ceil(dash); return [[dashValue, dashValue]]; } var isAllNumber = true; for (var i = 0; i < dash.length; ++i) { if (!isNumber(dash[i])) { isAllNumber = false; break; } } if (isAllNumber) { return normalizeDashArrayX([dash]); } var result = []; for (var i = 0; i < dash.length; ++i) { if (isNumber(dash[i])) { var dashValue = Math.ceil(dash[i]); result.push([dashValue, dashValue]); } else { var dashValue = map(dash[i], function(n) { return Math.ceil(n); }); if (dashValue.length % 2 === 1) { result.push(dashValue.concat(dashValue)); } else { result.push(dashValue); } } } return result; } function normalizeDashArrayY(dash) { if (!dash || typeof dash === "object" && dash.length === 0) { return [0, 0]; } if (isNumber(dash)) { var dashValue_1 = Math.ceil(dash); return [dashValue_1, dashValue_1]; } var dashValue = map(dash, function(n) { return Math.ceil(n); }); return dash.length % 2 ? dashValue.concat(dashValue) : dashValue; } function getLineBlockLengthX(dash) { return map(dash, function(line) { return getLineBlockLengthY(line); }); } function getLineBlockLengthY(dash) { var blockLength = 0; for (var i = 0; i < dash.length; ++i) { blockLength += dash[i]; } if (dash.length % 2 === 1) { return blockLength * 2; } return blockLength; } export { createOrUpdatePatternFromDecal };