mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-24 23:51:20 -08:00
fix(danmuku): [PKG-DANMUKU-10] bound dense heatmaps for issue 958
This commit is contained in:
1 parent
053d211fb0
commit
abc8008da7
18 files changed
+4841
-21
No files matched your search
@@ -25,7 +25,8 @@ export function heatmapGeometry({ width, height, duration, queue, option, points
|
||||
smoothing: 0.2,
|
||||
flattening: 0.2,
|
||||
}
|
||||
const options = Object.assign({}, defaults, typeof option === 'object' ? option : {})
|
||||
const configured = Object.assign({}, typeof option === 'object' ? option : {})
|
||||
const options = Object.assign({}, defaults, configured)
|
||||
for (const key of Object.keys(defaults)) {
|
||||
if (!Number.isFinite(options[key]))
|
||||
options[key] = defaults[key]
|
||||
@@ -34,7 +35,8 @@ export function heatmapGeometry({ width, height, duration, queue, option, points
|
||||
options.sampling = defaults.sampling
|
||||
if (options.xMin === options.xMax || options.yMin === options.yMax)
|
||||
return null
|
||||
const points = Array.isArray(input) && input.length ? [...input] : sampleHeatmap(queue, width, duration, options.sampling)
|
||||
const hasCustomPoints = Array.isArray(input) && input.length > 0
|
||||
const points = hasCustomPoints ? [...input] : sampleHeatmap(queue, width, duration, options.sampling)
|
||||
if (!points.length
|
||||
|| !points.every(point => Array.isArray(point) && Number.isFinite(point[0]) && Number.isFinite(point[1]))) { return null }
|
||||
const lastPoint = points[points.length - 1]
|
||||
@@ -55,14 +57,24 @@ export function heatmapGeometry({ width, height, duration, queue, option, points
|
||||
const y = point[1]
|
||||
point[1] = y * (y > yMid ? 1 + options.scale : 1 - options.scale) + options.minHeight
|
||||
}
|
||||
// Explicit axes and custom points retain their coordinate interpretation. Fit automatic
|
||||
// charts into the lower quarter so dense data cannot obscure the video.
|
||||
const automatic = !hasCustomPoints && !Number.isFinite(configured.yMin) && !Number.isFinite(configured.yMax)
|
||||
let peak = 0
|
||||
for (const point of points) peak = Math.max(peak, point[1])
|
||||
const fitted = automatic && peak > defaults.yMax / 4
|
||||
if (fitted)
|
||||
options.yMax = peak * 4
|
||||
const boundY = value => fitted ? Math.min(height, Math.max(height * 0.75, value)) : value
|
||||
const controlPoint = (current, previous, next, reverse) => {
|
||||
const geometry = line(previous || current, next || current)
|
||||
const flat = map(Math.cos(geometry.angle) * options.flattening, 0, 1, 1, 0)
|
||||
const angle = geometry.angle * flat + (reverse ? Math.PI : 0)
|
||||
const length = geometry.length * options.smoothing
|
||||
return [current[0] + Math.cos(angle) * length, current[1] + Math.sin(angle) * length]
|
||||
// A cubic stays inside the convex hull of its endpoints and controls.
|
||||
return [current[0] + Math.cos(angle) * length, boundY(current[1] + Math.sin(angle) * length)]
|
||||
}
|
||||
const positions = points.map(point => [map(point[0], options.xMin, options.xMax, 0, width), map(point[1], options.yMin, options.yMax, height, 0)])
|
||||
const positions = points.map(point => [map(point[0], options.xMin, options.xMax, 0, width), boundY(map(point[1], options.yMin, options.yMax, height, 0))])
|
||||
if (!positions.every(point => point.every(Number.isFinite)))
|
||||
return null
|
||||
const path = positions.map((point, index, all) => {
|
||||
|
||||
Reference in new issue
Block a user