@antv/f2
Version:
Charts for mobile visualization.
221 lines • 6.71 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import EE from '@antv/event-emitter';
import { createCanvas } from '@antv/f2-graphic';
import { deepMix, isFunction } from '@antv/util';
import Component from '../base/component';
import { destroyElement, renderChildren, renderComponent } from '../base/diff';
import equal from '../base/equal';
import Layout from '../base/layout';
import { createUpdater } from '../base/updater';
import defaultTheme from '../theme';
import { batch2hd, px2hd as defaultPx2hd } from '../util';
import Animation from './animation';
function measureText(canvas, px2hd) {
return function (text, font) {
var _ref = font || {},
fontSize = _ref.fontSize,
fontFamily = _ref.fontFamily,
fontStyle = _ref.fontStyle,
fontWeight = _ref.fontWeight,
fontVariant = _ref.fontVariant;
var shape = canvas.addShape('text', {
attrs: {
x: 0,
y: 0,
fontSize: px2hd(fontSize),
fontFamily: fontFamily,
fontStyle: fontStyle,
fontWeight: fontWeight,
fontVariant: fontVariant,
text: text
}
});
var _shape$getBBox = shape.getBBox(),
width = _shape$getBBox.width,
height = _shape$getBBox.height;
shape.remove(true);
return {
width: width,
height: height
};
};
}
// 顶层Canvas标签
var Canvas = /*#__PURE__*/function (_Component) {
_inherits(Canvas, _Component);
var _super = _createSuper(Canvas);
function Canvas(props) {
var _this;
_classCallCheck(this, Canvas);
_this = _super.call(this, props);
var context = props.context,
pixelRatio = props.pixelRatio,
width = props.width,
height = props.height,
_props$animate = props.animate,
animate = _props$animate === void 0 ? true : _props$animate,
customPx2hd = props.px2hd,
customTheme = props.theme,
customStyle = props.style,
createImage = props.createImage,
landscape = props.landscape;
var px2hd = isFunction(customPx2hd) ? batch2hd(customPx2hd) : defaultPx2hd;
var theme = px2hd(deepMix({}, defaultTheme, customTheme));
// 创建G的canvas
var canvas = createCanvas({
context: context,
pixelRatio: pixelRatio,
fontFamily: theme.fontFamily,
width: width,
height: height,
createImage: createImage,
landscape: landscape
});
// 组件更新器
var updater = createUpdater(_assertThisInitialized(_this));
// 供全局使用的一些变量
var componentContext = {
root: _assertThisInitialized(_this),
ctx: context,
canvas: canvas,
theme: theme,
px2hd: px2hd,
measureText: measureText(canvas, px2hd)
};
// 动画模块
var animation = new Animation(canvas);
canvas.on('afterdraw', function () {
var onAfterDraw = _this.props.onAfterDraw;
onAfterDraw && onAfterDraw();
});
_this.canvas = canvas;
_this.container = canvas;
_this.context = componentContext;
_this.updater = updater;
_this.animate = animate;
_this.animation = animation;
_this.theme = theme;
_this._ee = new EE();
_this.updateLayout(props);
return _this;
}
_createClass(Canvas, [{
key: "renderComponents",
value: function renderComponents(components) {
if (!components || !components.length) {
return;
}
renderComponent(components);
this.draw();
}
}, {
key: "update",
value: function update(nextProps) {
var props = this.props;
if (equal(nextProps, props)) {
return;
}
this.props = nextProps;
this.render();
}
}, {
key: "resize",
value: function resize(width, height) {
var _this$canvas$_attrs = this.canvas._attrs,
canvasWidth = _this$canvas$_attrs.width,
canvasHeight = _this$canvas$_attrs.height;
this.canvas.changeSize(width || canvasWidth, height || canvasHeight);
// this.canvas.clear();
// this.children = null;
this.updateLayout(_objectSpread(_objectSpread({}, this.props), {}, {
width: width,
height: height
}));
this.render();
}
}, {
key: "updateLayout",
value: function updateLayout(props) {
var _this$canvas$_attrs2 = this.canvas._attrs,
canvasWidth = _this$canvas$_attrs2.width,
canvasHeight = _this$canvas$_attrs2.height;
var style = this.context.px2hd(_objectSpread({
left: 0,
top: 0,
width: (props === null || props === void 0 ? void 0 : props.width) || canvasWidth,
height: (props === null || props === void 0 ? void 0 : props.height) || canvasHeight,
padding: this.theme.padding
}, props.style));
this.layout = Layout.fromStyle(style);
this.context = _objectSpread(_objectSpread({}, this.context), {}, {
left: this.layout.left,
top: this.layout.top,
width: this.layout.width,
height: this.layout.height
});
}
}, {
key: "draw",
value: function draw() {
var canvas = this.canvas,
animate = this.animate;
if (animate === false) {
canvas.draw();
return;
}
this.play();
}
}, {
key: "play",
value: function play() {
var _this2 = this;
var canvas = this.canvas,
animation = this.animation;
// 执行动画
animation.abort();
animation.play(canvas, function () {
_this2.emit('animationEnd');
});
}
}, {
key: "render",
value: function render() {
var lastChildren = this.children,
props = this.props;
var nextChildren = props.children;
renderChildren(this, nextChildren, lastChildren);
this.draw();
return null;
}
}, {
key: "destroy",
value: function destroy() {
var canvas = this.canvas,
children = this.children;
destroyElement(children);
canvas.destroy();
}
}, {
key: "on",
value: function on(type, listener) {
this._ee.on(type, listener);
}
}, {
key: "emit",
value: function emit(type, event) {
this._ee.emit(type, event);
}
}, {
key: "off",
value: function off(type, listener) {
this._ee.off(type, listener);
}
}]);
return Canvas;
}(Component);
export default Canvas;