@antv/s2
Version:
effective spreadsheet render core lib
140 lines • 6 kB
JavaScript
import { NormalizedAlign } from '../normalize';
/**
* 动态调整滚动过程中列头的可视区域
*/
export const adjustTextIconPositionWhileScrolling = (viewportArea, contentArea, style, options) => {
const { isCustomRenderer = false } = options || {};
const { align, size, padding } = style;
const { textSize, iconStartSize = 0, iconEndSize = 0 } = size;
let { betweenTextAndEndIcon = 0 } = padding;
betweenTextAndEndIcon = iconEndSize ? betweenTextAndEndIcon : 0;
const totalSize = textSize + iconStartSize + iconEndSize;
const paddingArea = {
start: contentArea.start - padding.start,
size: contentArea.size + padding.start + padding.end,
};
const paddingAreaEnd = paddingArea.start + paddingArea.size;
const contentAreaEnd = contentArea.start + contentArea.size;
const viewportAreaEnd = viewportArea.start + viewportArea.size;
function getTextIconPosition(area) {
switch (align) {
case NormalizedAlign.Start:
return {
iconStart: area.start,
textStart: area.start + iconStartSize,
iconEnd: area.start + iconStartSize + textSize + betweenTextAndEndIcon,
};
case NormalizedAlign.Center:
const start = area.start + area.size / 2 - totalSize / 2;
return {
iconStart: start,
textStart: start + iconStartSize + (isCustomRenderer ? 0 : textSize / 2),
iconEnd: start + iconStartSize + textSize + betweenTextAndEndIcon,
};
default:
const areaEnd = area.start + area.size;
return {
iconStart: areaEnd - iconEndSize - textSize - iconStartSize,
textStart: areaEnd - iconEndSize - (isCustomRenderer ? textSize : 0),
iconEnd: areaEnd - iconEndSize + betweenTextAndEndIcon,
};
}
}
if (paddingArea.start >= viewportArea.start &&
paddingAreaEnd <= viewportAreaEnd) {
/**
* +----------------------------+
* | +-------------+ |
* | | text | icon | viewport |
* | +-------------+ |
* +----------------------------+
*/
return getTextIconPosition(contentArea);
}
if (paddingArea.start < viewportArea.start &&
paddingAreaEnd <= viewportAreaEnd) {
/**
* +-------------------+
* +------|------+ |
* | text | icon | viewport |
* +------|------+ |
* +-------------------+
*/
const area = {
start: viewportArea.start +
(align !== NormalizedAlign.End ? padding.start : 0),
size: contentArea.size -
(viewportArea.start - contentArea.start) -
(align !== NormalizedAlign.End ? padding.start : 0),
};
if (area.size < totalSize) {
area.size = totalSize;
area.start = contentAreaEnd - totalSize;
}
return getTextIconPosition(area);
}
if (paddingArea.start >= viewportArea.start &&
paddingAreaEnd > viewportAreaEnd) {
/**
* +-------------------+
* | +------|------+
* | viewport | text | icon |
* | +------|------+
* +-------------------+
*/
const area = {
start: contentArea.start,
size: contentArea.size -
(contentAreaEnd - viewportAreaEnd) -
(align !== NormalizedAlign.Start ? padding.end : 0),
};
if (area.size < totalSize) {
area.size = totalSize;
area.start = contentArea.start;
}
return getTextIconPosition(area);
}
/**
* +----------------------+
* | viewport |
* +--|----------------------|--+
* | | text | icon | |
* +--|----------------------|--+
* +----------------------+
*/
const area = {
start: viewportArea.start + padding.start,
size: viewportArea.size - padding.start - padding.end,
};
/**
* 这种情况下需要考虑文本内容超级长,超过了可视区域范围的情况,在这情况下,文字的对齐方式无论是啥都没有意义,为了使内容能随着滚动完全被显示出来(以向左滚动为例):
* 1. 将文字和 icon 在单元格内居中对齐,以对齐后的文字和 icon 内容的起始点做作为左边界,结束点作为右边界
* 2. 如果当前左边界还在可视范围内,则以内容左边界贴边显示
* 3. 如果左边界滚出可视范围,则内容以左边界为界限,文字也跟随一起滚动
* 4. 直到右边界进入可以范围内,则以内容右边界贴边显示
* +----------------------+
* | viewport |
* +--|----------------------|----------------------+
* | | super super super| super long text | |
* +--|---|------------------|-------------------|--+
* +---|------------------| |
* v v v
* start center end
*/
if (area.size < totalSize) {
const contentStart = contentArea.start + contentArea.size / 2 - totalSize / 2;
const contentEnd = contentStart + totalSize;
// eslint-disable-next-line no-empty
if (contentStart > area.start) {
}
else if (contentEnd > area.start + area.size) {
area.start = contentStart;
}
else {
area.start -= totalSize - area.size;
}
area.size = totalSize;
}
return getTextIconPosition(area);
};
//# sourceMappingURL=text-scrolling.js.map