UNPKG

regl-shape

Version:
155 lines (154 loc) 7.28 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JoinStyle = void 0; const array_bounds_1 = __importDefault(require("array-bounds")); const array_normalize_1 = __importDefault(require("array-normalize")); const color_normalize_1 = __importDefault(require("color-normalize")); const earcut_1 = __importDefault(require("earcut")); const shaders_1 = require("./shaders"); const update_dash_texture_1 = require("./update-dash-texture"); const update_color_buffer_1 = require("./update-color-buffer"); var JoinStyle; (function (JoinStyle) { JoinStyle["Bevel"] = "bevel"; JoinStyle["Round"] = "round"; JoinStyle["Rect"] = "rect"; })(JoinStyle = exports.JoinStyle || (exports.JoinStyle = {})); function default_1(regl) { const shaders = shaders_1.createShaders(regl); let shapeCount = 0; return { createShape(points, initialPartialProps) { const id = shapeCount; shapeCount++; const normPoints = new Float64Array(points.length); const pointsData = new Float64Array(points.length + 6); const pointsDataFloat32 = new Float32Array(pointsData.length); const pointsDataFloat32Fract = new Float32Array(pointsData.length); const colorData = new Uint8Array(2 * points.length + 4); const colorBuffer = regl.buffer({ usage: "dynamic", type: "uint8", data: colorData, }); const positionBuffer = regl.buffer({ usage: "dynamic", type: "float", data: pointsDataFloat32, }); const positionFractBuffer = regl.buffer({ usage: "dynamic", type: "float", data: pointsDataFloat32Fract, }); const dashTexture = regl.texture({ channels: 1, data: new Uint8Array([255]), width: 1, height: 1, mag: "linear", min: "linear", }); return (partialProps) => { const props = Object.assign(Object.assign({ count: Math.floor(points.length / 2), color: "white", fill: null, thickness: 1, dashes: null, join: JoinStyle.Bevel, miterLimit: 1, close: false, opacity: 1, overlay: false, range: [-1, -1, 1, 1], viewport: { x: 0, y: 0, width: regl._gl.drawingBufferWidth, height: regl._gl.drawingBufferHeight, }, depth: -0.01 * id }, initialPartialProps), partialProps); let { count, color, close, join, range, dashes, fill } = props; // update position buffers const flatCount = 2 * count; const bounds = array_bounds_1.default(points.length > flatCount ? points.slice(0, flatCount) : points, 2); normPoints.set(points); array_normalize_1.default(normPoints, 2, bounds); const startIsEnd = points[0] === points[flatCount - 2] && points[1] === points[flatCount - 1]; // rotate first segment join if (close) { if (startIsEnd) { pointsData[0] = normPoints[flatCount - 4]; pointsData[1] = normPoints[flatCount - 3]; } else { pointsData[0] = normPoints[flatCount - 2]; pointsData[1] = normPoints[flatCount - 1]; } } else { pointsData[0] = normPoints[0]; pointsData[1] = normPoints[1]; } pointsData.set(normPoints, 2); // add last segment if (close) { // ignore coinciding start/end if (startIsEnd) { pointsData[flatCount + 2] = normPoints[2]; pointsData[flatCount + 3] = normPoints[3]; count--; } else { pointsData[flatCount + 2] = normPoints[0]; pointsData[flatCount + 3] = normPoints[1]; pointsData[flatCount + 4] = normPoints[2]; pointsData[flatCount + 5] = normPoints[3]; } } // add stub else { pointsData[flatCount + 2] = normPoints[flatCount - 2]; pointsData[flatCount + 3] = normPoints[flatCount - 1]; pointsData[flatCount + 4] = normPoints[flatCount - 2]; pointsData[flatCount + 5] = normPoints[flatCount - 1]; } pointsDataFloat32.set(pointsData); for (let i = 0; i < flatCount; i++) pointsDataFloat32Fract[i] = pointsData[i] - pointsDataFloat32[i]; positionBuffer.subdata(pointsDataFloat32); positionFractBuffer.subdata(pointsDataFloat32Fract); const boundsW = bounds[2] - bounds[0]; const boundsH = bounds[3] - bounds[1]; const rangeW = range[2] - range[0]; const rangeH = range[3] - range[1]; const scale = [boundsW / rangeW, boundsH / rangeH]; const translate = [ -range[0] / rangeW + bounds[0] / rangeW || 0, -range[1] / rangeH + bounds[1] / rangeH || 0, ]; const scale32 = new Float32Array(scale); const scaleFract = [scale[0] - scale32[0], scale[1] - scale32[1]]; const translate32 = new Float32Array(translate); const translateFract = [ translate[0] - translate32[0], translate[1] - translate32[1], ]; const dashLength = dashes ? update_dash_texture_1.updateDashTextureAndGetLength(dashTexture, dashes) : 1; if (color) update_color_buffer_1.updateColorBuffer(colorBuffer, colorData, color, count); const renderProps = Object.assign(Object.assign({}, props), { translate, translateFract, scale, scaleFract, colorBuffer, positionBuffer, positionFractBuffer, dashLength, dashTexture, triangles: fill ? earcut_1.default(points) : null, fillColor: fill ? color_normalize_1.default(fill, "uint8") : null }); regl._refresh(); if (fill) shaders.fill(renderProps); if (join === JoinStyle.Rect) shaders.rect(renderProps); else shaders.miter(renderProps); }; }, }; } exports.default = default_1;