1
0
Fork 0
mirror of synced 2024-06-22 17:01:09 -04:00
ultimate-vim/sources_non_forked/markdown-preview.nvim/app/pages/scroll.js
2022-05-19 20:12:11 +08:00

113 lines
2.4 KiB
JavaScript

function scroll (offsetTop) {
[document.body, document.documentElement].forEach((ele) => {
// eslint-disable-next-line
TweenLite.to(
ele,
0.4,
{
scrollTop: offsetTop,
ease: Power2.easeOut // eslint-disable-line
}
)
})
}
function getAttrTag (line) {
return `[data-source-line="${line}"]`
}
function getPreLineOffsetTop (line) {
let currentLine = line - 1
let ele = null
while (currentLine > 0 && !ele) {
ele = document.querySelector(getAttrTag(currentLine))
if (!ele) {
currentLine -= 1
}
}
return [
currentLine >= 0 ? currentLine : 0,
ele ? ele.offsetTop : 0
]
}
function getNextLineOffsetTop (line, len) {
let currentLine = line + 1
let ele = null
while (currentLine < len && !ele) {
ele = document.querySelector(getAttrTag(currentLine))
if (!ele) {
currentLine += 1
}
}
return [
currentLine < len ? currentLine : len - 1,
ele ? ele.offsetTop : document.documentElement.scrollHeight
]
}
function topOrBottom (line, len) {
if (line === 0) {
scroll(0)
} else if (line === len - 1) {
scroll(document.documentElement.scrollHeight)
}
}
function relativeScroll (line, ratio, len) {
let offsetTop = 0
const lineEle = document.querySelector(`[data-source-line="${line}"]`)
if (lineEle) {
offsetTop = lineEle.offsetTop
} else {
const pre = getPreLineOffsetTop(line)
const next = getNextLineOffsetTop(line, len)
offsetTop = pre[1] + ((next[1] - pre[1]) * (line - pre[0]) / (next[0] - pre[0]))
}
scroll(offsetTop - document.documentElement.clientHeight * ratio)
}
export default {
relative: function ({
cursor,
winline,
winheight,
len
}) {
const line = cursor - 1
const ratio = winline / winheight
if (line === 0 || line === len - 1) {
topOrBottom(line, len)
} else {
relativeScroll(line, ratio, len)
}
},
middle: function ({
cursor,
// winline,
// winheight,
len
}) {
const line = cursor - 1
if (line === 0 || line === len - 1) {
topOrBottom(line, len)
} else {
relativeScroll(line, 0.5, len)
}
},
top: function ({
cursor,
winline,
// winheight,
len
}) {
let line = cursor - 1
if (line === 0 || line === len - 1) {
topOrBottom(line, len)
} else {
line = cursor - winline
relativeScroll(line, 0, len)
}
}
}