Merge pull request #362 from wbkd/background-performance

Background performance
This commit is contained in:
Moritz
2020-07-26 17:08:52 +02:00
committed by GitHub
5 changed files with 26 additions and 51 deletions
-3
View File
@@ -13,9 +13,6 @@ describe('Basic Flow Rendering', () => {
it('renders a grid', () => {
cy.get('.react-flow__background');
const gridStroke = Cypress.$('.react-flow__background path').attr('stroke');
expect(gridStroke).to.equal('#eee');
});
it('selects a node by click', () => {
+1 -1
View File
@@ -136,7 +136,7 @@ const OverviewFlow = () => {
}}
/>
<Controls />
<Background color="#888" gap={16} />
<Background color="#aaa" gap={16} />
</ReactFlow>
);
};
+19 -13
View File
@@ -1,4 +1,4 @@
import React, { memo, HTMLAttributes } from 'react';
import React, { memo, useMemo, HTMLAttributes } from 'react';
import cc from 'classcat';
import { useStoreState } from '../../store/hooks';
@@ -21,26 +21,32 @@ const defaultColors = {
const Background = memo(
({ variant = BackgroundVariant.Dots, gap = 24, size = 0.5, color, style, className }: BackgroundProps) => {
const width = useStoreState((s) => s.width);
const height = useStoreState((s) => s.height);
const [x, y, scale] = useStoreState((s) => s.transform);
const bgClasses = cc(['react-flow__background', className]);
const bgColor = color ? color : defaultColors[variant];
const scaledGap = gap * scale;
const xOffset = x % scaledGap;
const yOffset = y % scaledGap;
const isLines = variant === BackgroundVariant.Lines;
const path = isLines
? createGridLinesPath(width, height, xOffset, yOffset, scaledGap)
: createGridDotsPath(width, height, xOffset, yOffset, scaledGap, size);
const fill = isLines ? 'none' : bgColor;
const stroke = isLines ? bgColor : 'none';
const bgSvgTile = useMemo(() => {
const isLines = variant === BackgroundVariant.Lines;
const bgColor = color ? color : defaultColors[variant];
const path = isLines ? createGridLinesPath(scaledGap, size, bgColor) : createGridDotsPath(size, bgColor);
return encodeURIComponent(
`<svg width="${scaledGap}" height="${scaledGap}" xmlns='http://www.w3.org/2000/svg'>${path}</svg>`
);
}, [variant, scaledGap, size, color]);
return (
<svg width={width} height={height} style={style} className={bgClasses}>
<path fill={fill} stroke={stroke} strokeWidth={size} d={path} />
</svg>
<div
className={bgClasses}
style={{
...style,
backgroundImage: `url("data:image/svg+xml;utf8,${bgSvgTile}")`,
backgroundPosition: `${xOffset}px ${yOffset}px`,
}}
></div>
);
}
);
@@ -2,4 +2,6 @@
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
+4 -34
View File
@@ -1,37 +1,7 @@
export const createGridLinesPath = (
width: number,
height: number,
xOffset: number,
yOffset: number,
gap: number
): string => {
const lineCountX = Math.ceil(width / gap) + 1;
const lineCountY = Math.ceil(height / gap) + 1;
const xValues = Array.from({ length: lineCountX }, (_, i) => `M${i * gap + xOffset} 0 V${height}`);
const yValues = Array.from({ length: lineCountY }, (_, i) => `M0 ${i * gap + yOffset} H${width}`);
return [...xValues, ...yValues].join(' ');
export const createGridLinesPath = (scaledGap: number, strokeWidth: number, stroke: string): string => {
return `<path stroke="${stroke}" strokeWidth="${strokeWidth}" d="M0 0 V${scaledGap} M0 0 H${scaledGap}" />`;
};
export const createGridDotsPath = (
width: number,
height: number,
xOffset: number,
yOffset: number,
gap: number,
size: number
): string => {
const lineCountX = Math.ceil(width / gap) + 1;
const lineCountY = Math.ceil(height / gap) + 1;
const values = Array.from({ length: lineCountX }, (_, col) => {
const x = col * gap + xOffset;
return Array.from({ length: lineCountY }, (_, row) => {
const y = row * gap + yOffset;
return `M${x} ${y - size} l${size} ${size} l${-size} ${size} l${-size} ${-size}z`;
}).join(' ');
});
return values.join(' ');
export const createGridDotsPath = (size: number, fill: string): string => {
return `<circle cx="${size}" cy="${size}" r="${size}" fill="${fill}" />`;
};