|
@@ -7,7 +7,7 @@ import state from "/src/state"
|
|
|
import "./index.less"
|
|
|
import Bird from "./bird"
|
|
|
|
|
|
-type pointsPosType = { x: number; y: number; MeasureNumberXML: number }[]
|
|
|
+type pointsPosType = { x: number; y: number; MeasureNumberXML: number; noteId: number }[]
|
|
|
type smoothAnimationType = {
|
|
|
isShow: Ref<boolean>
|
|
|
canvasDom: null | HTMLCanvasElement
|
|
@@ -64,7 +64,10 @@ export function initSmoothAnimation() {
|
|
|
// 初始化动画数据
|
|
|
const batePos = getPointsPosByBatePos()
|
|
|
console.log(batePos, "batePos")
|
|
|
- smoothAnimationState.pointsPos = createSmoothCurvePoints(batePos, undefined, undefined, _numberOfSegments)
|
|
|
+ const batePos1 = dataFilter([...batePos])
|
|
|
+ const batePos2 = createSmoothCurvePoints(batePos1, undefined, undefined, _numberOfSegments)
|
|
|
+ const batePos3 = dataFilter2(batePos, batePos2)
|
|
|
+ smoothAnimationState.pointsPos = batePos3
|
|
|
// 谱面的平均速度(因为可能有反复的情况所以实际距离要加上反复的距离)
|
|
|
const canvasDomPath = batePos.reduce((path, item, index, arr) => {
|
|
|
if (index !== 0) {
|
|
@@ -88,6 +91,27 @@ export function initSmoothAnimation() {
|
|
|
console.log(smoothAnimationState, "一行谱小鸟数据")
|
|
|
}
|
|
|
|
|
|
+// 排序
|
|
|
+function dataFilter(batePos: pointsPosType) {
|
|
|
+ const filterData = batePos.filter((item, index, array) => {
|
|
|
+ return array.findIndex(i => i.noteId === item.noteId) === index
|
|
|
+ })
|
|
|
+ // 先按 音符排序 因为音符可能有重复id
|
|
|
+ const sortedData = filterData.sort((a, b) => a.noteId - b.noteId)
|
|
|
+ // 再按 小节排序
|
|
|
+ return sortedData.sort((a, b) => a.MeasureNumberXML - b.MeasureNumberXML)
|
|
|
+}
|
|
|
+
|
|
|
+//给原始数据赋值
|
|
|
+function dataFilter2(batePos1: pointsPosType, batePos2: pointsPosType) {
|
|
|
+ return batePos1.reduce((arr: pointsPosType, { noteId, MeasureNumberXML }, index) => {
|
|
|
+ const noteIdIndex = batePos2.findIndex(item => {
|
|
|
+ return noteId === item.noteId && MeasureNumberXML === item.MeasureNumberXML
|
|
|
+ })
|
|
|
+ arr.push(...batePos2.slice(noteIdIndex, noteIdIndex + _numberOfSegments + 1))
|
|
|
+ return arr
|
|
|
+ }, [])
|
|
|
+}
|
|
|
/**
|
|
|
* 销毁
|
|
|
*/
|
|
@@ -163,6 +187,10 @@ export function moveSmoothAnimation(progress: number, activeIndex: number, isMov
|
|
|
let nowIndex = nextPointsIndex - _numberOfSegments + progressCalcIndex
|
|
|
const nowPointsPos = smoothAnimationState.pointsPos[nowIndex]
|
|
|
smoothAnimationState.canvasCtx?.clearRect(0, 0, smoothAnimationState.canvasDomWith, smoothAnimationState.canvasDomHeight)
|
|
|
+ if (!nowPointsPos?.x) {
|
|
|
+ console.error(nowPointsPos?.x, "nowPointsPos", nowIndex, activeIndex)
|
|
|
+ return
|
|
|
+ }
|
|
|
// 移动
|
|
|
smoothAnimationMove(
|
|
|
{
|
|
@@ -320,17 +348,26 @@ function getPointsPosByBatePos(): pointsPosType {
|
|
|
const frequencyData = state.times.map(item => {
|
|
|
return !item.frequency || item.frequency === -1 ? 0 : item.frequency
|
|
|
})
|
|
|
- console.log(frequencyData,"没线性化之前的数据")
|
|
|
// 线性频率数据
|
|
|
const frequencyLineData = quantileScale(frequencyData, 6, 74)
|
|
|
const pointsPos = state.times.reduce((posArr: any[], item, index) => {
|
|
|
- // 当休止小节,可能当前音符在谱面上没有实际的音符(没有bbox),所以往后找谱面上有的音符
|
|
|
- if (item.bbox) {
|
|
|
+ // 当休止小节,可能当前音符在谱面上没有实际的音符(没有bbox)
|
|
|
+ if (item.bbox?.x != null && item.noteId != null) {
|
|
|
posArr.push({
|
|
|
+ noteId: item.noteId,
|
|
|
MeasureNumberXML: item.MeasureNumberXML,
|
|
|
x: item.bbox.x,
|
|
|
y: 80 - frequencyLineData[index]
|
|
|
})
|
|
|
+ } else {
|
|
|
+ // 连续休止小节 noteId 可能为 null,所以这里取上一个音符的id
|
|
|
+ posArr.push({
|
|
|
+ // 这里当第一个音符noteId为null,找不到前一个noteId,所以兼容一下
|
|
|
+ noteId: item.noteId != null ? item.noteId : (posArr[posArr.length - 1]?.noteId != null ? posArr[posArr.length - 1]?.noteId : -1) + 0.01, // 这里+0.01 是制造一个假id
|
|
|
+ MeasureNumberXML: item.MeasureNumberXML,
|
|
|
+ x: item.bbox?.x != null ? item.bbox.x : posArr[posArr.length - 1]?.x || 10,
|
|
|
+ y: 80 - frequencyLineData[index]
|
|
|
+ })
|
|
|
}
|
|
|
return posArr
|
|
|
}, [])
|
|
@@ -338,7 +375,8 @@ function getPointsPosByBatePos(): pointsPosType {
|
|
|
const extendPoint = {
|
|
|
...pointsPos[pointsPos.length - 1]
|
|
|
}
|
|
|
- extendPoint.MeasureNumberXML++
|
|
|
+ extendPoint.MeasureNumberXML += 100 // 防止MeasureNumberXML重复
|
|
|
+ extendPoint.noteId += 100 // 防止noteId重复
|
|
|
// 当总长度减30小于最后一个音符时候,取最后一个音符加15
|
|
|
extendPoint.x = smoothAnimationState.canvasDomWith - 30 > extendPoint.x ? smoothAnimationState.canvasDomWith - 30 : extendPoint.x + 15
|
|
|
pointsPos.push(extendPoint)
|
|
@@ -399,62 +437,63 @@ function createSmoothCurvePoints(pointsPos: pointsPosType, tension?: number, clo
|
|
|
t2x = (ps[i + 2].x - ps[i].x) * tension
|
|
|
t1y = (ps[i + 1].y - ps[i - 1].y) * tension
|
|
|
t2y = (ps[i + 2].y - ps[i].y) * tension
|
|
|
- // 当中途出现反复 刚开始反复时候 53 52 22 52 (22)中途值会变小 这里强行拉大 防止算法平均值出现很大偏差
|
|
|
- if (ps[i + 1].MeasureNumberXML - ps[i + 2].MeasureNumberXML > 1) {
|
|
|
- const nowNumberXML = ps[i + 1].MeasureNumberXML + 1
|
|
|
- //在当前值的情况下 向前一位
|
|
|
- let index = ps.findIndex(item => {
|
|
|
- return nowNumberXML === item.MeasureNumberXML
|
|
|
- })
|
|
|
- // 查询不到index时候取当前值
|
|
|
- index === -1 && (index = i + 1)
|
|
|
- t2x = (ps[index].x - ps[i].x) * tension
|
|
|
- }
|
|
|
- // 当中途出现反复 结束反复时候 22 53 22 22 (53)中途值会变大 这里强行缩小 防止算法平均值出现很大偏差
|
|
|
- if (ps[i - 1].MeasureNumberXML - ps[i].MeasureNumberXML > 1) {
|
|
|
- //在当前值的情况下 向后一位
|
|
|
- const nowNumberXML = ps[i].MeasureNumberXML - 1
|
|
|
- let index = ps.findIndex((item, index) => {
|
|
|
- return nowNumberXML === item.MeasureNumberXML && nowNumberXML !== ps[index + 1]?.MeasureNumberXML
|
|
|
- })
|
|
|
- // 查询不到index时候取当前值
|
|
|
- index === -1 && (index = i)
|
|
|
- t1x = (ps[i + 1].x - ps[index].x) * tension
|
|
|
- }
|
|
|
- // 当中途出现跳房子 刚开始跳房子时候 35 35 54 35 (54)中途值会变大 这里强行缩小 防止算法平均值出现很大偏差
|
|
|
- if (ps[i + 1].MeasureNumberXML - ps[i + 2].MeasureNumberXML < -1) {
|
|
|
- const nowNumberXML = ps[i + 1].MeasureNumberXML + 1
|
|
|
- //在当前值的情况下 向前一位
|
|
|
- let index = ps.findIndex(item => {
|
|
|
- return nowNumberXML === item.MeasureNumberXML
|
|
|
- })
|
|
|
- // 查询不到index时候取当前值
|
|
|
- index === -1 && (index = i + 1)
|
|
|
- t2x = (ps[index].x - ps[i].x) * tension
|
|
|
- }
|
|
|
- // 当中途出现跳房子 结束跳房子时候 54 35 54 54 (35)中途值会变小 这里强行拉大 防止算法平均值出现很大偏差
|
|
|
- if (ps[i - 1].MeasureNumberXML - ps[i].MeasureNumberXML < -1) {
|
|
|
- const nowNumberXML = ps[i].MeasureNumberXML - 1
|
|
|
- let index = ps.findIndex((item, index) => {
|
|
|
- return nowNumberXML === item.MeasureNumberXML && nowNumberXML !== ps[index + 1]?.MeasureNumberXML
|
|
|
- })
|
|
|
- // 查询不到index时候取当前值
|
|
|
- index === -1 && (index = i)
|
|
|
- t1x = (ps[i + 1].x - ps[index].x) * tension
|
|
|
- }
|
|
|
- const nowMeasureNumberXML = pointsPos[i - 1].MeasureNumberXML
|
|
|
- const nextMeasureNumberXML = pointsPos[i].MeasureNumberXML
|
|
|
+ // // 当中途出现反复 刚开始反复时候 53 52 22 52 (22)中途值会变小 这里强行拉大 防止算法平均值出现很大偏差
|
|
|
+ // if (ps[i + 1].MeasureNumberXML - ps[i + 2].MeasureNumberXML > 1) {
|
|
|
+ // const nowNumberXML = ps[i + 1].MeasureNumberXML + 1
|
|
|
+ // //在当前值的情况下 向前一位
|
|
|
+ // let index = ps.findIndex(item => {
|
|
|
+ // return nowNumberXML === item.MeasureNumberXML
|
|
|
+ // })
|
|
|
+ // // 查询不到index时候取当前值
|
|
|
+ // index === -1 && (index = i + 1)
|
|
|
+ // t2x = (ps[index].x - ps[i].x) * tension
|
|
|
+ // }
|
|
|
+ // // 当中途出现反复 结束反复时候 22 53 22 22 (53)中途值会变大 这里强行缩小 防止算法平均值出现很大偏差
|
|
|
+ // if (ps[i - 1].MeasureNumberXML - ps[i].MeasureNumberXML > 1) {
|
|
|
+ // //在当前值的情况下 向后一位
|
|
|
+ // const nowNumberXML = ps[i].MeasureNumberXML - 1
|
|
|
+ // let index = ps.findIndex((item, index) => {
|
|
|
+ // return nowNumberXML === item.MeasureNumberXML && nowNumberXML !== ps[index + 1]?.MeasureNumberXML
|
|
|
+ // })
|
|
|
+ // // 查询不到index时候取当前值
|
|
|
+ // index === -1 && (index = i)
|
|
|
+ // t1x = (ps[i + 1].x - ps[index].x) * tension
|
|
|
+ // }
|
|
|
+ // // 当中途出现跳房子 刚开始跳房子时候 35 35 54 35 (54)中途值会变大 这里强行缩小 防止算法平均值出现很大偏差
|
|
|
+ // if (ps[i + 1].MeasureNumberXML - ps[i + 2].MeasureNumberXML < -1) {
|
|
|
+ // const nowNumberXML = ps[i + 1].MeasureNumberXML + 1
|
|
|
+ // //在当前值的情况下 向前一位
|
|
|
+ // let index = ps.findIndex(item => {
|
|
|
+ // return nowNumberXML === item.MeasureNumberXML
|
|
|
+ // })
|
|
|
+ // // 查询不到index时候取当前值
|
|
|
+ // index === -1 && (index = i + 1)
|
|
|
+ // t2x = (ps[index].x - ps[i].x) * tension
|
|
|
+ // }
|
|
|
+ // // 当中途出现跳房子 结束跳房子时候 54 35 54 54 (35)中途值会变小 这里强行拉大 防止算法平均值出现很大偏差
|
|
|
+ // if (ps[i - 1].MeasureNumberXML - ps[i].MeasureNumberXML < -1) {
|
|
|
+ // const nowNumberXML = ps[i].MeasureNumberXML - 1
|
|
|
+ // let index = ps.findIndex((item, index) => {
|
|
|
+ // return nowNumberXML === item.MeasureNumberXML && nowNumberXML !== ps[index + 1]?.MeasureNumberXML
|
|
|
+ // })
|
|
|
+ // // 查询不到index时候取当前值
|
|
|
+ // index === -1 && (index = i)
|
|
|
+ // t1x = (ps[i + 1].x - ps[index].x) * tension
|
|
|
+ // }
|
|
|
+ // const nowMeasureNumberXML = pointsPos[i - 1].MeasureNumberXML
|
|
|
+ // const nextMeasureNumberXML = pointsPos[i].MeasureNumberXML
|
|
|
for (t = 0; t <= numberOfSegments; t++) {
|
|
|
- // 小于1时候是反复 大于1是跳房子 不画曲线 停留
|
|
|
- if (nextMeasureNumberXML - nowMeasureNumberXML < 0 || nextMeasureNumberXML - nowMeasureNumberXML > 1) {
|
|
|
- //console.log(x, y)
|
|
|
- result.push({
|
|
|
- x: x as number,
|
|
|
- y: y as number,
|
|
|
- MeasureNumberXML: nowMeasureNumberXML
|
|
|
- })
|
|
|
- continue
|
|
|
- }
|
|
|
+ // // 小于1时候是反复 大于1是跳房子 不画曲线 停留
|
|
|
+ // if (nextMeasureNumberXML - nowMeasureNumberXML < 0 || nextMeasureNumberXML - nowMeasureNumberXML > 1) {
|
|
|
+ // //console.log(x, y)
|
|
|
+ // result.push({
|
|
|
+ // x: x as number,
|
|
|
+ // y: y as number,
|
|
|
+ // MeasureNumberXML: nowMeasureNumberXML,
|
|
|
+ // noteId: pointsPos[i - 1].noteId
|
|
|
+ // })
|
|
|
+ // continue
|
|
|
+ // }
|
|
|
st = t / numberOfSegments
|
|
|
c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1
|
|
|
c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2)
|
|
@@ -466,7 +505,10 @@ function createSmoothCurvePoints(pointsPos: pointsPosType, tension?: number, clo
|
|
|
result.push({
|
|
|
x,
|
|
|
y,
|
|
|
- MeasureNumberXML: t === numberOfSegments ? nextMeasureNumberXML : nowMeasureNumberXML
|
|
|
+ // MeasureNumberXML: t === numberOfSegments ? nextMeasureNumberXML : nowMeasureNumberXML,
|
|
|
+ // noteId: t === numberOfSegments ? pointsPos[i].noteId : pointsPos[i - 1].noteId
|
|
|
+ MeasureNumberXML: pointsPos[i - 1].MeasureNumberXML,
|
|
|
+ noteId: pointsPos[i - 1].noteId
|
|
|
})
|
|
|
}
|
|
|
}
|