in src/component/timeline/SliderTimelineView.ts [168:266]
private _layout(timelineModel: SliderTimelineModel, api: ExtensionAPI): LayoutInfo {
const labelPosOpt = timelineModel.get(['label', 'position']);
const orient = timelineModel.get('orient');
const viewRect = getViewRect(timelineModel, api);
let parsedLabelPos: number | '+' | '-';
// Auto label offset.
if (labelPosOpt == null || labelPosOpt === 'auto') {
parsedLabelPos = orient === 'horizontal'
? ((viewRect.y + viewRect.height / 2) < api.getHeight() / 2 ? '-' : '+')
: ((viewRect.x + viewRect.width / 2) < api.getWidth() / 2 ? '+' : '-');
}
else if (isString(labelPosOpt)) {
parsedLabelPos = ({
horizontal: {top: '-', bottom: '+'},
vertical: {left: '-', right: '+'}
} as const)[orient][labelPosOpt];
}
else {
// is number
parsedLabelPos = labelPosOpt;
}
const labelAlignMap = {
horizontal: 'center',
vertical: (parsedLabelPos >= 0 || parsedLabelPos === '+') ? 'left' : 'right'
};
const labelBaselineMap = {
horizontal: (parsedLabelPos >= 0 || parsedLabelPos === '+') ? 'top' : 'bottom',
vertical: 'middle'
};
const rotationMap = {
horizontal: 0,
vertical: PI / 2
};
// Position
const mainLength = orient === 'vertical' ? viewRect.height : viewRect.width;
const controlModel = timelineModel.getModel('controlStyle');
const showControl = controlModel.get('show', true);
const controlSize = showControl ? controlModel.get('itemSize') : 0;
const controlGap = showControl ? controlModel.get('itemGap') : 0;
const sizePlusGap = controlSize + controlGap;
// Special label rotate.
let labelRotation = timelineModel.get(['label', 'rotate']) || 0;
labelRotation = labelRotation * PI / 180; // To radian.
let playPosition: number[];
let prevBtnPosition: number[];
let nextBtnPosition: number[];
const controlPosition = controlModel.get('position', true);
const showPlayBtn = showControl && controlModel.get('showPlayBtn', true);
const showPrevBtn = showControl && controlModel.get('showPrevBtn', true);
const showNextBtn = showControl && controlModel.get('showNextBtn', true);
let xLeft = 0;
let xRight = mainLength;
// position[0] means left, position[1] means middle.
if (controlPosition === 'left' || controlPosition === 'bottom') {
showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap);
showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap);
showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
}
else { // 'top' 'right'
showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap);
showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
}
const axisExtent = [xLeft, xRight];
if (timelineModel.get('inverse')) {
axisExtent.reverse();
}
return {
viewRect: viewRect,
mainLength: mainLength,
orient: orient,
rotation: rotationMap[orient],
labelRotation: labelRotation,
labelPosOpt: parsedLabelPos,
labelAlign: timelineModel.get(['label', 'align']) || labelAlignMap[orient] as ZRTextAlign,
labelBaseline: timelineModel.get(['label', 'verticalAlign'])
|| timelineModel.get(['label', 'baseline'])
|| labelBaselineMap[orient] as ZRTextVerticalAlign,
// Based on mainGroup.
playPosition: playPosition,
prevBtnPosition: prevBtnPosition,
nextBtnPosition: nextBtnPosition,
axisExtent: axisExtent,
controlSize: controlSize,
controlGap: controlGap
};
}