tweak-tools
Version:
Tweak your React projects until awesomeness
124 lines (123 loc) • 5.74 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Monitor = void 0;
const react_1 = __importStar(require("react"));
const colord_1 = require("colord");
const StyledMonitor_1 = require("./StyledMonitor");
const UI_1 = require("../UI");
const utils_1 = require("../../utils");
const hooks_1 = require("../../hooks");
const styles_1 = require("../../styles");
const POINTS = 100;
function push(arr, val) {
arr.push(val);
if (arr.length > POINTS)
arr.shift();
}
const MonitorCanvas = (0, react_1.forwardRef)(function ({ initialValue }, ref) {
const accentColor = (0, styles_1.useTh)('colors', 'highlight3');
const backgroundColor = (0, styles_1.useTh)('colors', 'elevation2');
const fillColor = (0, styles_1.useTh)('colors', 'highlight1');
const [gradientTop, gradientBottom] = (0, react_1.useMemo)(() => {
return [(0, colord_1.colord)(fillColor).alpha(0.4).toRgbString(), (0, colord_1.colord)(fillColor).alpha(0.1).toRgbString()];
}, [fillColor]);
const points = (0, react_1.useRef)([initialValue]);
const min = (0, react_1.useRef)(initialValue);
const max = (0, react_1.useRef)(initialValue);
const raf = (0, react_1.useRef)();
const drawPlot = (0, react_1.useCallback)((_canvas, _ctx) => {
// fixes unmount potential bug
if (!_canvas)
return;
const { width, height } = _canvas;
// compute the path
const path = new Path2D();
const interval = width / POINTS;
const verticalPadding = height * 0.05;
for (let i = 0; i < points.current.length; i++) {
const p = (0, utils_1.range)(points.current[i], min.current, max.current);
const x = interval * i;
const y = height - p * (height - verticalPadding * 2) - verticalPadding;
path.lineTo(x, y);
}
// clear
_ctx.clearRect(0, 0, width, height);
// draw gradient
const gradientPath = new Path2D(path);
gradientPath.lineTo(interval * (points.current.length + 1), height);
gradientPath.lineTo(0, height);
gradientPath.lineTo(0, 0);
const gradient = _ctx.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0.0, gradientTop);
gradient.addColorStop(1.0, gradientBottom);
_ctx.fillStyle = gradient;
_ctx.fill(gradientPath);
// draw the dark line
_ctx.strokeStyle = backgroundColor;
_ctx.lineJoin = 'round';
_ctx.lineWidth = 14;
_ctx.stroke(path);
// draw the white line
_ctx.strokeStyle = accentColor;
_ctx.lineWidth = 2;
_ctx.stroke(path);
}, [accentColor, backgroundColor, gradientTop, gradientBottom]);
const [canvas, ctx] = (0, hooks_1.useCanvas2d)(drawPlot);
(0, react_1.useImperativeHandle)(ref, () => ({
frame: (val) => {
if (min.current === undefined || val < min.current)
min.current = val;
if (max.current === undefined || val > max.current)
max.current = val;
push(points.current, val);
raf.current = requestAnimationFrame(() => drawPlot(canvas.current, ctx.current));
},
}), [canvas, ctx, drawPlot]);
(0, react_1.useEffect)(() => () => cancelAnimationFrame(raf.current), []);
return react_1.default.createElement(StyledMonitor_1.Canvas, { ref: canvas });
});
const parse = (val) => (Number.isFinite(val) ? val.toPrecision(2) : val.toString());
const MonitorLog = (0, react_1.forwardRef)(function ({ initialValue }, ref) {
const [val, set] = (0, react_1.useState)(parse(initialValue));
(0, react_1.useImperativeHandle)(ref, () => ({ frame: (v) => set(parse(v)) }), []);
return react_1.default.createElement("div", null, val);
});
function getValue(o) {
return typeof o === 'function' ? o() : o.current;
}
function Monitor({ label, objectOrFn, settings }) {
const ref = (0, react_1.useRef)();
const initialValue = (0, react_1.useRef)(getValue(objectOrFn));
(0, react_1.useEffect)(() => {
const timeout = window.setInterval(() => {
var _a;
if (document.hidden)
return; // prevent drawing when document is hidden
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.frame(getValue(objectOrFn));
}, settings.interval);
return () => window.clearInterval(timeout);
}, [objectOrFn, settings.interval]);
return (react_1.default.createElement(UI_1.Row, { input: true },
react_1.default.createElement(UI_1.Label, { align: "top" }, label),
settings.graph ? (react_1.default.createElement(MonitorCanvas, { ref: ref, initialValue: initialValue.current })) : (react_1.default.createElement(MonitorLog, { ref: ref, initialValue: initialValue.current }))));
}
exports.Monitor = Monitor;