| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.addWaterWave = void 0;
- var tslib_1 = require("tslib");
- var g2_1 = require("@antv/g2");
- var util_1 = require("@antv/util");
- var matrix_1 = require("../../../utils/matrix");
- var DURATION = 5000;
- /**
- * 一个线性映射的函数
- * @param min
- * @param max
- * @param factor
- */
- function lerp(min, max, factor) {
- return min + (max - min) * factor;
- }
- /**
- * 波浪的 attrs
- * @param cfg
- */
- function getFillAttrs(cfg) {
- var attrs = tslib_1.__assign({ opacity: 1 }, cfg.style);
- if (cfg.color && !attrs.fill) {
- attrs.fill = cfg.color;
- }
- return attrs;
- }
- /**
- * shape 的 attrs
- * @param cfg
- */
- function getLineAttrs(cfg) {
- var defaultAttrs = {
- fill: '#fff',
- fillOpacity: 0,
- lineWidth: 4,
- };
- var attrs = (0, util_1.mix)({}, defaultAttrs, cfg.style);
- if (cfg.color && !attrs.stroke) {
- attrs.stroke = cfg.color;
- }
- if ((0, util_1.isNumber)(cfg.opacity)) {
- attrs.opacity = attrs.strokeOpacity = cfg.opacity;
- }
- return attrs;
- }
- /**
- * 用贝塞尔曲线模拟正弦波
- * Using Bezier curves to fit sine wave.
- * There is 4 control points for each curve of wave,
- * which is at 1/4 wave length of the sine wave.
- *
- * The control points for a wave from (a) to (d) are a-b-c-d:
- * c *----* d
- * b *
- * |
- * ... a * ..................
- *
- * whose positions are a: (0, 0), b: (0.5, 0.5), c: (1, 1), d: (PI / 2, 1)
- *
- * @param x x position of the left-most point (a)
- * @param stage 0-3, stating which part of the wave it is
- * @param waveLength wave length of the sine wave
- * @param amplitude wave amplitude
- * @return 正弦片段曲线
- */
- function getWaterWavePositions(x, stage, waveLength, amplitude) {
- if (stage === 0) {
- return [
- [x + ((1 / 2) * waveLength) / Math.PI / 2, amplitude / 2],
- [x + ((1 / 2) * waveLength) / Math.PI, amplitude],
- [x + waveLength / 4, amplitude],
- ];
- }
- if (stage === 1) {
- return [
- [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 2), amplitude],
- [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 1), amplitude / 2],
- [x + waveLength / 4, 0],
- ];
- }
- if (stage === 2) {
- return [
- [x + ((1 / 2) * waveLength) / Math.PI / 2, -amplitude / 2],
- [x + ((1 / 2) * waveLength) / Math.PI, -amplitude],
- [x + waveLength / 4, -amplitude],
- ];
- }
- return [
- [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 2), -amplitude],
- [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 1), -amplitude / 2],
- [x + waveLength / 4, 0],
- ];
- }
- /**
- * 获取水波路径
- * @param radius 半径
- * @param waterLevel 水位
- * @param waveLength 波长
- * @param phase 相位
- * @param amplitude 震幅
- * @param cx 圆心x
- * @param cy 圆心y
- * @return path 路径
- * @reference http://gitlab.alipay-inc.com/datavis/g6/blob/1.2.0/src/graph/utils/path.js#L135
- */
- function getWaterWavePath(radius, waterLevel, waveLength, phase, amplitude, cx, cy) {
- var curves = Math.ceil(((2 * radius) / waveLength) * 4) * 4;
- var path = [];
- var _phase = phase;
- // map phase to [-Math.PI * 2, 0]
- while (_phase < -Math.PI * 2) {
- _phase += Math.PI * 2;
- }
- while (_phase > 0) {
- _phase -= Math.PI * 2;
- }
- _phase = (_phase / Math.PI / 2) * waveLength;
- var left = cx - radius + _phase - radius * 2;
- /**
- * top-left corner as start point
- *
- * draws this point
- * |
- * \|/
- * ~~~~~~~~
- * | |
- * +------+
- */
- path.push(['M', left, waterLevel]);
- /**
- * top wave
- *
- * ~~~~~~~~ <- draws this sine wave
- * | |
- * +------+
- */
- var waveRight = 0;
- for (var c = 0; c < curves; ++c) {
- var stage = c % 4;
- var pos = getWaterWavePositions((c * waveLength) / 4, stage, waveLength, amplitude);
- path.push([
- 'C',
- pos[0][0] + left,
- -pos[0][1] + waterLevel,
- pos[1][0] + left,
- -pos[1][1] + waterLevel,
- pos[2][0] + left,
- -pos[2][1] + waterLevel,
- ]);
- if (c === curves - 1) {
- waveRight = pos[2][0];
- }
- }
- /**
- * top-right corner
- *
- * ~~~~~~~~
- * 3. draws this line -> | | <- 1. draws this line
- * +------+
- * ^
- * |
- * 2. draws this line
- */
- path.push(['L', waveRight + left, cy + radius]);
- path.push(['L', left, cy + radius]);
- path.push(['Z']);
- // path.push(['L', left, waterLevel]);
- return path;
- }
- /**
- * 添加水波
- * @param x 中心x
- * @param y 中心y
- * @param level 水位等级 0~1
- * @param waveCount 水波数
- * @param waveAttrs 色值
- * @param group 图组
- * @param clip 用于剪切的图形
- * @param radius 绘制图形的高度
- * @param waveLength 波的长度
- */
- function addWaterWave(x, y, level, waveCount, waveAttrs, group, clip, radius, waveLength, animation) {
- // 盒子属性 颜色 宽高
- var fill = waveAttrs.fill, opacity = waveAttrs.opacity;
- var bbox = clip.getBBox();
- var width = bbox.maxX - bbox.minX;
- var height = bbox.maxY - bbox.minY;
- // 循环 waveCount 个数
- for (var idx = 0; idx < waveCount; idx++) {
- var factor = waveCount <= 1 ? 1 : idx / (waveCount - 1);
- // 画波
- var wave = group.addShape('path', {
- name: "waterwave-path",
- attrs: {
- // 波形路径配置
- path: getWaterWavePath(radius, bbox.minY + height * level, waveLength, 0, width / 32, // 波幅高度
- x, y),
- fill: fill,
- opacity: lerp(0.2, 0.9, factor) * opacity,
- },
- });
- try {
- // 默认 underfind 开启动画
- if (animation === false)
- return;
- var matrix = (0, matrix_1.transform)([['t', waveLength, 0]]);
- wave.stopAnimate();
- wave.animate({ matrix: matrix }, {
- duration: lerp(0.5 * DURATION, DURATION, factor),
- repeat: true,
- });
- }
- catch (e) {
- // TODO off-screen canvas 中动画会找不到 canvas
- console.warn('off-screen group animate error!');
- }
- }
- }
- exports.addWaterWave = addWaterWave;
- /**
- *
- * @param x 中心 x
- * @param y 中心 y
- * @param width 外接矩形的宽
- * @param height 外接矩形的高
- */
- function pin(x, y, width, height) {
- var w = (width * 2) / 3;
- var h = Math.max(w, height);
- var r = w / 2;
- // attrs of the upper circle
- var cx = x;
- var cy = r + y - h / 2;
- var theta = Math.asin(r / ((h - r) * 0.85));
- var dy = Math.sin(theta) * r;
- var dx = Math.cos(theta) * r;
- // the start point of the path
- var x0 = cx - dx;
- var y0 = cy + dy;
- // control point
- var cpX = x;
- var cpY = cy + r / Math.sin(theta);
- return "\n M ".concat(x0, " ").concat(y0, "\n A ").concat(r, " ").concat(r, " 0 1 1 ").concat(x0 + dx * 2, " ").concat(y0, "\n Q ").concat(cpX, " ").concat(cpY, " ").concat(x, " ").concat(y + h / 2, "\n Q ").concat(cpX, " ").concat(cpY, " ").concat(x0, " ").concat(y0, "\n Z \n ");
- }
- /**
- *
- * @param x 中心 x
- * @param y 中心 y
- * @param width 外接矩形的宽
- * @param height 外接矩形的高
- */
- function circle(x, y, width, height) {
- var rx = width / 2;
- var ry = height / 2;
- return "\n M ".concat(x, " ").concat(y - ry, " \n a ").concat(rx, " ").concat(ry, " 0 1 0 0 ").concat(ry * 2, "\n a ").concat(rx, " ").concat(ry, " 0 1 0 0 ").concat(-ry * 2, "\n Z\n ");
- }
- /**
- *
- * @param x 中心 x
- * @param y 中心 y
- * @param width 外接矩形的宽
- * @param height 外接矩形的高
- */
- function diamond(x, y, width, height) {
- var h = height / 2;
- var w = width / 2;
- return "\n M ".concat(x, " ").concat(y - h, "\n L ").concat(x + w, " ").concat(y, "\n L ").concat(x, " ").concat(y + h, "\n L ").concat(x - w, " ").concat(y, "\n Z\n ");
- }
- /**
- *
- * @param x 中心 x
- * @param y 中心 y
- * @param width 外接矩形的宽
- * @param height 外接矩形的高
- */
- function triangle(x, y, width, height) {
- var h = height / 2;
- var w = width / 2;
- return "\n M ".concat(x, " ").concat(y - h, "\n L ").concat(x + w, " ").concat(y + h, "\n L ").concat(x - w, " ").concat(y + h, "\n Z\n ");
- }
- /**
- *
- * @param x 中心 x
- * @param y 中心 y
- * @param width 外接矩形的宽
- * @param height 外接矩形的高
- */
- function rect(x, y, width, height) {
- var GOLDEN_SECTION_RATIO = 0.618;
- var h = height / 2;
- var w = (width / 2) * GOLDEN_SECTION_RATIO;
- return "\n M ".concat(x - w, " ").concat(y - h, "\n L ").concat(x + w, " ").concat(y - h, "\n L ").concat(x + w, " ").concat(y + h, "\n L ").concat(x - w, " ").concat(y + h, "\n Z\n ");
- }
- var builtInShapeByName = {
- pin: pin,
- circle: circle,
- diamond: diamond,
- triangle: triangle,
- rect: rect,
- };
- (0, g2_1.registerShape)('interval', 'liquid-fill-gauge', {
- draw: function (cfg, container) {
- var cx = 0.5;
- var cy = 0.5;
- var customInfo = cfg.customInfo;
- var _a = customInfo, percent = _a.percent, radio = _a.radius, shape = _a.shape, shapeStyle = _a.shapeStyle, background = _a.background, animation = _a.animation;
- var outline = customInfo.outline;
- var wave = customInfo.wave;
- var border = outline.border, distance = outline.distance;
- var waveCount = wave.count, waveLength = wave.length;
- // 获取最小 minX
- var minX = (0, util_1.reduce)(cfg.points, function (r, p) {
- return Math.min(r, p.x);
- }, Infinity);
- var center = this.parsePoint({ x: cx, y: cy });
- var minXPoint = this.parsePoint({ x: minX, y: cy });
- var halfWidth = center.x - minXPoint.x;
- // 保证半径是 画布宽高最小值的 radius 值
- var radius = Math.min(halfWidth, minXPoint.y * radio);
- var waveAttrs = getFillAttrs(cfg);
- var outlineAttrs = getLineAttrs((0, util_1.mix)({}, cfg, outline));
- var innerRadius = radius - border / 2;
- var buildPath = typeof shape === 'function' ? shape : builtInShapeByName[shape] || builtInShapeByName['circle'];
- var shapePath = buildPath(center.x, center.y, innerRadius * 2, innerRadius * 2);
- // 1. 当 shapeStyle 不为空时,绘制形状样式作为背景
- if (shapeStyle) {
- container.addShape('path', {
- name: 'shape',
- attrs: tslib_1.__assign({ path: shapePath }, shapeStyle),
- });
- }
- // 比例大于 0 时才绘制水波
- if (percent > 0) {
- // 2. 绘制一个波
- var waves = container.addGroup({
- name: 'waves',
- });
- // 3. 波对应的 clip 裁剪形状
- var clipPath = waves.setClip({
- type: 'path',
- attrs: {
- path: shapePath,
- },
- });
- // 4. 绘制波形
- addWaterWave(center.x, center.y, 1 - cfg.points[1].y, waveCount, waveAttrs, waves, clipPath, radius * 2, waveLength, animation);
- }
- // 5. 绘制一个 distance 宽的 border
- container.addShape('path', {
- name: 'distance',
- attrs: {
- path: shapePath,
- fill: 'transparent',
- lineWidth: border + distance * 2,
- stroke: background === 'transparent' ? '#fff' : background,
- },
- });
- // 6. 绘制一个 border 宽的 border
- container.addShape('path', {
- name: 'wrap',
- attrs: (0, util_1.mix)(outlineAttrs, {
- path: shapePath,
- fill: 'transparent',
- lineWidth: border,
- }),
- });
- return container;
- },
- });
- //# sourceMappingURL=liquid.js.map
|