|
|
@@ -0,0 +1,261 @@
|
|
|
+const modelViewerParameters = document.querySelector("model-viewer#sphere")
|
|
|
+const ecButton = document.querySelector("#ec-button")
|
|
|
+const strengthButton = document.querySelector("#strength-button")
|
|
|
+const splitBox = document.querySelector(".splitBox")
|
|
|
+const container = document.querySelector("#container")
|
|
|
+const buttonBox = document.querySelector(".buttonBox")
|
|
|
+
|
|
|
+// 需要切换的贴图
|
|
|
+let bmTexture = null
|
|
|
+let bmTexture2 = null
|
|
|
+// 金属度粗糙度贴图
|
|
|
+let mRTexture = null
|
|
|
+
|
|
|
+// 当前贴图
|
|
|
+let material = null
|
|
|
+
|
|
|
+
|
|
|
+// 进入页面,加载好贴图
|
|
|
+modelViewerParameters.addEventListener("load", () => {
|
|
|
+ strengthButton.style.display = "block"
|
|
|
+ ecButton.style.display = "block"
|
|
|
+ material = modelViewerParameters.model.materials[0]
|
|
|
+ // 设置金属度粗糙度
|
|
|
+ // material.pbrMetallicRoughness.setMetallicFactor(0);
|
|
|
+ // material.pbrMetallicRoughness.setRoughnessFactor(0.66)
|
|
|
+ // 设置baseColor贴图
|
|
|
+
|
|
|
+ bmTexture = material.pbrMetallicRoughness.baseColorTexture.texture
|
|
|
+ // 设置金属度粗糙度贴图
|
|
|
+ modelViewerParameters.createTexture("./static/gltf-13/2_r-4k.jpg").then((texture) => {
|
|
|
+ material.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(texture)
|
|
|
+ mRTexture = texture
|
|
|
+ })
|
|
|
+ modelViewerParameters.createTexture("./static/gltf-13/bm-color.jpg").then((texture) => {
|
|
|
+ bmTexture2 = texture
|
|
|
+ })
|
|
|
+ modelViewerParameters.createTexture("./static/gltf-13/color_normal.jpg").then((texture) => {
|
|
|
+ material.normalTexture.setTexture(texture)
|
|
|
+ })
|
|
|
+
|
|
|
+})
|
|
|
+
|
|
|
+// 创建第二个模型
|
|
|
+const modelViewerParameters2 = modelViewerParameters.cloneNode(true)
|
|
|
+modelViewerParameters2.id = "sphere2"
|
|
|
+modelViewerParameters2.style.display = "none"
|
|
|
+document.querySelector("#container").appendChild(modelViewerParameters2)
|
|
|
+// 加载第二个模型
|
|
|
+modelViewerParameters2.addEventListener("load", () => {
|
|
|
+ const material2 = modelViewerParameters2.model.materials[0]
|
|
|
+ modelViewerParameters2.createTexture("./static/gltf-13/2_r-4k.jpg").then((texture) => {
|
|
|
+ material2.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(texture)
|
|
|
+ })
|
|
|
+ modelViewerParameters2.createTexture("./static/gltf-13/bm-color.jpg").then((texture) => {
|
|
|
+ material2.pbrMetallicRoughness.baseColorTexture.setTexture(texture)
|
|
|
+ })
|
|
|
+ material2.pbrMetallicRoughness.setBaseColorFactor([0.3137, 0.3137, 0.3137])
|
|
|
+ console.log(material2)
|
|
|
+})
|
|
|
+
|
|
|
+const closeCompare = () => {
|
|
|
+ modelViewerParameters2.style.display = "none"
|
|
|
+ modelViewerParameters.style.width = "100%"
|
|
|
+ modelViewerParameters.style.height = "100%"
|
|
|
+ modelViewerParameters.style.maxWidth = "100%"
|
|
|
+ splitBox.style.display = "none"
|
|
|
+ ecButton.style.backgroundColor = "#f0f0f0"
|
|
|
+ container.style.flexDirection = "row"
|
|
|
+
|
|
|
+ isEcClick = true
|
|
|
+}
|
|
|
+
|
|
|
+const openComparePC = () => {
|
|
|
+ modelViewerParameters2.style.display = "block"
|
|
|
+ modelViewerParameters.style.width = "49.5%"
|
|
|
+ modelViewerParameters.style.maxWidth = "80%"
|
|
|
+ splitBox.style.display = "flex"
|
|
|
+ ecButton.style.backgroundColor = "#ccc"
|
|
|
+ startSync()
|
|
|
+ isEcClick = false
|
|
|
+}
|
|
|
+
|
|
|
+const openCompareM = () => {
|
|
|
+ modelViewerParameters2.style.display = "block"
|
|
|
+ modelViewerParameters2.style.width = "100%"
|
|
|
+ modelViewerParameters2.style.height = "0%"
|
|
|
+ modelViewerParameters.style.height = "50%"
|
|
|
+ container.style.flexDirection = "column"
|
|
|
+ ecButton.style.backgroundColor = "#ccc"
|
|
|
+
|
|
|
+ startSync()
|
|
|
+ isEcClick = false
|
|
|
+}
|
|
|
+
|
|
|
+// 点击切换展示第二个模型
|
|
|
+let isEcClick = true
|
|
|
+ecButton.addEventListener("click", () => {
|
|
|
+ if (isEcClick) {
|
|
|
+ if (isMobile) {
|
|
|
+ openCompareM()
|
|
|
+ } else {
|
|
|
+ openComparePC()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ closeCompare()
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// 点击增强按钮切换贴图
|
|
|
+let isStrengthClick = true
|
|
|
+strengthButton.addEventListener("click", () => {
|
|
|
+ console.log("点击了")
|
|
|
+ if (isStrengthClick) {
|
|
|
+ material.pbrMetallicRoughness.baseColorTexture.setTexture(bmTexture2)
|
|
|
+ material.pbrMetallicRoughness.setBaseColorFactor([0.3137, 0.3137, 0.3137])
|
|
|
+ strengthButton.style.backgroundColor = "#ccc"
|
|
|
+ isStrengthClick = false
|
|
|
+ closeCompare()
|
|
|
+ } else {
|
|
|
+ material.pbrMetallicRoughness.baseColorTexture.setTexture(bmTexture)
|
|
|
+ material.pbrMetallicRoughness.setBaseColorFactor([1, 1, 1])
|
|
|
+ strengthButton.style.backgroundColor = "#f0f0f0"
|
|
|
+ isStrengthClick = true
|
|
|
+ }
|
|
|
+
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+// 拖动分割线
|
|
|
+splitBox.addEventListener("mousedown", (e) => {
|
|
|
+ e.preventDefault() // 阻止默认行为
|
|
|
+
|
|
|
+ const containerWidth = container.offsetWidth
|
|
|
+ const startX = e.clientX
|
|
|
+ const startWidth = modelViewerParameters.offsetWidth
|
|
|
+
|
|
|
+ // 保存事件处理函数的引用以便后续移除
|
|
|
+ const onMouseMove = (e) => {
|
|
|
+ const moveX = e.clientX
|
|
|
+ const moveWidth = moveX - startX
|
|
|
+ const newWidth = startWidth + moveWidth
|
|
|
+
|
|
|
+ // 更新左右面板的宽度
|
|
|
+ modelViewerParameters.style.width = newWidth + "px"
|
|
|
+ modelViewerParameters2.style.width = (containerWidth - newWidth) + "px"
|
|
|
+ }
|
|
|
+
|
|
|
+ const onMouseUp = () => {
|
|
|
+ document.removeEventListener("mousemove", onMouseMove)
|
|
|
+ document.removeEventListener("mouseup", onMouseUp)
|
|
|
+ }
|
|
|
+
|
|
|
+ document.addEventListener("mousemove", onMouseMove)
|
|
|
+ document.addEventListener("mouseup", onMouseUp)
|
|
|
+})
|
|
|
+
|
|
|
+// 实时同步
|
|
|
+function startSync() {
|
|
|
+ modelViewerParameters.addEventListener('mousemove', () => {
|
|
|
+ modelViewerParameters.addEventListener('camera-change', handleCameraChange)
|
|
|
+ modelViewerParameters2.removeEventListener('camera-change', handleCameraChange2)
|
|
|
+ })
|
|
|
+ modelViewerParameters2.addEventListener('mousemove', () => {
|
|
|
+ modelViewerParameters2.addEventListener('camera-change', handleCameraChange2)
|
|
|
+ modelViewerParameters.removeEventListener('camera-change', handleCameraChange)
|
|
|
+ })
|
|
|
+ // 兼容移动端
|
|
|
+ modelViewerParameters.addEventListener('touchmove', () => {
|
|
|
+ modelViewerParameters.addEventListener('camera-change', handleCameraChange)
|
|
|
+ modelViewerParameters2.removeEventListener('camera-change', handleCameraChange2)
|
|
|
+ })
|
|
|
+ modelViewerParameters2.addEventListener('touchmove', () => {
|
|
|
+ modelViewerParameters2.addEventListener('camera-change', handleCameraChange2)
|
|
|
+ modelViewerParameters.removeEventListener('camera-change', handleCameraChange)
|
|
|
+ })
|
|
|
+ // 兼容鼠标滚轮
|
|
|
+ modelViewerParameters.addEventListener('wheel', () => {
|
|
|
+ modelViewerParameters.addEventListener('camera-change', handleCameraChange)
|
|
|
+ modelViewerParameters2.removeEventListener('camera-change', handleCameraChange2)
|
|
|
+ })
|
|
|
+ modelViewerParameters2.addEventListener('wheel', () => {
|
|
|
+ modelViewerParameters2.addEventListener('camera-change', handleCameraChange2)
|
|
|
+ modelViewerParameters.removeEventListener('camera-change', handleCameraChange)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 相机变化处理
|
|
|
+function handleCameraChange() {
|
|
|
+ // 如果正在同步中,则不处理此次事件,避免循环触发
|
|
|
+ modelViewerParameters2.removeEventListener('camera-change', handleCameraChange2)
|
|
|
+ // 获取相机参数
|
|
|
+ const orbit = modelViewerParameters.getCameraOrbit()
|
|
|
+ const targetPoint = modelViewerParameters.getCameraTarget()
|
|
|
+ const fov = modelViewerParameters.getFieldOfView()
|
|
|
+
|
|
|
+ // 设置到目标viewer
|
|
|
+ modelViewerParameters2.cameraOrbit = orbit.toString()
|
|
|
+ modelViewerParameters2.cameraTarget = targetPoint.toString()
|
|
|
+ modelViewerParameters2.fieldOfView = `${fov}deg`
|
|
|
+ modelViewerParameters2.jumpCameraToGoal()
|
|
|
+ console.log(modelViewerParameters.cameraOrbit, 'modelViewerParameters.cameraOrbit')
|
|
|
+ console.log(modelViewerParameters2.cameraOrbit, 'modelViewerParameters2.cameraOrbit')
|
|
|
+}
|
|
|
+
|
|
|
+function handleCameraChange2() {
|
|
|
+ modelViewerParameters.removeEventListener('camera-change', handleCameraChange)
|
|
|
+ // 获取相机参数
|
|
|
+ const orbit = modelViewerParameters2.getCameraOrbit()
|
|
|
+ const targetPoint = modelViewerParameters2.getCameraTarget()
|
|
|
+ const fov = modelViewerParameters2.getFieldOfView()
|
|
|
+
|
|
|
+ // 设置到目标viewer
|
|
|
+ modelViewerParameters.cameraOrbit = orbit.toString()
|
|
|
+ modelViewerParameters.cameraTarget = targetPoint.toString()
|
|
|
+ modelViewerParameters.fieldOfView = `${fov}deg`
|
|
|
+ modelViewerParameters.jumpCameraToGoal()
|
|
|
+ // modelViewerParameters2.cameraOrbit = orbit.toString()
|
|
|
+ // modelViewerParameters2.cameraTarget = targetPoint.toString()
|
|
|
+ // modelViewerParameters2.fieldOfView = `${fov}deg`
|
|
|
+ // modelViewerParameters.jumpCameraToGoal()
|
|
|
+
|
|
|
+ console.log(modelViewerParameters.cameraOrbit, 'modelViewerParameters.cameraOrbit')
|
|
|
+ console.log(modelViewerParameters2.cameraOrbit, 'modelViewerParameters2.cameraOrbit')
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+let isMobile = false
|
|
|
+// 页面旋转和缩放处理函数
|
|
|
+function handleOrientationChange() {
|
|
|
+ const screenWidth = document.documentElement.clientWidth
|
|
|
+ const screenHeight = document.documentElement.clientHeight
|
|
|
+
|
|
|
+ console.log(screenWidth, screenHeight)
|
|
|
+
|
|
|
+ if (screenWidth <= screenHeight) {
|
|
|
+ // 竖屏模式
|
|
|
+ console.log('竖屏模式')
|
|
|
+ isMobile = true
|
|
|
+ modelViewerParameters.orientation = '-90deg 0deg 0deg'
|
|
|
+ modelViewerParameters2.orientation = '-90deg 0deg 0deg'
|
|
|
+ splitBox.style.display = 'none'
|
|
|
+ buttonBox.style.transform = "rotate(90deg) translate(-10px, -10px)"
|
|
|
+ buttonBox.style.transformOrigin = "center"
|
|
|
+ buttonBox.style.bottom = "10px"
|
|
|
+ buttonBox.style.top = "auto"
|
|
|
+ buttonBox.style.zIndex = "1"
|
|
|
+ } else {
|
|
|
+ isMobile = false
|
|
|
+ modelViewerParameters.orientation = '0deg 0deg 0deg'
|
|
|
+ modelViewerParameters2.orientation = '0deg 0deg 0deg'
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 页面加载完成后初始化
|
|
|
+window.addEventListener('load', () => {
|
|
|
+ handleOrientationChange()
|
|
|
+})
|
|
|
+
|
|
|
+// 监听窗口大小变化
|
|
|
+window.addEventListener('resize', handleOrientationChange)
|