Skip to content

Commit

Permalink
fix: 自定义px2hd。 Closed #1462 (#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed May 7, 2022
1 parent 46b5a4a commit 76f886a
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 59 deletions.
8 changes: 5 additions & 3 deletions packages/f2/src/base/diff.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { JSX } from '../jsx/jsx-namespace';
import { render, renderJSXElement, compareRenderTree } from '../jsx';
import { renderJSXElement, compareRenderTree } from '../jsx';
import { render } from '../jsx/render';
import { isArray, isUndefined, isBoolean, pick } from '@antv/util';
import Component from './component';
import equal from './equal';
Expand Down Expand Up @@ -29,6 +30,7 @@ function renderShape(component: Component, children: JSX.Element, animate?: bool
container.clear();

animate = isBoolean(animate) ? animate : componentAnimate;
const { px2hd } = context;
const lastElement = __lastElement || (transformFrom && transformFrom.__lastElement);

// children 是 shape 的 jsx 结构, component.render() 返回的结构
Expand All @@ -41,10 +43,10 @@ function renderShape(component: Component, children: JSX.Element, animate?: bool
// 生成G的节点树, 存在数组的情况是根节点有变化,之前的树删除,新的树创建
if (isArray(renderElement)) {
return renderElement.map((element) => {
return render(element, container, animate);
return render(element, container, animate, px2hd);
});
} else {
return render(renderElement, container, animate);
return render(renderElement, container, animate, px2hd);
}
}

Expand Down
7 changes: 4 additions & 3 deletions packages/f2/src/canvas/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createCanvas, Canvas as GCanvas } from '@antv/f2-graphic';
import { deepMix } from '@antv/util';
import { deepMix, isFunction } from '@antv/util';
import Component from '../base/component';
import Layout from '../base/layout';
import equal from '../base/equal';
import Animation from './animation';
import { px2hd as defaultPx2hd } from '../util';
import { px2hd as defaultPx2hd, batch2hd } from '../util';
import { createUpdater } from '../base/updater';
import defaultTheme from '../theme';
import { renderChildren, renderComponent } from '../base/diff';
Expand Down Expand Up @@ -65,11 +65,12 @@ class Canvas extends Component<ChartProps> {
width,
height,
animate = true,
px2hd = defaultPx2hd,
px2hd: customPx2hd,
theme: customTheme,
style: customStyle,
} = props;

const px2hd = isFunction(customPx2hd) ? batch2hd(customPx2hd) : defaultPx2hd;
const theme = px2hd(deepMix({}, defaultTheme, customTheme));

// 创建G的canvas
Expand Down
16 changes: 11 additions & 5 deletions packages/f2/src/jsx/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { JSX } from './jsx-namespace';
import { extendMap, px2hd } from '../util';
import { extendMap, px2hd as defaultPx2hd } from '../util';
import { omit } from '@antv/util';
import computeLayout from './css-layout';
import getShapeAttrs from './shape';
Expand All @@ -8,10 +8,10 @@ import { ELEMENT_DELETE } from './elementStatus';
import createClipElement from './createClipElement';

// 转换成布局所需要的布局树
function createNodeTree(element, container) {
function createNodeTree(element, container, px2hd) {
const { key, ref, _cache, type, props, status, animation } = element;
const children = extendMap(props.children, (child) => {
return createNodeTree(child, container);
return createNodeTree(child, container, px2hd);
});

// const { style, attrs } = props;
Expand Down Expand Up @@ -149,12 +149,18 @@ function filterDeleteElement(node) {
return node;
}

export default (element: JSX.Element, container, animate?: boolean) => {
function render(element: JSX.Element, container, animate?: boolean, px2hd = defaultPx2hd) {
if (!element) {
return;
}
const nodeTree = createNodeTree(element, container);
const nodeTree = createNodeTree(element, container, px2hd);
const computeLayoutTree = filterDeleteElement(nodeTree);
computeLayout(computeLayoutTree);
return createElement(nodeTree, container, null, animate);
}

export { render };

export default (element: JSX.Element, container, animate?: boolean) => {
return render(element, container, animate);
};
87 changes: 39 additions & 48 deletions packages/f2/src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
isDate,
isPlainObject,
isNumber,
isString,
isArray,
} from '@antv/util';
import { isDate, isPlainObject, isNumber, isString, isArray } from '@antv/util';

// 默认设置50
let ONE_REM: number;
Expand All @@ -21,7 +15,7 @@ const SCALE = ONE_REM / 100;
* @param {Number} px - 750视觉稿像素
* @return {Number} 屏幕上实际像素
*/
function px2hd(px: number): number {
function defaultPx2hd(px: number): number {
if (!px) {
return 0;
}
Expand All @@ -41,42 +35,45 @@ function parsePadding(padding: number | number[]) {

type pxstr = `${number}px`;

function batch2hd(value: pxstr | pxstr[] | number | number[] | string | string[] | any) {
// 处理带px的数据
if (isString(value) && /^-?\d+px$/.test(value)) {
const num = value.substr(0, value.length - 2);
return px2hd(Number(num));
}
if (isArray(value)) {
return value.map((v) => {
return batch2hd(v);
});
}
if (isPlainObject(value)) {
const result = {};
for (const key in value) {
if (value.hasOwnProperty(key)) {
const rst = batch2hd(value[key]);
if (!rst) {
function batch2hd(px2hd) {
const batchPx2hd = (value: pxstr | pxstr[] | number | number[] | string | string[] | any) => {
// 处理带px的数据
if (isString(value) && /^-?\d+px$/.test(value)) {
const num = value.substr(0, value.length - 2);
return px2hd(Number(num));
}
if (isArray(value)) {
return value.map((v) => {
return batchPx2hd(v);
});
}
if (isPlainObject(value)) {
const result = {};
for (const key in value) {
if (value.hasOwnProperty(key)) {
const rst = batchPx2hd(value[key]);
if (!rst) {
result[key] = rst;
continue;
}
if (key === 'padding' || key === 'margin') {
const paddingArray = parsePadding(rst);
result[key] = paddingArray;
result[`${key}Top`] = paddingArray[0];
result[`${key}Right`] = paddingArray[1];
result[`${key}Bottom`] = paddingArray[2];
result[`${key}Left`] = paddingArray[3];
continue;
}
result[key] = rst;
continue;
}
if (key === 'padding' || key === 'margin') {
const paddingArray = parsePadding(rst);
result[key] = paddingArray;
result[`${key}Top`] = paddingArray[0];
result[`${key}Right`] = paddingArray[1];
result[`${key}Bottom`] = paddingArray[2];
result[`${key}Left`] = paddingArray[3];
continue;
}
result[key] = rst;
}
return result;
}
return result;
// 默认直接返回
return value;
}
// 默认直接返回
return value;
return batchPx2hd;
}

// 展开数组
Expand Down Expand Up @@ -138,12 +135,6 @@ function getElementsByClassName(className: string, element) {
return rst;
}

export {
// px2hd 含义更清晰
batch2hd as px2hd,
extendMap,
parsePadding,
toTimeStamp,
isInBBox,
getElementsByClassName,
};
const px2hd = batch2hd(defaultPx2hd);

export { px2hd, batch2hd, extendMap, parsePadding, toTimeStamp, isInBBox, getElementsByClassName };
53 changes: 53 additions & 0 deletions packages/f2/test/components/canvas/px2hd.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { jsx } from '../../../src/jsx';
import { createContext } from '../../util';
import { Canvas, Component } from '../../../src';
const context = createContext('', {
width: '300px',
height: '300px',
});

class Test extends Component {
render() {
return (
<rect
attrs={{
x: '20px',
y: '20px',
width: '20px',
height: '20px',
fill: 'red',
}}
/>
);
}
}

describe('Canvas', () => {
it('自定义 px2hd', () => {
const { props } = (
<Canvas
context={context}
pixelRatio={1}
px2hd={(v) => {
return parseFloat(v);
}}
>
<Test />
</Canvas>
);

const canvas = new Canvas(props);
const testComponent = canvas.props.children.type;

expect(context.canvas.width).toBe(300);
expect(context.canvas.height).toBe(300);

expect(testComponent).toBe(Test);

canvas.render();

const rect = canvas.children.component.container._attrs.children[0];
expect(rect._attrs.type).toBe('rect');
expect(rect._attrs.attrs.fill).toBe('red');
});
});

0 comments on commit 76f886a

Please sign in to comment.