Skip to content

Commit

Permalink
Merge pull request #1 from leon-kfd/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
leon-kfd authored Oct 18, 2023
2 parents 072d083 + 1ff6b63 commit 4542086
Show file tree
Hide file tree
Showing 16 changed files with 978 additions and 806 deletions.
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,24 @@
"licence": "MIT",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build": "vite build",
"serve": "vite preview"
},
"dependencies": {
"@antv/g-canvas": "^0.5.10",
"@types/d3": "^6.7.0",
"@antv/g": "^5.18.14",
"@antv/g-canvas": "^1.11.17",
"d3": "^7.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
},
"devDependencies": {
"@types/d3": "^6.7.0",
"@types/node": "^20.8.3",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@vitejs/plugin-react-refresh": "^1.3.1",
"sass": "^1.35.0",
"typescript": "^4.3.2",
"vite": "^2.3.7"
"@vitejs/plugin-react": "^4.1.0",
"sass": "^1.69.0",
"typescript": "^5.2.2",
"vite": "^4.4.11"
}
}
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React from 'react'
import GAudio from './components/g-audio'

function App() {
Expand Down
4 changes: 1 addition & 3 deletions src/components/g-audio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { MusicVisualizer } from '../plugins/MusicVisualizer'
import style from './g-audio.module.scss'
import SLine from './s-line'
import SPath from './s-path'
import SPathDot from './s-path-dot'
import SPathFill from './s-path-fill'
import SCircle from './s-circle'
import SPathDouble from './s-path-double'
Expand All @@ -13,7 +12,7 @@ import { apiURL, DEFAULT_IMG } from '@/global'

export const MusicVisualizerCtx = new MusicVisualizer()

const exampleList = [SLine, SPathDouble, SPath, SPathFill, SCircle, SPaticle, SDot, SPathDot]
const exampleList = [SLine, SPathDouble, SPath, SPathFill, SDot, SCircle, SPaticle ]

export default function GAudio() {
const audio = useRef<HTMLAudioElement>(null)
Expand Down Expand Up @@ -55,7 +54,6 @@ export default function GAudio() {
try {
const res = await (await fetch(`https://api.injahow.cn/meting/?type=playlist&id=8577182717`)).json()
if (res && res.length > 0) {
console.log('res')
setPlayList(res)
}
} catch {
Expand Down
128 changes: 67 additions & 61 deletions src/components/s-circle.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import React, { useEffect, useRef } from "react";
import { Canvas, IShape } from '@antv/g-canvas';
import { getCirclePath } from '../utils'
import { Canvas, Image, Circle, Group, IAnimation } from '@antv/g';
import { Renderer } from '@antv/g-canvas';
import { getImageCircle } from '../utils/base';
import { X, Y, R } from '../utils/constanst'
import useAudioImg from "@/hooks/useAudioImg";

type ICircleItem = {
circle: Circle,
dot: Circle
}

export default function SCircle(props: SComponentProps) {
const LINE_COLOR = '#fff'
const DOT_COLOR = '#e9dcf7'
const DOT_COLOR = '#fa7'
const DOT_R = 5
const CIRCLE_NUM = 3
const CIRCLE_DELAY = 2000
const CIRCLE_SCALE_OFFSET = 80
const CIRCLE_SCALE_RARIO = 2

const canvas = useRef<Canvas>()
const circle = useRef<IShape>()
const circle = useRef<Image>()

const circleArr = useRef<IShape[]>([])
const circleDotArr = useRef<IShape[]>([])
const circleDotDegArr = useRef<number[]>([])
const circleArr = useRef<ICircleItem[]>([])
const circleArrStart = useRef<boolean[]>([])

const realtimeData = useRef<number[]>([])
Expand Down Expand Up @@ -50,6 +53,7 @@ export default function SCircle(props: SComponentProps) {
container: 'SCircle',
width: 2 * X,
height: 2 * Y,
renderer: new Renderer()
});

circle.current = getImageCircle(canvas.current, {
Expand All @@ -60,89 +64,66 @@ export default function SCircle(props: SComponentProps) {
})

const addCircle = () => {
return (canvas.current as Canvas).addShape('circle', {
attrs: {
const circle = new Circle({
style: {
cx: X,
cy: Y,
stroke: LINE_COLOR,
lineWidth: 2,
opacity: 0,
x: X,
y: Y,
opacity: 1,
r: R
//path: getCirclePath(X, Y, R),
}
})
};
const addCircleDot = () => {
return (canvas.current as Canvas).addShape('circle', {
attrs: {
x: X,
y: Y - R,
const circleDot = new Circle({
style: {
r: DOT_R,
fill: LINE_COLOR,
shadowColor: DOT_COLOR,
shadowBlur: DOT_R,
opacity: 0
}
opacity: 0,
},
})
}
canvas.current?.appendChild(circle)
canvas.current?.appendChild(circleDot)
return [circle, circleDot]
};
const animateOption = {
duration: 6000,
easing: 'easeLinear',
repeat: true
duration: CIRCLE_DELAY * CIRCLE_NUM,
iterations: Infinity
}
Array.from({ length: CIRCLE_NUM }, (item, index) => {
circleArrStart.current.push(false)
// circle
circleArr.current.push(addCircle())
circleArr.current[index].animate((ratio: number) => {
return {
r: R + ratio * CIRCLE_SCALE_OFFSET,
// path: getCirclePath(X, Y, R + ratio * 80),
opacity: ratio > 0.02 && ratio < 0.9 ? 0.8 - ratio * 0.8 : 0
}
}, animateOption)
// circle-dot
circleDotArr.current.push(addCircleDot())
circleDotDegArr.current.push(0)
circleDotArr.current[index].animate((ratio: number) => {
if (props.data && ratio < 0.05 && !circleDotDegArr.current[index]) {
circleDotDegArr.current[index] = pickStartPoint()
} else if (ratio > 0.9) {
circleDotDegArr.current[index] = 0
}
const deg = circleDotDegArr.current[index] + ratio * 360 - 180
const l = Math.cos(deg * Math.PI / 180)
const t = Math.sin(deg * Math.PI / 180)
const r = R + ratio * CIRCLE_SCALE_OFFSET
return {
x: X + l * r,
y: Y + t * r,
r: DOT_R * (1 - ratio / 2),
opacity: ratio > 0.05 && ratio < 0.9 ? 0.8 - ratio * 0.8 : 0
}
}, animateOption)
const [circle, dot] = addCircle()
circleArr.current.push({ circle, dot })
circleArr.current[index].circle.animate(
[
{ transform: 'scale(1)', opacity: 0.8 },
{ transform: `scale(${CIRCLE_SCALE_RARIO})`, opacity: 0 }
],
animateOption
)
})
}

if (props.isPlaying) {
for(let i = 0; i < circleArr.current.length; i++) {
if (circleArrStart.current[i]) {
circleArr.current[i].resumeAnimate()
circleDotArr.current[i].resumeAnimate()
circleArr.current[i].circle.getAnimations()?.[0]?.play()
circleArr.current[i].dot.getAnimations()?.[0]?.play()
} else {
setTimeout(() => {
if (!isPlaying.current) return
circleArr.current[i].resumeAnimate()
circleDotArr.current[i].resumeAnimate()
circleArr.current[i].circle.getAnimations()?.[0]?.play()
runDotAnimation(circleArr.current[i].dot)
circleArrStart.current[i] = true
}, i * CIRCLE_DELAY)
}
}
} else {
setTimeout(() => {
for(let i = 0; i < circleArr.current.length; i++) {
circleArr.current[i].pauseAnimate()
circleDotArr.current[i].pauseAnimate()
circleArr.current[i].circle.getAnimations()?.[0]?.pause()
circleArr.current[i].dot.getAnimations()?.[0]?.pause()
}
})
}
Expand All @@ -154,6 +135,31 @@ export default function SCircle(props: SComponentProps) {

useAudioImg(canvas, circle, props.isPlaying, props.audioImg)

function runDotAnimation(shape: Circle) {
const deg = -135 + pickStartPoint()
const l = Math.cos(deg * Math.PI / 180)
const t = Math.sin(deg * Math.PI / 180)
shape.setAttribute('cx', X + l * R)
shape.setAttribute('cy', Y + t * R)
shape.setAttribute('transformOrigin', `${-l * R + DOT_R}px ${-t * R + DOT_R}px`);
const animation = shape.animate(
[
{ transform: 'rotate(0) translate(0, 0)', opacity: 0, offset: 0.01 },
{ opacity: 0.9, offset: 0.02 },
{ transform: `rotate(360deg) translate(${l * R}, ${t * R})`, opacity: 0 }
],
{
duration: CIRCLE_DELAY * CIRCLE_NUM
}
)
if (animation) {
animation.onfinish = () => {
animation.cancel() // release memory??
runDotAnimation(shape)
}
}
}

return (
<div id="SCircle" className="s-canvas-wrapper"></div>
)
Expand Down
46 changes: 16 additions & 30 deletions src/components/s-dot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef } from "react";
import { Canvas } from '@antv/g-canvas';
import { Canvas, Image, Circle, Line } from '@antv/g';
import { Renderer } from '@antv/g-canvas'
// import { formatToTransit } from '../utils'
import { IElement, IShape } from "@antv/g-canvas/lib/types";
import { getImageCircle } from '../utils/base';
import { X, Y, R } from '../utils/constanst';
import useAudioImg from "@/hooks/useAudioImg";
Expand All @@ -18,10 +18,10 @@ export default function SDot(props: SComponentProps) {


const canvas = useRef<Canvas>()
const circle = useRef<IShape>()
const circle = useRef<Image>()

const sArr = useRef<IElement[]>([])
const lArr = useRef<IElement[]>([])
const sArr = useRef<Circle[]>([])
const lArr = useRef<Line[]>([])

function getArray(arr: number[]) {
// return formatToTransit(arr, 13, 0.92)
Expand All @@ -43,8 +43,8 @@ export default function SDot(props: SComponentProps) {
if (props.data?.length) {
getArray(props.data).map((item,index) => {
const [x, y] = getPointByIndex(index, item * item / 65025 * DOT_OFFSET + 4)
sArr.current[index].attr('x', x)
sArr.current[index].attr('y', y)
sArr.current[index].attr('cx', x)
sArr.current[index].attr('cy', y)
lArr.current[index].attr('x2', x)
lArr.current[index].attr('y2', y)
})
Expand All @@ -58,6 +58,7 @@ export default function SDot(props: SComponentProps) {
container: 'SDot',
width: 2 * X,
height: 2 * Y,
renderer: new Renderer()
});

circle.current = getImageCircle(canvas.current, {
Expand All @@ -67,36 +68,19 @@ export default function SDot(props: SComponentProps) {
shadowColor: DOT_COLOR
})

// sArr.current = Array.from({ length: POINT_NUM }, (item, index: number) => {
// const [x, y, l, t] = getPointByIndex(index)
// const shadowOffsetX = l * SHADOW_OFFSET
// const shadowOffsetY = t * SHADOW_OFFSET
// return (canvas.current as Canvas).addShape('circle', {
// attrs: {
// x,
// y,
// r: DOT_R,
// fill: DOT_COLOR,
// shadowColor: SHADOW_COLOR,
// shadowOffsetX: -shadowOffsetX,
// shadowOffsetY: -shadowOffsetY,
// shadowBlur: SHADOW_BLUR
// }
// })
// })
Array.from({ length: POINT_NUM }, (item, index: number) => {
const [x, y, l, t] = getPointByIndex(index)
const deg = ~~(index * (360 / POINT_NUM) + 210)
const dot = (canvas.current as Canvas).addShape('circle', {
attrs: {
x,
y,
const dot = new Circle({
style: {
cx: x,
cy: y,
r: DOT_R,
fill: DOT_COLOR
}
})
const line = (canvas.current as Canvas).addShape('line', {
attrs: {
const line = new Line({
style: {
x1: x,
y1: y,
x2: x,
Expand All @@ -105,6 +89,8 @@ export default function SDot(props: SComponentProps) {
stroke: `l(${deg}) 0.3:rgba(255,255,255,0) 1:${DOT_COLOR}`
}
})
canvas.current?.appendChild(dot)
canvas.current?.appendChild(line)
sArr.current.push(dot)
lArr.current.push(line)
})
Expand Down
Loading

0 comments on commit 4542086

Please sign in to comment.