upgrade skinview3d

This commit is contained in:
Pig Fang 2022-02-05 15:02:58 +08:00
parent 1c105629fc
commit 5579bed8f0
No known key found for this signature in database
GPG Key ID: A8198F548DADA9E2
3 changed files with 115 additions and 106 deletions

View File

@ -42,7 +42,7 @@
"reaptcha": "^1.7.2",
"rxjs": "^6.5.5",
"skinview-utils": "^0.5.5",
"skinview3d": "^1.2.1",
"skinview3d": "^2.2.1",
"spectre.css": "^0.5.8",
"use-immer": "^0.4.2",
"workbox-expiration": "^5.1.3",

View File

@ -26,24 +26,16 @@ interface Props {
initPositionZ?: number
}
type ViewerStuff = {
handles: {
walk: skinview3d.AnimationHandle
run: skinview3d.AnimationHandle
rotate: skinview3d.AnimationHandle
}
control: skinview3d.OrbitControls
firstRun: boolean
type AnimationHandles = {
walk: skinview3d.SubAnimationHandle | null
run: skinview3d.SubAnimationHandle | null
rotate: skinview3d.SubAnimationHandle | null
}
const emptyStuff: ViewerStuff = {
handles: {
walk: {} as skinview3d.AnimationHandle,
run: {} as skinview3d.AnimationHandle,
rotate: {} as skinview3d.AnimationHandle,
},
control: {} as skinview3d.OrbitControls,
firstRun: true,
const animationHandles: AnimationHandles = {
walk: null,
run: null,
rotate: null,
}
const ActionButton = styled.i`
@ -55,15 +47,11 @@ const ActionButton = styled.i`
}
`
const cssCardBody = css`
background-repeat: no-repeat;
background-position: center;
background-size: cover;
`
const cssViewer = css`
${breakpoints.greaterThan(breakpoints.Breakpoint.lg)} {
min-height: 500px;
}
width: 100%;
canvas {
cursor: move;
@ -74,15 +62,11 @@ const Viewer: React.FC<Props> = (props) => {
const { initPositionZ = 70 } = props
const viewRef: React.MutableRefObject<skinview3d.SkinViewer> = useRef(null!)
const containerRef = useRef<HTMLDivElement>(null)
const stuffRef = useRef(emptyStuff)
const containerRef = useRef<HTMLCanvasElement>(null)
const animationHandlesRef = useRef(animationHandles)
const [paused, setPaused] = useState(false)
const [running, setRunning] = useState(false)
const [reset, setReset] = useState(0)
const [background, setBackground] = useState(() =>
document.body.classList.contains('dark-mode') ? '#6c757d' : '#fff',
)
const [bgPicture, setBgPicture] = useState(-1)
const indicator = (() => {
@ -99,118 +83,124 @@ const Viewer: React.FC<Props> = (props) => {
useEffect(() => {
const container = containerRef.current!
const viewer = new skinview3d.SkinViewer({
domElement: container,
const viewer = new skinview3d.FXAASkinViewer({
canvas: container,
width: container.clientWidth,
height: container.clientHeight,
skinUrl: props.skin || SkinSteve,
capeUrl: props.cape || '',
detectModel: false,
skin: props.skin || SkinSteve,
cape: props.cape || '',
model: props.isAlex ? 'slim' : 'default',
zoom: initPositionZ / 100,
})
viewer.camera.position.z = initPositionZ
viewer.playerObject.skin.slim = props.isAlex
const animation = new skinview3d.CompositeAnimation()
stuffRef.current.handles = {
walk: animation.add(skinview3d.WalkingAnimation),
run: animation.add(skinview3d.RunningAnimation),
rotate: animation.add(skinview3d.RotatingAnimation),
if (document.body.classList.contains('dark-mode')) {
viewer.background = '#6c757d'
}
stuffRef.current.handles.run.paused = true
// @ts-ignore
viewer.animation = animation as skinview3d.Animation
stuffRef.current.control = skinview3d.createOrbitControls(viewer)
if (!stuffRef.current.firstRun) {
const { handles } = stuffRef.current
handles.walk.paused = true
handles.run.paused = true
handles.rotate.paused = true
viewer.camera.position.z = 70
}
const rotate = viewer.animations.add(skinview3d.RotatingAnimation)
animationHandlesRef.current.rotate = rotate
const control = skinview3d.createOrbitControls(viewer)
viewRef.current = viewer
return () => {
control.dispose()
viewer.dispose()
stuffRef.current.firstRun = false
}
}, [reset])
useEffect(() => {
return () => {
stuffRef.current.firstRun = true
}
}, [])
useEffect(() => {
const viewer = viewRef.current
viewer.skinUrl = props.skin || SkinSteve
}, [props.skin])
viewer.loadSkin(props.skin || SkinSteve, props.isAlex ? 'slim' : 'default')
}, [props.skin, props.isAlex])
useEffect(() => {
const viewer = viewRef.current
if (props.cape) {
viewer.capeUrl = props.cape
viewer.loadCape(props.cape)
} else {
viewer.playerObject.cape.visible = false
viewer.resetCape()
}
}, [props.cape])
useEffect(() => {
const viewer = viewRef.current
viewer.playerObject.skin.slim = props.isAlex
}, [props.isAlex])
const handles = animationHandlesRef.current
if (running) {
handles.walk?.resetAndRemove()
handles.walk = null
const run = viewRef.current.animations.add(skinview3d.RunningAnimation)
run.speed = 0.6
handles.run = run
} else {
handles.run?.resetAndRemove()
handles.run = null
const walk = viewRef.current.animations.add(skinview3d.WalkingAnimation)
handles.walk = walk
}
}, [running])
useEffect(() => {
viewRef.current.animations.paused = paused
}, [paused])
useEffect(() => {
viewRef.current.loadBackground(backgrounds[bgPicture]!)
}, [bgPicture])
const togglePause = () => {
setPaused((paused) => !paused)
viewRef.current.animationPaused = !viewRef.current.animationPaused
}
const toggleRun = () => {
setRunning((running) => !running)
const { handles } = stuffRef.current
handles.run.paused = !handles.run.paused
handles.walk.paused = false
}
const toggleRotate = () => {
const { handles } = stuffRef.current
handles.rotate.paused = !handles.rotate.paused
const handles = animationHandlesRef.current
if (handles.rotate) {
handles.rotate.paused = !handles.rotate.paused
}
}
const handleReset = () => {
setReset((c) => c + 1)
const handles = animationHandlesRef.current
handles.walk?.resetAndRemove()
handles.run?.resetAndRemove()
handles.rotate?.resetAndRemove()
viewRef.current.animations.paused = true
}
const setWhite = () => setBackground('#fff')
const setGray = () => setBackground('#6c757d')
const setBlack = () => setBackground('#000')
const setWhite = () => {
viewRef.current.background = '#fff'
}
const setGray = () => {
viewRef.current.background = '#6c757d'
}
const setBlack = () => {
viewRef.current.background = '#000'
}
const setPrevPicture = () => {
let index = bgPicture
if (bgPicture <= 0) {
index = PICTURES_COUNT - 1
} else {
index -= 1
}
setBgPicture(index)
setBackground(`url('${backgrounds[index]}')`)
setBgPicture((index) => {
if (bgPicture <= 0) {
return PICTURES_COUNT - 1
} else {
return index - 1
}
})
}
const setNextPicture = () => {
let index = bgPicture
if (bgPicture >= PICTURES_COUNT - 1) {
index = 0
} else {
index += 1
}
setBgPicture(index)
setBackground(`url('${backgrounds[index]}')`)
setBgPicture((index) => {
if (bgPicture >= PICTURES_COUNT - 1) {
return 0
} else {
return index + 1
}
})
}
const backgroundStyle = background.startsWith('#')
? { backgroundColor: background }
: { backgroundImage: background }
return (
<div className="card">
<div className="card-header">
@ -253,8 +243,8 @@ const Viewer: React.FC<Props> = (props) => {
</div>
</div>
</div>
<div className="card-body" css={cssCardBody} style={backgroundStyle}>
<div ref={containerRef} css={cssViewer}></div>
<div className="card-body p-0">
<canvas ref={containerRef} css={cssViewer}></canvas>
</div>
<div className="card-footer">
<div className="mt-2 mb-3 d-flex">

View File

@ -1567,6 +1567,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42"
integrity sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==
"@types/offscreencanvas@^2019.6.4":
version "2019.6.4"
resolved "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.6.4.tgz#64f6d120b53925028299c744fcdd32d2cd525963"
integrity sha512-u8SAgdZ8ROtkTF+mfZGOscl0or6BSj9A4g37e6nvxDc+YB/oDut0wHkK2PBBiC2bNR8TS0CPV+1gAk4fNisr1Q==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@ -1669,6 +1674,11 @@
dependencies:
"@types/jest" "*"
"@types/three@^0.136.1":
version "0.136.1"
resolved "https://registry.npmjs.org/@types/three/-/three-0.136.1.tgz#030fc01cdc5ce82cad93db17b94a24515cb4b50e"
integrity sha512-gzTw6RR4dU8sGf+RpLBWWKHRVIJ4gwKVQPk+IFCgha04Efg/itXYUalX6iBcYeSmaDu0qE5M7uTq0XLQpU4FAg==
"@types/tween.js@^18.5.0":
version "18.5.0"
resolved "https://registry.yarnpkg.com/@types/tween.js/-/tween.js-18.5.0.tgz#27d10aafa36c75c72953f00936663546b2a28441"
@ -7662,12 +7672,21 @@ skinview-utils@^0.5.5:
resolved "https://registry.npmjs.org/skinview-utils/-/skinview-utils-0.5.5.tgz#55671db8db97f82df0f87e1c8ec95bd58e861bc8"
integrity sha512-lApkcJuGQhK9j4oGeaPTjAx/WiRMduunho7RUoBbP+ceOCbncHogQNkfwbil7pjgvyy8S82pBdfzOQggjbZMdg==
skinview3d@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/skinview3d/-/skinview3d-1.2.1.tgz#f9628940b5118112fc877872325717839f0d3976"
integrity sha512-M7fyNaybg0C3y87NOE3VyozxQeYXo0BA160mob9TLRSKLEeWAfX1W10t4fQ3WJNXkQiA+i8smUyaXfxjY7r43w==
skinview-utils@^0.6.2:
version "0.6.2"
resolved "https://registry.npmjs.org/skinview-utils/-/skinview-utils-0.6.2.tgz#1247aef71c472e963fd3f0db3494f18d63e31e51"
integrity sha512-UdjWwXCVZobtG+dc7ilvMRbtXYSqPJtWKPFdgWc44Gs4aoOmZML2lErr77h7uussXo9zrcR+fPizGshGpdETvQ==
dependencies:
three "^0.112.1"
"@types/offscreencanvas" "^2019.6.4"
skinview3d@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/skinview3d/-/skinview3d-2.2.1.tgz#f66f29a35055d378a5949c72512e2c6eddaad02a"
integrity sha512-VOzB2jcsXWTmyEqE6nIXhECg1+29ZcZjP0tw9mFIGN9Y4P/hDlAt2ev7NT7J0Sqgei5UJenkorW24VDZHCepKw==
dependencies:
"@types/three" "^0.136.1"
skinview-utils "^0.6.2"
three "^0.136.0"
slash@^2.0.0:
version "2.0.0"
@ -8172,10 +8191,10 @@ text-table@^0.2.0:
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
three@^0.112.1:
version "0.112.1"
resolved "https://registry.yarnpkg.com/three/-/three-0.112.1.tgz#f8d8f4d0f8e5f753dac6260491b8209457fdc131"
integrity sha512-8I0O74hiYtKl3LgDNcPJbBGOlpekbcJ6fJnImmW3mFdeUFJ2H9Y3/UuUSW2sBdjrIlCM0gvOkaTEFlofO900TQ==
three@^0.136.0:
version "0.136.0"
resolved "https://registry.npmjs.org/three/-/three-0.136.0.tgz#b1504db021b46398ef468aa7849f3dcabb814f50"
integrity sha512-+fEMX7nYLz2ZesVP/dyifli5Jf8gR3XPAnFJveQ80aMhibFduzrADnjMbARXh8+W9qLK7rshJCjAIL/6cDxC+A==
throat@^6.0.1:
version "6.0.1"